void new_song_dialog(void) { struct dialog *dialog; /* only create everything if it hasn't been set up already */ if (new_song_widgets[0].width == 0) { create_togglebutton(new_song_widgets + 0, 35, 24, 6, 0, 2, 1, 1, 1, NULL, "Keep", 2, new_song_groups[0]); create_togglebutton(new_song_widgets + 1, 45, 24, 7, 1, 3, 0, 0, 0, NULL, "Clear", 2, new_song_groups[0]); create_togglebutton(new_song_widgets + 2, 35, 27, 6, 0, 4, 3, 3, 3, NULL, "Keep", 2, new_song_groups[1]); create_togglebutton(new_song_widgets + 3, 45, 27, 7, 1, 5, 2, 2, 2, NULL, "Clear", 2, new_song_groups[1]); create_togglebutton(new_song_widgets + 4, 35, 30, 6, 2, 6, 5, 5, 5, NULL, "Keep", 2, new_song_groups[2]); create_togglebutton(new_song_widgets + 5, 45, 30, 7, 3, 7, 4, 4, 4, NULL, "Clear", 2, new_song_groups[2]); create_togglebutton(new_song_widgets + 6, 35, 33, 6, 4, 8, 7, 7, 7, NULL, "Keep", 2, new_song_groups[3]); create_togglebutton(new_song_widgets + 7, 45, 33, 7, 5, 9, 6, 6, 6, NULL, "Clear", 2, new_song_groups[3]); create_button(new_song_widgets + 8, 28, 36, 8, 6, 8, 9, 9, 9, dialog_yes_NULL, "OK", 4); create_button(new_song_widgets + 9, 41, 36, 8, 6, 9, 8, 8, 8, dialog_cancel_NULL, "Cancel", 2); togglebutton_set(new_song_widgets, 1, 0); togglebutton_set(new_song_widgets, 3, 0); togglebutton_set(new_song_widgets, 5, 0); togglebutton_set(new_song_widgets, 7, 0); } dialog = dialog_create_custom(21, 20, 38, 19, new_song_widgets, 10, 8, new_song_draw_const, NULL); dialog->action_yes = new_song_ok; }
static void loadsave_song_changed(void) { int r = 4; /* what? */ int i; const char *ext; const char *ptr = song_get_filename(); if (!ptr) return; ext = get_extension(ptr); if (ext[0] && ext[1]) { for (i = 0; song_save_formats[i].label; i++) { if (strcasecmp(ext, song_save_formats[i].ext) == 0) { /* ugh :) offset to the button for the file type on the save module page is (position in diskwriter driver array) + 4 */ r = i + 4; break; } } } togglebutton_set(widgets_savemodule, r, 0); }
/* 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; }