static void load_instrument_handle_key(struct key_event * k) { if (k->state == KEY_RELEASE) return; if (k->sym == SDLK_ESCAPE && NO_MODIFIER(k->mod)) set_page(PAGE_INSTRUMENT_LIST); }
static void palette_list_handle_key(struct key_event * k) { int n = *selected_widget; if (!NO_MODIFIER(k->mod)) return; if (k->state == KEY_RELEASE) return; switch (k->sym) { case SDLK_PAGEUP: n -= 3; break; case SDLK_PAGEDOWN: n += 3; break; default: return; } if (status.flags & CLASSIC_MODE) { if (n < 0) return; if (n > 48) n = 48; } else { n = CLAMP(n, 0, 48); } if (n != *selected_widget) change_focus_to(n); }
static int thumbbar_prompt_value(struct widget *widget, struct key_event *k) { int c; if (!NO_MODIFIER(k->mod)) { /* annoying */ return 0; } if (k->sym == SDLK_MINUS) { if (widget->d.thumbbar.min >= 0) return 0; c = '-'; } else { c = numeric_key_event(k, 0); if (c < 0) return 0; c += '0'; } numprompt_create("Enter Value", thumbbar_prompt_finish, c); return 1; }
static int file_list_handle_key(struct key_event * k) { int new_file = current_file; new_file = CLAMP(new_file, 0, flist.num_files - 1); if (k->mouse != MOUSE_NONE) { if (k->x >= 6 && k->x <= 67 && k->y >= 13 && k->y <= 47) { slash_search_mode = -1; if (k->mouse == MOUSE_SCROLL_UP) { new_file -= MOUSE_SCROLL_LINES; } else if (k->mouse == MOUSE_SCROLL_DOWN) { new_file += MOUSE_SCROLL_LINES; } else { new_file = top_file + (k->y - 13); } } } else if (slash_search_mode > -1) { int c = unicode_to_ascii(k->unicode); if (k->sym == SDLK_RETURN || k->sym == SDLK_ESCAPE) { if (k->state == KEY_PRESS) return 1; slash_search_mode = -1; status.flags |= NEED_UPDATE; return 1; } else if (k->sym == SDLK_BACKSPACE) { if (k->state == KEY_RELEASE) return 1; slash_search_mode--; status.flags |= NEED_UPDATE; reposition_at_slash_search(); return 1; } else if (c >= 32) { if (k->state == KEY_RELEASE) return 1; if (slash_search_mode < PATH_MAX) { slash_search_str[ slash_search_mode ] = c; slash_search_mode++; reposition_at_slash_search(); status.flags |= NEED_UPDATE; } return 1; } } switch (k->sym) { case SDLK_UP: new_file--; slash_search_mode = -1; break; case SDLK_DOWN: new_file++; slash_search_mode = -1; break; case SDLK_PAGEUP: new_file -= 35; slash_search_mode = -1; break; case SDLK_PAGEDOWN: new_file += 35; slash_search_mode = -1; break; case SDLK_HOME: new_file = 0; slash_search_mode = -1; break; case SDLK_END: new_file = flist.num_files - 1; slash_search_mode = -1; break; case SDLK_RETURN: if (k->state == KEY_PRESS) return 0; handle_enter_key(); slash_search_mode = -1; return 1; case SDLK_DELETE: if (k->state == KEY_RELEASE) return 1; slash_search_mode = -1; if (flist.num_files > 0) dialog_create(DIALOG_OK_CANCEL, "Delete file?", do_delete_file, NULL, 1, NULL); return 1; case SDLK_ESCAPE: slash_search_mode = -1; if (k->state == KEY_RELEASE && NO_MODIFIER(k->mod)) set_page(PAGE_INSTRUMENT_LIST); return 1; case SDLK_SLASH: if (k->orig_sym == SDLK_SLASH) { if (status.flags & CLASSIC_MODE) return 0; if (k->state == KEY_RELEASE) return 0; slash_search_mode = 0; status.flags |= NEED_UPDATE; return 1; } default: if (k->mouse == MOUSE_NONE) return 0; } if (k->mouse == MOUSE_CLICK) { if (k->state == KEY_RELEASE) return 0; } else if (k->mouse == MOUSE_DBLCLICK) { handle_enter_key(); return 1; } else { if (k->state == KEY_PRESS) return 0; } new_file = CLAMP(new_file, 0, flist.num_files - 1); if (new_file < 0) new_file = 0; if (new_file != current_file) { current_file = new_file; file_list_reposition(); status.flags |= NEED_UPDATE; } return 1; }
static int palette_list_handle_key_on_list(struct key_event * k) { int new_palette = selected_palette; const int focus_offsets[] = { 0, 1, 1, 2, 3, 3, 4, 4, 5, 6, 6, 7, 7, 8, 9, 9, 10, 10, 11, 12 }; if (k->mouse == MOUSE_CLICK) { if (k->state == KEY_PRESS) return 0; if (k->x < 56 || k->y < 27 || k->y > 46 || k->x > 76) return 0; new_palette = (k->y - 28); if (new_palette == selected_palette) { // alright if (selected_palette == -1) return 1; palette_load_preset(selected_palette); palette_apply(); update_thumbbars(); status.flags |= NEED_UPDATE; return 1; } } else { if (k->state == KEY_RELEASE) return 0; if (k->mouse == MOUSE_SCROLL_UP) new_palette -= MOUSE_SCROLL_LINES; else if (k->mouse == MOUSE_SCROLL_DOWN) new_palette += MOUSE_SCROLL_LINES; } switch (k->sym) { case SDLK_UP: if (!NO_MODIFIER(k->mod)) return 0; if (--new_palette < -1) { change_focus_to(47); return 1; } break; case SDLK_DOWN: if (!NO_MODIFIER(k->mod)) return 0; new_palette++; break; case SDLK_HOME: if (!NO_MODIFIER(k->mod)) return 0; new_palette = 0; break; case SDLK_PAGEUP: if (!NO_MODIFIER(k->mod)) return 0; if (new_palette == -1) { change_focus_to(45); return 1; } new_palette -= 16; break; case SDLK_END: if (!NO_MODIFIER(k->mod)) return 0; new_palette = max_palette - 1; break; case SDLK_PAGEDOWN: if (!NO_MODIFIER(k->mod)) return 0; new_palette += 16; break; case SDLK_RETURN: if (!NO_MODIFIER(k->mod)) return 0; if (selected_palette == -1) return 1; palette_load_preset(selected_palette); palette_apply(); update_thumbbars(); status.flags |= NEED_UPDATE; return 1; case SDLK_RIGHT: case SDLK_TAB: if (k->mod & KMOD_SHIFT) { change_focus_to(focus_offsets[selected_palette+1] + 29); return 1; } if (!NO_MODIFIER(k->mod)) return 0; change_focus_to(focus_offsets[selected_palette+1] + 8); return 1; case SDLK_LEFT: if (!NO_MODIFIER(k->mod)) return 0; change_focus_to(focus_offsets[selected_palette+1] + 29); return 1; default: if (k->mouse == MOUSE_NONE) return 0; } if (new_palette < -1) new_palette = -1; else if (new_palette >= (max_palette-1)) new_palette = (max_palette-1); if (new_palette != selected_palette) { selected_palette = new_palette; status.flags |= NEED_UPDATE; } return 1; }
static int message_handle_key_editmode(struct key_event * k) { int line_len, num_lines = -1; int new_cursor_line = cursor_line; int new_cursor_char = cursor_char; char *ptr; int doing_drag = 0; int clipl, clipr, cp; if (k->mouse == MOUSE_SCROLL_UP) { if (k->state == KEY_RELEASE) return 0; new_cursor_line -= MOUSE_SCROLL_LINES; } else if (k->mouse == MOUSE_SCROLL_DOWN) { if (k->state == KEY_RELEASE) return 0; new_cursor_line += MOUSE_SCROLL_LINES; } else if (k->mouse == MOUSE_CLICK && k->mouse_button == 2) { if (k->state == KEY_RELEASE) status.flags |= CLIPPY_PASTE_SELECTION; return 1; } else if (k->mouse == MOUSE_CLICK) { if (k->x >= 2 && k->x <= 77 && k->y >= 13 && k->y <= 47) { new_cursor_line = (k->y - 13) + top_line; new_cursor_char = (k->x - 2); if (k->sx != k->x || k->sy != k->y) { /* yay drag operation */ cp = get_absolute_position(current_song->message, (k->sy-13)+top_line, (k->sx-2)); widgets_message[0].clip_start = cp; doing_drag = 1; } } } line_len = get_nth_line(current_song->message, cursor_line, &ptr); switch (k->sym) { case SDLK_UP: if (!NO_MODIFIER(k->mod)) return 0; if (k->state == KEY_RELEASE) return 1; new_cursor_line--; break; case SDLK_DOWN: if (!NO_MODIFIER(k->mod)) return 0; if (k->state == KEY_RELEASE) return 1; new_cursor_line++; break; case SDLK_LEFT: if (!NO_MODIFIER(k->mod)) return 0; if (k->state == KEY_RELEASE) return 1; new_cursor_char--; break; case SDLK_RIGHT: if (!NO_MODIFIER(k->mod)) return 0; if (k->state == KEY_RELEASE) return 1; new_cursor_char++; break; case SDLK_PAGEUP: if (!NO_MODIFIER(k->mod)) return 0; if (k->state == KEY_RELEASE) return 1; new_cursor_line -= 35; break; case SDLK_PAGEDOWN: if (!NO_MODIFIER(k->mod)) return 0; if (k->state == KEY_RELEASE) return 1; new_cursor_line += 35; break; case SDLK_HOME: if (k->state == KEY_RELEASE) return 1; if (k->mod & KMOD_CTRL) new_cursor_line = 0; else new_cursor_char = 0; break; case SDLK_END: if (k->state == KEY_RELEASE) return 1; if (k->mod & KMOD_CTRL) { num_lines = get_num_lines(current_song->message); new_cursor_line = num_lines; } else { new_cursor_char = line_len; } break; case SDLK_ESCAPE: if (!NO_MODIFIER(k->mod)) return 0; if (k->state == KEY_RELEASE) return 1; message_set_viewmode(); memused_songchanged(); return 1; case SDLK_BACKSPACE: if (!NO_MODIFIER(k->mod)) return 0; if (k->state == KEY_RELEASE) return 1; if (k->sym && clippy_owner(CLIPPY_SELECT) == widgets_message) { _delete_selection(); } else { message_delete_char(); } return 1; case SDLK_DELETE: if (!NO_MODIFIER(k->mod)) return 0; if (k->state == KEY_RELEASE) return 1; if (k->sym && clippy_owner(CLIPPY_SELECT) == widgets_message) { _delete_selection(); } else { message_delete_next_char(); } return 1; default: if (k->mod & KMOD_CTRL) { if (k->state == KEY_RELEASE) return 1; if (k->sym == SDLK_t) { message_extfont = !message_extfont; break; } else if (k->sym == SDLK_y) { clippy_select(NULL, NULL, 0); message_delete_line(); break; } } else if (k->mod & KMOD_ALT) { if (k->state == KEY_RELEASE) return 1; if (k->sym == SDLK_c) { prompt_message_clear(); return 1; } } else if (k->mouse == MOUSE_NONE) { if (k->unicode == '\r' || k->unicode == '\t' || k->unicode >= 32) { if (k->state == KEY_RELEASE) return 1; if (k->sym && clippy_owner(CLIPPY_SELECT) == widgets_message) { _delete_selection(); } if (k->mod & (KMOD_SHIFT|KMOD_CAPS)) { message_insert_char(toupper((unsigned int)k->unicode)); } else { message_insert_char(k->unicode); } return 1; } return 0; } if (k->mouse != MOUSE_CLICK) return 0; if (k->state == KEY_RELEASE) return 1; if (!doing_drag) { clippy_select(NULL, NULL, 0); } } if (new_cursor_line != cursor_line) { if (num_lines == -1) num_lines = get_num_lines(current_song->message); if (new_cursor_line < 0) new_cursor_line = 0; else if (new_cursor_line > num_lines) new_cursor_line = num_lines; /* make sure the cursor doesn't go past the new eol */ line_len = get_nth_line(current_song->message, new_cursor_line, &ptr); if (new_cursor_char > line_len) new_cursor_char = line_len; cursor_char = new_cursor_char; cursor_line = new_cursor_line; } else if (new_cursor_char != cursor_char) { /* we say "else" here ESPECIALLY because the mouse can only come in the top section - not because it's some clever optimization */ if (new_cursor_char < 0) { if (cursor_line == 0) { new_cursor_char = cursor_char; } else { cursor_line--; new_cursor_char = get_nth_line(current_song->message, cursor_line, &ptr); } } else if (new_cursor_char > get_nth_line(current_song->message, cursor_line, &ptr)) { if (cursor_line == get_num_lines(current_song->message)) { new_cursor_char = cursor_char; } else { cursor_line++; new_cursor_char = 0; } } cursor_char = new_cursor_char; } message_reposition(); cursor_pos = get_absolute_position(current_song->message, cursor_line, cursor_char); if (doing_drag) { widgets_message[0].clip_end = cursor_pos; clipl = widgets_message[0].clip_start; clipr = widgets_message[0].clip_end; if (clipl > clipr) { cp = clipl; clipl = clipr; clipr = cp; } clippy_select(widgets_message, (current_song->message+clipl), clipr-clipl); } status.flags |= NEED_UPDATE; return 1; }
/* return: 1 = handled key, 0 = didn't */ int widget_handle_key(struct key_event * k) { struct widget *widget = &ACTIVE_WIDGET; if (!widget) return 0; int n, onw, wx, fmin, fmax, pad; void (*changed)(void); enum widget_type current_type = widget->type; if (!(status.flags & DISKWRITER_ACTIVE) && (current_type == WIDGET_OTHER) && widget->d.other.handle_key(k)) return 1; if (!(status.flags & DISKWRITER_ACTIVE) && k->mouse && (status.flags & CLASSIC_MODE)) { switch(current_type) { case WIDGET_NUMENTRY: if (k->mouse_button == MOUSE_BUTTON_LEFT) { k->sym = SDLK_MINUS; k->mouse = MOUSE_NONE; } else if (k->mouse_button == MOUSE_BUTTON_RIGHT) { k->sym = SDLK_PLUS; k->mouse = MOUSE_NONE; } break; default: break; }; } if (k->mouse == MOUSE_CLICK) { if (status.flags & DISKWRITER_ACTIVE) return 0; switch (current_type) { case WIDGET_TOGGLE: if (!NO_MODIFIER(k->mod)) return 0; if (k->state == KEY_RELEASE) return 1; widget->d.toggle.state = !widget->d.toggle.state; if (widget->changed) widget->changed(); status.flags |= NEED_UPDATE; return 1; case WIDGET_MENUTOGGLE: if (!NO_MODIFIER(k->mod)) return 0; if (k->state == KEY_RELEASE) return 1; widget->d.menutoggle.state = (widget->d.menutoggle.state + 1) % widget->d.menutoggle.num_choices; if (widget->changed) widget->changed(); status.flags |= NEED_UPDATE; return 1; default: break; } } else if (k->mouse == MOUSE_DBLCLICK) { if (status.flags & DISKWRITER_ACTIVE) return 0; if (current_type == WIDGET_PANBAR) { if (!NO_MODIFIER(k->mod)) return 0; widget->d.panbar.muted = !widget->d.panbar.muted; changed = widget->changed; if (changed) changed(); return 1; } } if (k->mouse == MOUSE_CLICK || (k->mouse == MOUSE_NONE && k->sym == SDLK_RETURN)) { #if 0 if (k->mouse && k->mouse_button == MOUSE_BUTTON_MIDDLE) { if (status.flags & DISKWRITER_ACTIVE) return 0; if (k->state == KEY_PRESS) return 1; status.flags |= CLIPPY_PASTE_SELECTION; return 1; } #endif if (k->mouse && (current_type == WIDGET_THUMBBAR || current_type == WIDGET_PANBAR)) { if (status.flags & DISKWRITER_ACTIVE) return 0; /* swallow it */ if (!k->on_target) return 0; fmin = widget->d.thumbbar.min; fmax = widget->d.thumbbar.max; if (current_type == WIDGET_PANBAR) { n = k->fx - ((widget->x + 11) * k->rx); wx = (widget->width - 16) * k->rx; } else { n = k->fx - (widget->x * k->rx); wx = (widget->width-1) * k->rx; } if (n < 0) n = 0; else if (n >= wx) n = wx; n = fmin + ((n * (fmax - fmin)) / wx); if (n < fmin) n = fmin; else if (n > fmax) n = fmax; if (current_type == WIDGET_PANBAR) { widget->d.panbar.muted = 0; widget->d.panbar.surround = 0; if (k->x - widget->x < 11) return 1; if (k->x - widget->x > 19) return 1; } numentry_change_value(widget, n); return 1; } if (k->mouse) { switch (widget->type) { case WIDGET_BUTTON: pad = widget->d.button.padding+1; break; case WIDGET_TOGGLEBUTTON: pad = widget->d.togglebutton.padding+1; break; default: pad = 0; }; onw = ((signed) k->x < widget->x || (signed) k->x >= widget->x + widget->width + pad || (signed) k->y != widget->y) ? 0 : 1; n = (k->state == KEY_RELEASE && onw) ? 1 : 0; if (widget->depressed != n) status.flags |= NEED_UPDATE; widget->depressed = n; if (current_type != WIDGET_TEXTENTRY && current_type != WIDGET_NUMENTRY) { if (k->state == KEY_PRESS || !onw) return 1; } else if (!onw) { return 1; } } else { n = (k->state == KEY_PRESS) ? 1 : 0; if (widget->depressed != n) status.flags |= NEED_UPDATE; else if (k->state == KEY_RELEASE) return 1; // swallor widget->depressed = n; if (k->state == KEY_PRESS) return 1; } if (k->mouse) { switch(current_type) { case WIDGET_MENUTOGGLE: case WIDGET_BUTTON: case WIDGET_TOGGLEBUTTON: if (k->on_target && widget->activate) widget->activate(); default: break; }; } else if (current_type != WIDGET_OTHER) { if (widget->activate) widget->activate(); } switch (current_type) { case WIDGET_OTHER: break; case WIDGET_TEXTENTRY: if (status.flags & DISKWRITER_ACTIVE) return 0; /* LOL WOW THIS SUCKS */ if (k->mouse == MOUSE_CLICK && k->on_target) { /* position cursor */ n = k->x - widget->x; n = CLAMP(n, 0, widget->width - 1); wx = k->sx - widget->x; wx = CLAMP(wx, 0, widget->width - 1); widget->d.textentry.cursor_pos = n+widget->d.textentry.firstchar; wx = wx+widget->d.textentry.firstchar; if (widget->d.textentry.cursor_pos >= (signed) strlen(widget->d.textentry.text)) widget->d.textentry.cursor_pos = strlen(widget->d.textentry.text); if (wx >= (signed) strlen(widget->d.textentry.text)) wx = strlen(widget->d.textentry.text); status.flags |= NEED_UPDATE; } /* for a text entry, the only thing enter does is run the activate callback. thus, if no activate callback is defined, the key wasn't handled */ return (widget->activate != NULL); case WIDGET_NUMENTRY: if (status.flags & DISKWRITER_ACTIVE) return 0; if (k->mouse == MOUSE_CLICK && k->on_target) { /* position cursor */ n = k->x - widget->x; n = CLAMP(n, 0, widget->width - 1); wx = k->sx - widget->x; wx = CLAMP(wx, 0, widget->width - 1); if (n >= widget->width) n = widget->width-1; *widget->d.numentry.cursor_pos = n; status.flags |= NEED_UPDATE; } break; case WIDGET_TOGGLEBUTTON: if (status.flags & DISKWRITER_ACTIVE) return 0; if (widget->d.togglebutton.group) { /* this also runs the changed callback and redraws the button(s) */ togglebutton_set(widgets, *selected_widget, 1); return 1; } /* else... */ widget->d.togglebutton.state = !widget->d.togglebutton.state; /* and fall through */ case WIDGET_BUTTON: /* maybe buttons should ignore the changed callback, and use activate instead... (but still call the changed callback for togglebuttons if they *actually* changed) */ if (widget->changed) widget->changed(); status.flags |= NEED_UPDATE; return 1; default: break; } return 0; } /* a WIDGET_OTHER that *didn't* handle the key itself needs to get run through the switch statement to account for stuff like the tab key */ if (k->state == KEY_RELEASE) return 0; if (k->mouse == MOUSE_SCROLL_UP && current_type == WIDGET_NUMENTRY) { k->sym = SDLK_MINUS; } else if (k->mouse == MOUSE_SCROLL_DOWN && current_type == WIDGET_NUMENTRY) { k->sym = SDLK_PLUS; } switch (k->sym) { case SDLK_ESCAPE: /* this is to keep the text entries from taking the key hostage and inserting '<-' characters instead of showing the menu */ return 0; case SDLK_UP: if (status.flags & DISKWRITER_ACTIVE) return 0; if (!NO_MODIFIER(k->mod)) return 0; change_focus_to(widget->next.up); return 1; case SDLK_DOWN: if (status.flags & DISKWRITER_ACTIVE) return 0; if (!NO_MODIFIER(k->mod)) return 0; change_focus_to(widget->next.down); return 1; case SDLK_TAB: if (status.flags & DISKWRITER_ACTIVE) return 0; if (k->mod & KMOD_SHIFT) { _backtab(); return 1; } if (!NO_MODIFIER(k->mod)) return 0; change_focus_to(widget->next.tab); return 1; case SDLK_LEFT: if (status.flags & DISKWRITER_ACTIVE) return 0; switch (current_type) { case WIDGET_BITSET: if (NO_MODIFIER(k->mod)) bitset_move_cursor(widget, -1); break; case WIDGET_NUMENTRY: if (!NO_MODIFIER(k->mod)) { return 0; } numentry_move_cursor(widget, -1); return 1; case WIDGET_TEXTENTRY: if (!NO_MODIFIER(k->mod)) { return 0; } textentry_move_cursor(widget, -1); return 1; case WIDGET_PANBAR: widget->d.panbar.muted = 0; widget->d.panbar.surround = 0; /* fall through */ case WIDGET_THUMBBAR: /* I'm handling the key modifiers differently than Impulse Tracker, but only because I think this is much more useful. :) */ n = 1; if (k->mod & (KMOD_ALT | KMOD_META)) n *= 8; if (k->mod & KMOD_SHIFT) n *= 4; if (k->mod & KMOD_CTRL) n *= 2; n = widget->d.numentry.value - n; numentry_change_value(widget, n); return 1; default: if (!NO_MODIFIER(k->mod)) return 0; change_focus_to(widget->next.left); return 1; } break; case SDLK_RIGHT: if (status.flags & DISKWRITER_ACTIVE) return 0; /* pretty much the same as left, but with a few small * changes here and there... */ switch (current_type) { case WIDGET_BITSET: if (NO_MODIFIER(k->mod)) bitset_move_cursor(widget, 1); break; case WIDGET_NUMENTRY: if (!NO_MODIFIER(k->mod)) { return 0; } numentry_move_cursor(widget, 1); return 1; case WIDGET_TEXTENTRY: if (!NO_MODIFIER(k->mod)) { return 0; } textentry_move_cursor(widget, 1); return 1; case WIDGET_PANBAR: widget->d.panbar.muted = 0; widget->d.panbar.surround = 0; /* fall through */ case WIDGET_THUMBBAR: n = 1; if (k->mod & (KMOD_ALT | KMOD_META)) n *= 8; if (k->mod & KMOD_SHIFT) n *= 4; if (k->mod & KMOD_CTRL) n *= 2; n = widget->d.numentry.value + n; numentry_change_value(widget, n); return 1; default: if (!NO_MODIFIER(k->mod)) return 0; change_focus_to(widget->next.right); return 1; } break; case SDLK_HOME: if (status.flags & DISKWRITER_ACTIVE) return 0; /* Impulse Tracker only does home/end for the thumbbars. * This stuff is all extra. */ switch (current_type) { case WIDGET_NUMENTRY: if (!NO_MODIFIER(k->mod)) return 0; *(widget->d.numentry.cursor_pos) = 0; status.flags |= NEED_UPDATE; return 1; case WIDGET_TEXTENTRY: if (!NO_MODIFIER(k->mod)) return 0; widget->d.textentry.cursor_pos = 0; status.flags |= NEED_UPDATE; return 1; case WIDGET_PANBAR: widget->d.panbar.muted = 0; widget->d.panbar.surround = 0; /* fall through */ case WIDGET_THUMBBAR: n = widget->d.thumbbar.min; numentry_change_value(widget, n); return 1; default: break; } break; case SDLK_END: if (status.flags & DISKWRITER_ACTIVE) return 0; switch (current_type) { case WIDGET_NUMENTRY: if (!NO_MODIFIER(k->mod)) return 0; *(widget->d.numentry.cursor_pos) = widget->width - 1; status.flags |= NEED_UPDATE; return 1; case WIDGET_TEXTENTRY: if (!NO_MODIFIER(k->mod)) return 0; widget->d.textentry.cursor_pos = strlen(widget->d.textentry.text); status.flags |= NEED_UPDATE; return 1; case WIDGET_PANBAR: widget->d.panbar.muted = 0; widget->d.panbar.surround = 0; /* fall through */ case WIDGET_THUMBBAR: n = widget->d.thumbbar.max; numentry_change_value(widget, n); return 1; default: break; } break; case SDLK_SPACE: if (status.flags & DISKWRITER_ACTIVE) return 0; switch (current_type) { case WIDGET_BITSET: if (!NO_MODIFIER(k->mod)) return 0; widget->d.bitset.value ^= (1 << *widget->d.bitset.cursor_pos); if (widget->changed) widget->changed(); status.flags |= NEED_UPDATE; return 1; case WIDGET_TOGGLE: if (!NO_MODIFIER(k->mod)) return 0; widget->d.toggle.state = !widget->d.toggle.state; if (widget->changed) widget->changed(); status.flags |= NEED_UPDATE; return 1; case WIDGET_MENUTOGGLE: if (!NO_MODIFIER(k->mod)) return 0; widget->d.menutoggle.state = (widget->d.menutoggle.state + 1) % widget->d.menutoggle.num_choices; if (widget->changed) widget->changed(); status.flags |= NEED_UPDATE; return 1; case WIDGET_PANBAR: if (!NO_MODIFIER(k->mod)) return 0; widget->d.panbar.muted = !widget->d.panbar.muted; changed = widget->changed; change_focus_to(widget->next.down); if (changed) changed(); return 1; default: break; } break; case SDLK_BACKSPACE: if (status.flags & DISKWRITER_ACTIVE) return 0; if (current_type == WIDGET_NUMENTRY) { if (widget->d.numentry.reverse) { /* woot! */ widget->d.numentry.value /= 10; if (widget->changed) widget->changed(); status.flags |= NEED_UPDATE; return 1; } } /* this ought to be in a separate function. */ if (current_type != WIDGET_TEXTENTRY) break; if (!widget->d.textentry.text[0]) { /* nothing to do */ return 1; } if (k->mod & KMOD_CTRL) { /* clear the whole field */ widget->d.textentry.text[0] = 0; widget->d.textentry.cursor_pos = 0; } else { if (widget->d.textentry.cursor_pos == 0) { /* act like ST3 */ text_delete_next_char(widget->d.textentry.text, &(widget->d.textentry.cursor_pos), widget->d.textentry.max_length); } else { text_delete_char(widget->d.textentry.text, &(widget->d.textentry.cursor_pos), widget->d.textentry.max_length); } } if (widget->changed) widget->changed(); status.flags |= NEED_UPDATE; return 1; case SDLK_DELETE: if (status.flags & DISKWRITER_ACTIVE) return 0; if (current_type != WIDGET_TEXTENTRY) break; if (!widget->d.textentry.text[0]) { /* nothing to do */ return 1; } text_delete_next_char(widget->d.textentry.text, &(widget->d.textentry.cursor_pos), widget->d.textentry.max_length); if (widget->changed) widget->changed(); status.flags |= NEED_UPDATE; return 1; case SDLK_PLUS: if (status.flags & DISKWRITER_ACTIVE) return 0; if (current_type == WIDGET_NUMENTRY && NO_MODIFIER(k->mod)) { numentry_change_value(widget, widget->d.numentry.value + 1); return 1; } break; case SDLK_MINUS: if (status.flags & DISKWRITER_ACTIVE) return 0; if (current_type == WIDGET_NUMENTRY && NO_MODIFIER(k->mod)) { numentry_change_value(widget, widget->d.numentry.value - 1); return 1; } break; case SDLK_l: if (status.flags & DISKWRITER_ACTIVE) return 0; if (current_type == WIDGET_PANBAR) { if (k->mod & KMOD_ALT) { song_set_pan_scheme(PANS_LEFT); return 1; } else if (NO_MODIFIER(k->mod)) { widget->d.panbar.muted = 0; widget->d.panbar.surround = 0; numentry_change_value(widget, 0); return 1; } } break; case SDLK_m: if (status.flags & DISKWRITER_ACTIVE) return 0; if (current_type == WIDGET_PANBAR) { if (k->mod & KMOD_ALT) { song_set_pan_scheme(PANS_MONO); return 1; } else if (NO_MODIFIER(k->mod)) { widget->d.panbar.muted = 0; widget->d.panbar.surround = 0; numentry_change_value(widget, 32); return 1; } } break; case SDLK_r: if (status.flags & DISKWRITER_ACTIVE) return 0; if (current_type == WIDGET_PANBAR) { if (k->mod & KMOD_ALT) { song_set_pan_scheme(PANS_RIGHT); return 1; } else if (NO_MODIFIER(k->mod)) { widget->d.panbar.muted = 0; widget->d.panbar.surround = 0; numentry_change_value(widget, 64); return 1; } } break; case SDLK_s: if (status.flags & DISKWRITER_ACTIVE) return 0; if (current_type == WIDGET_PANBAR) { if (k->mod & KMOD_ALT) { song_set_pan_scheme(PANS_STEREO); return 1; } else if(NO_MODIFIER(k->mod)) { widget->d.panbar.muted = 0; widget->d.panbar.surround = 1; if (widget->changed) widget->changed(); status.flags |= NEED_UPDATE; return 1; } } break; case SDLK_a: if (status.flags & DISKWRITER_ACTIVE) return 0; if (current_type == WIDGET_PANBAR && (k->mod & KMOD_ALT)) { song_set_pan_scheme(PANS_AMIGA); return 1; } break; #if 0 case SDLK_x: if (status.flags & DISKWRITER_ACTIVE) return 0; if (current_type == WIDGET_PANBAR && (k->mod & KMOD_ALT)) { song_set_pan_scheme(PANS_CROSS); return 1; } break; #endif case SDLK_SLASH: case SDLK_KP_DIVIDE: if (status.flags & DISKWRITER_ACTIVE) return 0; if (current_type == WIDGET_PANBAR && (k->mod & KMOD_ALT)) { song_set_pan_scheme(PANS_SLASH); return 1; } break; case SDLK_BACKSLASH: if (status.flags & DISKWRITER_ACTIVE) return 0; if (current_type == WIDGET_PANBAR && (k->mod & KMOD_ALT)) { song_set_pan_scheme(PANS_BACKSLASH); return 1; } break; default: /* this avoids a warning about all the values of an enum not being handled. (sheesh, it's already hundreds of lines long as it is!) */ break; } if (status.flags & DISKWRITER_ACTIVE) return 0; /* if we're here, that mess didn't completely handle the key (gosh...) so now here's another mess. */ switch (current_type) { case WIDGET_MENUTOGGLE: if (menutoggle_handle_key(widget, k)) return 1; break; case WIDGET_BITSET: if (bitset_handle_key(widget, k)) return 1; break; case WIDGET_NUMENTRY: if (numentry_handle_digit(widget, k)) return 1; break; case WIDGET_THUMBBAR: case WIDGET_PANBAR: if (thumbbar_prompt_value(widget, k)) return 1; break; case WIDGET_TEXTENTRY: if ((k->mod & (KMOD_CTRL | KMOD_ALT | KMOD_META)) == 0 && textentry_add_char(widget, k->unicode)) return 1; break; default: break; } /* if we got down here the key wasn't handled */ return 0; }
static int _handle_ime(struct key_event *k) { int c, m; static int alt_numpad = 0; static int alt_numpad_c = 0; static int digraph_n = 0; static int digraph_c = 0; static int cs_unicode = 0; static int cs_unicode_c = 0; struct key_event fake; if (ACTIVE_PAGE.selected_widget > -1 && ACTIVE_PAGE.selected_widget < ACTIVE_PAGE.total_widgets && ACTIVE_PAGE.widgets[ACTIVE_PAGE.selected_widget].accept_text) { if (digraph_n == -1 && k->state == KEY_RELEASE) { digraph_n = 0; } else if (!(status.flags & CLASSIC_MODE) && (k->sym == SDLK_LCTRL || k->sym == SDLK_RCTRL)) { if (k->state == KEY_RELEASE && digraph_n >= 0) { digraph_n++; if (digraph_n >= 2) status_text_flash_bios("Enter digraph:"); } } else if (k->sym == SDLK_LSHIFT || k->sym == SDLK_RSHIFT) { /* do nothing */ } else if (!NO_MODIFIER((k->mod&~KMOD_SHIFT)) || (c=k->unicode) == 0 || digraph_n < 2) { if (k->state == KEY_PRESS && k->mouse == MOUSE_NONE) { if (digraph_n > 0) status_text_flash(" "); digraph_n = -1; } } else if (digraph_n >= 2) { if (k->state == KEY_RELEASE) return 1; if (!digraph_c) { digraph_c = c; status_text_flash_bios("Enter digraph: %c", c); } else { memset(&fake, 0, sizeof(fake)); fake.unicode = char_digraph(digraph_c, c); if (fake.unicode) { status_text_flash_bios("Enter digraph: %c%c -> %c", digraph_c, c, fake.unicode); } else { status_text_flash_bios("Enter digraph: %c%c -> INVALID", digraph_c, c); } digraph_n = digraph_c = 0; if (fake.unicode) { fake.is_synthetic = 3; handle_key(&fake); fake.state = KEY_RELEASE; handle_key(&fake); } } return 1; } else { if (digraph_n > 0) status_text_flash(" "); digraph_n = 0; } /* ctrl+shift -> unicode character */ if ((k->sym==SDLK_LCTRL || k->sym==SDLK_RCTRL || k->sym==SDLK_LSHIFT || k->sym==SDLK_RSHIFT)) { if (k->state == KEY_RELEASE && cs_unicode_c > 0) { memset(&fake, 0, sizeof(fake)); fake.unicode = char_unicode_to_cp437(cs_unicode); if (fake.unicode) { status_text_flash_bios("Enter Unicode: U+%04X -> %c", cs_unicode, fake.unicode); fake.is_synthetic = 3; handle_key(&fake); fake.state = KEY_RELEASE; handle_key(&fake); } else { status_text_flash_bios("Enter Unicode: U+%04X -> INVALID", cs_unicode); } cs_unicode = cs_unicode_c = 0; alt_numpad = alt_numpad_c = 0; digraph_n = digraph_c = 0; return 1; } } else if (!(status.flags & CLASSIC_MODE) && (k->mod & KMOD_CTRL) && (k->mod & KMOD_SHIFT)) { if (cs_unicode_c >= 0) { /* bleh... */ m = k->mod; k->mod = 0; c = kbd_char_to_hex(k); k->mod = m; if (c == -1) { cs_unicode = cs_unicode_c = -1; } else { if (k->state == KEY_PRESS) return 1; cs_unicode *= 16; cs_unicode += c; cs_unicode_c++; digraph_n = digraph_c = 0; status_text_flash_bios("Enter Unicode: U+%04X", cs_unicode); return 1; } } } else { cs_unicode = cs_unicode_c = 0; } /* alt+numpad -> char number */ if (k->sym == SDLK_LALT || k->sym == SDLK_RALT || k->sym == SDLK_LMETA || k->sym == SDLK_RMETA) { if (k->state == KEY_RELEASE && alt_numpad_c > 0 && (alt_numpad & 255) > 0) { memset(&fake, 0, sizeof(fake)); fake.unicode = alt_numpad & 255; if (!(status.flags & CLASSIC_MODE)) status_text_flash_bios("Enter DOS/ASCII: %d -> %c", (int)fake.unicode, (int)fake.unicode); fake.is_synthetic = 3; handle_key(&fake); fake.state = KEY_RELEASE; handle_key(&fake); alt_numpad = alt_numpad_c = 0; digraph_n = digraph_c = 0; cs_unicode = cs_unicode_c = 0; return 1; } } else if (k->mod & KMOD_ALT && !(k->mod & (KMOD_CTRL|KMOD_SHIFT))) { if (alt_numpad_c >= 0) { m = k->mod; k->mod = 0; c = numeric_key_event(k, 1); /* kp only */ k->mod = m; if (c == -1 || c > 9) { alt_numpad = alt_numpad_c = -1; } else { if (k->state == KEY_PRESS) return 1; alt_numpad *= 10; alt_numpad += c; alt_numpad_c++; if (!(status.flags & CLASSIC_MODE)) status_text_flash_bios("Enter DOS/ASCII: %d", (int)alt_numpad); return 1; } } } else { alt_numpad = alt_numpad_c = 0; } } else { cs_unicode = cs_unicode_c = 0; alt_numpad = alt_numpad_c = 0; digraph_n = digraph_c = 0; } return 0; }
/* returns 1 if the key was handled */ static int handle_key_global(struct key_event * k) { int i, ins_mode; if (_mp_active == 2 && (k->mouse == MOUSE_CLICK && k->state == KEY_RELEASE)) { status.flags |= NEED_UPDATE; dialog_destroy_all(); _mp_active = 0; // eat it... return 1; } if ((!_mp_active) && k->state == KEY_PRESS && k->mouse == MOUSE_CLICK) { if (k->x >= 63 && k->x <= 77 && k->y >= 6 && k->y <= 7) { status.vis_style++; status.vis_style %= VIS_SENTINEL; status.flags |= NEED_UPDATE; return 1; } else if (k->y == 5 && k->x == 50) { minipop_slide(kbd_get_current_octave(), "Octave", 0, 8, kbd_set_current_octave, NULL, 50, 5); return 1; } else if (k->y == 4 && k->x >= 50 && k->x <= 52) { minipop_slide(song_get_current_speed(), "Speed", 1, 255, song_set_current_speed, song_set_initial_speed, 51, 4); return 1; } else if (k->y == 4 && k->x >= 54 && k->x <= 56) { minipop_slide(song_get_current_tempo(), "Tempo", 32, 255, song_set_current_tempo, song_set_initial_tempo, 55, 4); return 1; } else if (k->y == 3 && k->x >= 50 && k-> x <= 77) { if (page_is_instrument_list(status.current_page) || status.current_page == PAGE_SAMPLE_LIST || (!(status.flags & CLASSIC_MODE) && (status.current_page == PAGE_ORDERLIST_PANNING || status.current_page == PAGE_ORDERLIST_VOLUMES))) ins_mode = 0; else ins_mode = song_is_instrument_mode(); if (ins_mode) { minipop_slide(instrument_get_current(), "!", status.current_page == PAGE_INSTRUMENT_LIST ? 1 : 0, 99 /* FIXME */, instrument_set, NULL, 58, 3); } else { minipop_slide(sample_get_current(), "@", status.current_page == PAGE_SAMPLE_LIST ? 1 : 0, 99 /* FIXME */, sample_set, NULL, 58, 3); } } else if (k->y == 7 && k->x >= 11 && k->x <= 17) { minipop_slide(get_current_row(), "Row", 0, song_get_rows_in_pattern(get_current_pattern()), set_current_row, NULL, 14, 7); return 1; } else if (k->y == 6 && k->x >= 11 && k->x <= 17) { minipop_slide(get_current_pattern(), "Pattern", 0, csf_get_num_patterns(current_song), set_current_pattern, NULL, 14, 6); return 1; } else if (k->y == 5 && k->x >= 11 && k->x <= 17) { minipop_slide(song_get_current_order(), "Order", 0, csf_get_num_orders(current_song), set_current_order, NULL, 14, 5); return 1; } } else if ((!_mp_active) && k->mouse == MOUSE_DBLCLICK) { if (k->y == 4 && k->x >= 11 && k->x <= 28) { set_page(PAGE_SAVE_MODULE); return 1; } else if (k->y == 3 && k->x >= 11 && k->x <= 35) { set_page(PAGE_SONG_VARIABLES); return 1; } } /* shortcut */ if (k->mouse != MOUSE_NONE) { return 0; } /* first, check the truly global keys (the ones that still work if * a dialog's open) */ switch (k->sym) { case SDLK_RETURN: if ((k->mod & KMOD_CTRL) && k->mod & KMOD_ALT) { if (k->state == KEY_PRESS) return 1; toggle_display_fullscreen(); return 1; } break; case SDLK_m: if (k->mod & KMOD_CTRL) { if (k->state == KEY_RELEASE) return 1; video_mousecursor(MOUSE_CYCLE_STATE); return 1; } break; case SDLK_d: if (k->mod & KMOD_CTRL) { if (k->state == KEY_RELEASE) return 1; /* argh */ i = SDL_WM_GrabInput(SDL_GRAB_QUERY); if (i == SDL_GRAB_QUERY) i = currently_grabbed; currently_grabbed = i = (i != SDL_GRAB_ON ? SDL_GRAB_ON : SDL_GRAB_OFF); SDL_WM_GrabInput(i); status_text_flash(i ? "Mouse and keyboard grabbed, press Ctrl+D to release" : "Mouse and keyboard released"); return 1; } break; case SDLK_i: /* reset audio stuff? */ if (k->mod & KMOD_CTRL) { if (k->state == KEY_RELEASE) return 1; audio_reinit(); return 1; } break; case SDLK_e: /* This should reset everything display-related. */ if (k->mod & KMOD_CTRL) { if (k->state == KEY_RELEASE) return 1; font_init(); status.flags |= NEED_UPDATE; return 1; } break; case SDLK_HOME: if (!(k->mod & KMOD_ALT)) break; if (status.flags & DISKWRITER_ACTIVE) break; if (k->state == KEY_RELEASE) return 0; kbd_set_current_octave(kbd_get_current_octave() - 1); return 1; case SDLK_END: if (!(k->mod & KMOD_ALT)) break; if (status.flags & DISKWRITER_ACTIVE) break; if (k->state == KEY_RELEASE) return 0; kbd_set_current_octave(kbd_get_current_octave() + 1); return 1; default: break; } /* next, if there's no dialog, check the rest of the keys */ if (status.flags & DISKWRITER_ACTIVE) return 0; switch (k->sym) { case SDLK_q: if (status.dialog_type != DIALOG_NONE) return 0; if (k->mod & KMOD_CTRL) { _mp_finish(NULL); if (k->state == KEY_PRESS) show_exit_prompt(); return 1; } break; case SDLK_n: if (status.dialog_type != DIALOG_NONE) return 0; if (k->mod & KMOD_CTRL) { _mp_finish(NULL); if (k->state == KEY_PRESS) new_song_dialog(); return 1; } break; case SDLK_g: if (status.dialog_type != DIALOG_NONE) return 0; if (k->mod & KMOD_CTRL) { _mp_finish(NULL); if (k->state == KEY_PRESS) show_song_timejump(); return 1; } break; case SDLK_p: if (status.dialog_type != DIALOG_NONE) return 0; if (k->mod & KMOD_CTRL) { _mp_finish(NULL); if (k->state == KEY_PRESS) show_song_length(); return 1; } break; case SDLK_F1: if (status.dialog_type != DIALOG_NONE) return 0; if (k->mod & KMOD_CTRL) { _mp_finish(NULL); if (k->state == KEY_PRESS) set_page(PAGE_CONFIG); } else if (k->mod & KMOD_SHIFT) { _mp_finish(NULL); if (k->state == KEY_PRESS) set_page(status.current_page == PAGE_MIDI ? PAGE_MIDI_OUTPUT : PAGE_MIDI); } else if (NO_MODIFIER(k->mod)) { _mp_finish(NULL); if (k->state == KEY_PRESS) set_page(PAGE_HELP); } else { break; } return 1; case SDLK_F2: if (k->mod & KMOD_CTRL) { if (status.current_page == PAGE_PATTERN_EDITOR) { _mp_finish(NULL); if (k->state == KEY_PRESS && status.dialog_type == DIALOG_NONE) { pattern_editor_length_edit(); } return 1; } if (status.dialog_type != DIALOG_NONE) return 0; } else if (NO_MODIFIER(k->mod)) { if (status.current_page == PAGE_PATTERN_EDITOR) { if (k->state == KEY_PRESS) { if (status.dialog_type & DIALOG_MENU) { return 0; } else if (status.dialog_type != DIALOG_NONE) { dialog_yes_NULL(); status.flags |= NEED_UPDATE; } else { _mp_finish(NULL); pattern_editor_display_options(); } } } else { if (status.dialog_type != DIALOG_NONE) return 0; _mp_finish(NULL); if (k->state == KEY_PRESS) set_page(PAGE_PATTERN_EDITOR); } return 1; } break; case SDLK_F3: if (status.dialog_type != DIALOG_NONE) return 0; if (NO_MODIFIER(k->mod)) { _mp_finish(NULL); if (k->state == KEY_PRESS) set_page(PAGE_SAMPLE_LIST); } else { _mp_finish(NULL); if (k->mod & KMOD_CTRL) set_page(PAGE_LIBRARY_SAMPLE); break; } return 1; case SDLK_F4: if (status.dialog_type != DIALOG_NONE) return 0; if (NO_MODIFIER(k->mod)) { if (status.current_page == PAGE_INSTRUMENT_LIST) return 0; _mp_finish(NULL); if (k->state == KEY_PRESS) set_page(PAGE_INSTRUMENT_LIST); } else { if (k->mod & KMOD_SHIFT) return 0; _mp_finish(NULL); if (k->mod & KMOD_CTRL) set_page(PAGE_LIBRARY_INSTRUMENT); break; } return 1; case SDLK_F5: if (k->mod & KMOD_CTRL) { _mp_finish(NULL); if (k->state == KEY_PRESS) song_start(); } else if (k->mod & KMOD_SHIFT) { if (status.dialog_type != DIALOG_NONE) return 0; _mp_finish(NULL); if (k->state == KEY_RELEASE) set_page(PAGE_PREFERENCES); } else if (NO_MODIFIER(k->mod)) { if (song_get_mode() == MODE_STOPPED || (song_get_mode() == MODE_SINGLE_STEP && status.current_page == PAGE_INFO)) { _mp_finish(NULL); if (k->state == KEY_PRESS) song_start(); } if (k->state == KEY_PRESS) { if (status.dialog_type != DIALOG_NONE) return 0; _mp_finish(NULL); set_page(PAGE_INFO); } } else { break; } return 1; case SDLK_F6: if (k->mod & KMOD_SHIFT) { _mp_finish(NULL); if (k->state == KEY_PRESS) song_start_at_order(get_current_order(), 0); } else if (NO_MODIFIER(k->mod)) { _mp_finish(NULL); if (k->state == KEY_PRESS) song_loop_pattern(get_current_pattern(), 0); } else { break; } return 1; case SDLK_F7: if (NO_MODIFIER(k->mod)) { _mp_finish(NULL); if (k->state == KEY_PRESS) play_song_from_mark(); } else { break; } return 1; case SDLK_F8: if (k->mod & KMOD_SHIFT) { if (k->state == KEY_PRESS) song_pause(); } else if (NO_MODIFIER(k->mod)) { _mp_finish(NULL); if (k->state == KEY_PRESS) song_stop(); status.flags |= NEED_UPDATE; } else { break; } return 1; case SDLK_F9: if (status.dialog_type != DIALOG_NONE) return 0; if (k->mod & KMOD_SHIFT) { _mp_finish(NULL); if (k->state == KEY_PRESS) set_page(PAGE_MESSAGE); } else if (NO_MODIFIER(k->mod)) { _mp_finish(NULL); if (k->state == KEY_PRESS) set_page(PAGE_LOAD_MODULE); } else { break; } return 1; case SDLK_l: case SDLK_r: if (status.dialog_type != DIALOG_NONE) return 0; if (k->mod & KMOD_CTRL) { _mp_finish(NULL); if (k->state == KEY_RELEASE) set_page(PAGE_LOAD_MODULE); } else { break; } return 1; case SDLK_s: if (status.dialog_type != DIALOG_NONE) return 0; if (k->mod & KMOD_CTRL) { _mp_finish(NULL); if (k->state == KEY_RELEASE) save_song_or_save_as(); } else { break; } return 1; case SDLK_w: /* Ctrl-W _IS_ in IT, and hands don't leave home row :) */ if (status.dialog_type != DIALOG_NONE) return 0; if (k->mod & KMOD_CTRL) { _mp_finish(NULL); if (k->state == KEY_RELEASE) set_page(PAGE_SAVE_MODULE); } else { break; } return 1; case SDLK_F10: if (status.dialog_type != DIALOG_NONE) return 0; if (k->mod & KMOD_ALT) break; if (k->mod & KMOD_CTRL) break; _mp_finish(NULL); if (k->mod & KMOD_SHIFT) { if (k->state == KEY_PRESS) set_page(PAGE_EXPORT_MODULE); } else { if (k->state == KEY_PRESS) set_page(PAGE_SAVE_MODULE); } return 1; case SDLK_F11: if (status.dialog_type != DIALOG_NONE) return 0; if (NO_MODIFIER(k->mod)) { _mp_finish(NULL); if (status.current_page == PAGE_ORDERLIST_PANNING) { if (k->state == KEY_PRESS) set_page(PAGE_ORDERLIST_VOLUMES); } else { if (k->state == KEY_PRESS) set_page(PAGE_ORDERLIST_PANNING); } } else if (k->mod & KMOD_CTRL) { if (k->state == KEY_PRESS) { _mp_finish(NULL); if (status.current_page == PAGE_LOG) { show_about(); } else { set_page(PAGE_LOG); } } } else if (k->state == KEY_PRESS && (k->mod & KMOD_ALT)) { _mp_finish(NULL); if (song_toggle_orderlist_locked()) status_text_flash("Order list locked"); else status_text_flash("Order list unlocked"); } else { break; } return 1; case SDLK_F12: if (status.dialog_type != DIALOG_NONE) return 0; if ((k->mod & KMOD_ALT) && status.current_page == PAGE_INFO) { _mp_finish(NULL); if (k->state == KEY_PRESS) set_page(PAGE_WATERFALL); } else if (k->mod & KMOD_CTRL) { _mp_finish(NULL); if (k->state == KEY_PRESS) set_page(PAGE_PALETTE_EDITOR); } else if (k->mod & KMOD_SHIFT) { _mp_finish(NULL); if (k->state == KEY_PRESS) { fontedit_return_page = status.current_page; set_page(PAGE_FONT_EDIT); } } else if (NO_MODIFIER(k->mod)) { _mp_finish(NULL); if (k->state == KEY_PRESS) set_page(PAGE_SONG_VARIABLES); } else { break; } return 1; /* hack alert */ case SDLK_f: if (!(k->mod & KMOD_CTRL)) return 0; /* fall through */ case SDLK_SCROLLOCK: if (status.dialog_type != DIALOG_NONE) return 0; _mp_finish(NULL); if (k->mod & KMOD_ALT) { if (k->state == KEY_PRESS) { midi_flags ^= (MIDI_DISABLE_RECORD); status_text_flash("MIDI Input %s", (midi_flags & MIDI_DISABLE_RECORD) ? "Disabled" : "Enabled"); } return 1; } else { /* os x steals plain scroll lock for brightness, * so catch ctrl+scroll lock here as well */ if (k->state == KEY_PRESS) { midi_playback_tracing = (playback_tracing = !playback_tracing); status_text_flash("Playback tracing %s", (playback_tracing ? "enabled" : "disabled")); } return 1; } default: if (status.dialog_type != DIALOG_NONE) return 0; break; } /* got a bit ugly here, sorry */ i = k->sym; if (k->mod & KMOD_ALT) { switch (i) { case SDLK_F1: i = 0; break; case SDLK_F2: i = 1; break; case SDLK_F3: i = 2; break; case SDLK_F4: i = 3; break; case SDLK_F5: i = 4; break; case SDLK_F6: i = 5; break; case SDLK_F7: i = 6; break; case SDLK_F8: i = 7; break; default: return 0; }; if (k->state == KEY_RELEASE) return 1; song_toggle_channel_mute(i); status.flags |= NEED_UPDATE; return 1; } /* oh well */ return 0; }
/* this is the important one */ void handle_key(struct key_event *k) { if (_handle_ime(k)) return; /* okay... */ if (!(status.flags & DISKWRITER_ACTIVE) && ACTIVE_PAGE.pre_handle_key) { if (ACTIVE_PAGE.pre_handle_key(k)) return; } if (handle_key_global(k)) return; if (!(status.flags & DISKWRITER_ACTIVE) && menu_handle_key(k)) return; if (widget_handle_key(k)) return; /* now check a couple other keys. */ switch (k->sym) { case SDLK_LEFT: if (k->state == KEY_RELEASE) return; if (status.flags & DISKWRITER_ACTIVE) return; if ((k->mod & KMOD_CTRL) && status.current_page != PAGE_PATTERN_EDITOR) { _mp_finish(NULL); if (song_get_mode() == MODE_PLAYING) song_set_current_order(song_get_current_order() - 1); return; } break; case SDLK_RIGHT: if (k->state == KEY_RELEASE) return; if (status.flags & DISKWRITER_ACTIVE) return; if ((k->mod & KMOD_CTRL) && status.current_page != PAGE_PATTERN_EDITOR) { _mp_finish(NULL); if (song_get_mode() == MODE_PLAYING) song_set_current_order(song_get_current_order() + 1); return; } break; case SDLK_ESCAPE: /* TODO | Page key handlers should return true/false depending on if the key was handled TODO | (same as with other handlers), and the escape key check should go *after* the TODO | page gets a chance to grab it. This way, the load sample page can switch back TODO | to the sample list on escape like it's supposed to. (The status.current_page TODO | checks above won't be necessary, either.) */ if (NO_MODIFIER(k->mod) && status.dialog_type == DIALOG_NONE && status.current_page != PAGE_LOAD_SAMPLE && status.current_page != PAGE_LOAD_INSTRUMENT) { if (k->state == KEY_RELEASE) return; if (_mp_active) { _mp_finish(NULL); return; } menu_show(); return; } break; case SDLK_SLASH: if (k->state == KEY_RELEASE) return; if (status.flags & DISKWRITER_ACTIVE) return; if (k->orig_sym == SDLK_KP_DIVIDE) { kbd_set_current_octave(kbd_get_current_octave() - 1); } return; case SDLK_ASTERISK: if (k->state == KEY_RELEASE) return; if (status.flags & DISKWRITER_ACTIVE) return; if (k->orig_sym == SDLK_KP_MULTIPLY) { kbd_set_current_octave(kbd_get_current_octave() + 1); } return; case SDLK_LEFTBRACKET: if (k->state == KEY_RELEASE) break; if (status.flags & DISKWRITER_ACTIVE) return; if (k->mod & KMOD_SHIFT) { song_set_current_speed(song_get_current_speed() - 1); status_text_flash("Speed set to %d frames per row", song_get_current_speed()); if (!(song_get_mode() & (MODE_PLAYING | MODE_PATTERN_LOOP))) { song_set_initial_speed(song_get_current_speed()); } } else if ((k->mod & KMOD_CTRL) && !(status.flags & CLASSIC_MODE)) { song_set_current_tempo(song_get_current_tempo() - 1); status_text_flash("Tempo set to %d frames per row", song_get_current_tempo()); if (!(song_get_mode() & (MODE_PLAYING | MODE_PATTERN_LOOP))) { song_set_initial_tempo(song_get_current_tempo()); } } else if (NO_MODIFIER(k->mod)) { song_set_current_global_volume(song_get_current_global_volume() - 1); status_text_flash("Global volume set to %d", song_get_current_global_volume()); if (!(song_get_mode() & (MODE_PLAYING | MODE_PATTERN_LOOP))) { song_set_initial_global_volume(song_get_current_global_volume()); } } return; case SDLK_RIGHTBRACKET: if (k->state == KEY_RELEASE) break; if (status.flags & DISKWRITER_ACTIVE) return; if (k->mod & KMOD_SHIFT) { song_set_current_speed(song_get_current_speed() + 1); status_text_flash("Speed set to %d frames per row", song_get_current_speed()); if (!(song_get_mode() & (MODE_PLAYING | MODE_PATTERN_LOOP))) { song_set_initial_speed(song_get_current_speed()); } } else if ((k->mod & KMOD_CTRL) && !(status.flags & CLASSIC_MODE)) { song_set_current_tempo(song_get_current_tempo() + 1); status_text_flash("Tempo set to %d frames per row", song_get_current_tempo()); if (!(song_get_mode() & (MODE_PLAYING | MODE_PATTERN_LOOP))) { song_set_initial_tempo(song_get_current_tempo()); } } else if (NO_MODIFIER(k->mod)) { song_set_current_global_volume(song_get_current_global_volume() + 1); status_text_flash("Global volume set to %d", song_get_current_global_volume()); if (!(song_get_mode() & (MODE_PLAYING | MODE_PATTERN_LOOP))) { song_set_initial_global_volume(song_get_current_global_volume()); } } return; default: break; } /* and if we STILL didn't handle the key, pass it to the page. * (or dialog, if one's active) */ if (status.dialog_type & DIALOG_BOX) { dialog_handle_key(k); } else { if (status.flags & DISKWRITER_ACTIVE) return; if (ACTIVE_PAGE.handle_key) ACTIVE_PAGE.handle_key(k); } }