void ServePlayState::handle_events(KinectInput* kinect) { cv::Mat depth, rgb; if (m_game->get_kinect()->poll_data(rgb, depth)) { //cv::GaussianBlur(depth, depth, cv::Size(11, 11), 3, 3); //cv::medianBlur(depth, depth, 11); cv::flip(rgb, rgb, 1); cv::flip(depth, depth, 1); m_game->get_image_processor()->set_player_masks(depth); //face detector is too slow to run in this loop //m_game->get_image_processor()->find_player_faces(rgb, depth); cv::Mat right_player_mask; m_game->get_image_processor()->get_right_player_mask(right_player_mask); m_game->get_gameboard()->get_player(0)->player_input(right_player_mask); cv::Mat left_player_mask; m_game->get_image_processor()->get_left_player_mask(left_player_mask); m_game->get_gameboard()->get_player(1)->player_input(left_player_mask); cv::Mat right_contact_mask; m_game->get_image_processor()->get_right_player_contact_mask(right_contact_mask); m_game->get_gameboard()->get_player(0)->paddle_input(right_contact_mask); cv::Mat left_contact_mask; m_game->get_image_processor()->get_left_player_contact_mask(left_contact_mask); m_game->get_gameboard()->get_player(1)->paddle_input(left_contact_mask); } default_event_handler(); }
bool action_userabort(int timeout) { int action = get_action_worker(CONTEXT_STD,timeout,NULL); bool ret = (action == ACTION_STD_CANCEL); if(!ret) { default_event_handler(action); } return ret; }
static bool reset_settings(void) { bool done=false; int line; int button; lcd_clear_display(); #ifdef HAVE_LCD_CHARCELLS line = 0; #else line = 1; lcd_puts(0,0,str(LANG_RESET_ASK_RECORDER)); #endif lcd_puts(0,line,str(LANG_RESET_CONFIRM)); lcd_puts(0,line+1,str(LANG_RESET_CANCEL)); lcd_update(); while(!done) { button = button_get(true); switch(button) { case SETTINGS_OK: settings_reset(); settings_apply(); lcd_clear_display(); lcd_puts(0,1,str(LANG_RESET_DONE_CLEAR)); done = true; break; case SETTINGS_CANCEL: lcd_clear_display(); lcd_puts(0,1,str(LANG_RESET_DONE_CANCEL)); done = true; break; default: if(default_event_handler(button) == SYS_USB_CONNECTED) return true; } } lcd_puts(0,0,str(LANG_RESET_DONE_SETTING)); lcd_update(); sleep(HZ); return false; }
static bool gui_syncquickscreen_run(struct gui_quickscreen * qs, int button_enter) { int button, i, j; struct viewport parent[NB_SCREENS]; struct viewport vps[NB_SCREENS][QUICKSCREEN_ITEM_COUNT]; struct viewport vp_icons[NB_SCREENS]; bool changed = false; /* To quit we need either : * - a second press on the button that made us enter * - an action taken while pressing the enter button, * then release the enter button*/ bool can_quit = false; FOR_NB_SCREENS(i) { screens[i].set_viewport(NULL); screens[i].stop_scroll(); viewportmanager_theme_enable(i, true, &parent[i]); quickscreen_fix_viewports(qs, &screens[i], &parent[i], vps[i], &vp_icons[i]); gui_quickscreen_draw(qs, &screens[i], &parent[i], vps[i], &vp_icons[i]); } /* Announce current selection on entering this screen. This is all queued up, but can be interrupted as soon as a setting is changed. */ cond_talk_ids(VOICE_QUICKSCREEN); talk_qs_option(qs->items[QUICKSCREEN_TOP], true); talk_qs_option(qs->items[QUICKSCREEN_LEFT], true); talk_qs_option(qs->items[QUICKSCREEN_BOTTOM], true); talk_qs_option(qs->items[QUICKSCREEN_RIGHT], true); while (true) { button = get_action(CONTEXT_QUICKSCREEN, HZ/5); #ifdef HAVE_TOUCHSCREEN if (button == ACTION_TOUCHSCREEN) button = quickscreen_touchscreen_button(vps[SCREEN_MAIN]); #endif if (default_event_handler(button) == SYS_USB_CONNECTED) return(true); if (gui_quickscreen_do_button(qs, button)) { changed = true; can_quit = true; FOR_NB_SCREENS(i) gui_quickscreen_draw(qs, &screens[i], &parent[i], vps[i], &vp_icons[i]); if (qs->callback) qs->callback(qs); } else if (button == button_enter) can_quit = true; if ((button == button_enter) && can_quit) break; if (button == ACTION_STD_CANCEL) break; } /* Notify that we're exiting this screen */ cond_talk_ids_fq(VOICE_OK); FOR_NB_SCREENS(i) { /* stop scrolling before exiting */ for (j = 0; j < QUICKSCREEN_ITEM_COUNT; j++) screens[i].scroll_stop(&vps[i][j]); viewportmanager_theme_undo(i, true); } return changed; }
void radio_screen(void) { bool done = false; int button; bool stereo = false, last_stereo = false; int update_type = 0; bool screen_freeze = false; bool keep_playing = false; bool talk = false; #ifdef FM_RECORD_DBLPRE int lastbutton = BUTTON_NONE; unsigned long rec_lastclick = 0; #endif #if CONFIG_CODEC != SWCODEC int timeout = current_tick + HZ/10; #if !defined(SIMULATOR) unsigned int last_seconds = 0; unsigned int seconds = 0; struct audio_recording_options rec_options; #endif /* SIMULATOR */ #endif /* CONFIG_CODEC != SWCODEC */ #ifndef HAVE_NOISY_IDLE_MODE int button_timeout = current_tick + (2*HZ); #endif /* change status to "in screen" */ push_current_activity(ACTIVITY_FM); in_screen = true; if(radio_preset_count() <= 0) { radio_load_presets(global_settings.fmr_file); } skin_get_global_state()->id3 = NULL; #ifdef HAVE_ALBUMART radioart_init(true); #endif if(radio_status == FMRADIO_OFF) audio_stop(); fms_fix_displays(FMS_ENTER); #ifndef SIMULATOR #if CONFIG_CODEC != SWCODEC rec_create_directory(); audio_init_recording(); sound_settings_apply(); /* Yes, we use the D/A for monitoring */ peak_meter_playback(true); peak_meter_enable(true); rec_init_recording_options(&rec_options); rec_options.rec_source = AUDIO_SRC_LINEIN; rec_set_recording_options(&rec_options); audio_set_recording_gain(sound_default(SOUND_LEFT_GAIN), sound_default(SOUND_RIGHT_GAIN), AUDIO_GAIN_LINEIN); #endif /* CONFIG_CODEC != SWCODEC */ #endif /* ndef SIMULATOR */ /* turn on radio */ #if CONFIG_CODEC == SWCODEC /* This should be done before touching audio settings */ while (!pcm_is_initialized()) sleep(0); audio_set_input_source(AUDIO_SRC_FMRADIO, (radio_status == FMRADIO_PAUSED) ? SRCF_FMRADIO_PAUSED : SRCF_FMRADIO_PLAYING); #else if (radio_status == FMRADIO_OFF) radio_start(); #endif if(radio_preset_count() < 1 && yesno_pop(ID2P(LANG_FM_FIRST_AUTOSCAN))) presets_scan(NULL); preset_set_current(preset_find(curr_freq)); if(radio_current_preset() != -1) radio_mode = RADIO_PRESET_MODE; /* Load/update the skin at last, when fully initialzed, so that it can * display the right content from the beginning */ FOR_NB_SCREENS(i) skin_update(FM_SCREEN, i, SKIN_REFRESH_ALL); #ifndef HAVE_NOISY_IDLE_MODE cpu_idle_mode(true); #endif while(!done) { if(search_dir != 0) { curr_freq = step_freq(curr_freq, search_dir); update_type = SKIN_REFRESH_ALL; if(tuner_set(RADIO_SCAN_FREQUENCY, curr_freq)) { preset_set_current(preset_find(curr_freq)); remember_frequency(); end_search(); talk = true; } trigger_cpu_boost(); } if (!update_type) { cancel_cpu_boost(); } button = fms_do_button_loop(update_type>0); #ifndef HAVE_NOISY_IDLE_MODE if (button != ACTION_NONE) { cpu_idle_mode(false); button_timeout = current_tick + (2*HZ); } #endif switch(button) { case ACTION_FM_STOP: #if CONFIG_CODEC != SWCODEC && !defined(SIMULATOR) if(audio_status() == AUDIO_STATUS_RECORD) { audio_stop(); } else #endif { done = true; if(presets_have_changed()) { if(yesno_pop(ID2P(LANG_SAVE_CHANGES))) { presets_save(); } } } update_type = SKIN_REFRESH_NON_STATIC; break; #ifdef FM_RECORD case ACTION_FM_RECORD: #ifdef FM_RECORD_DBLPRE if (lastbutton != ACTION_FM_RECORD_DBLPRE) { rec_lastclick = 0; break; } if (current_tick - rec_lastclick > HZ/2) { rec_lastclick = current_tick; break; } #endif /* FM_RECORD_DBLPRE */ #ifndef SIMULATOR if(audio_status() == AUDIO_STATUS_RECORD) { rec_command(RECORDING_CMD_START_NEWFILE); update_type = SKIN_REFRESH_ALL; } else { rec_command(RECORDING_CMD_START); update_type = SKIN_REFRESH_ALL; } #if CONFIG_CODEC != SWCODEC last_seconds = 0; #endif #endif /* SIMULATOR */ break; #endif /* #ifdef FM_RECORD */ case ACTION_FM_EXIT: #if CONFIG_CODEC != SWCODEC && !defined(SIMULATOR) if(audio_status() == AUDIO_STATUS_RECORD) audio_stop(); #endif keep_playing = true; done = true; if(presets_have_changed()) { if(yesno_pop(ID2P(LANG_SAVE_CHANGES))) { presets_save(); } } break; case ACTION_STD_PREV: case ACTION_STD_NEXT: next_station(button == ACTION_STD_PREV ? -1 : 1); end_search(); update_type = SKIN_REFRESH_ALL; talk = true; break; case ACTION_STD_PREVREPEAT: case ACTION_STD_NEXTREPEAT: { int dir = search_dir; search_dir = button == ACTION_STD_PREVREPEAT ? -1 : 1; if (radio_mode != RADIO_SCAN_MODE) { preset_next(search_dir); end_search(); talk = true; } else if (dir == 0) { /* Starting auto scan */ tuner_set(RADIO_MUTE, 1); } update_type = SKIN_REFRESH_ALL; break; } case ACTION_SETTINGS_INC: case ACTION_SETTINGS_INCREPEAT: global_settings.volume++; setvol(); update_type = SKIN_REFRESH_NON_STATIC; break; case ACTION_SETTINGS_DEC: case ACTION_SETTINGS_DECREPEAT: global_settings.volume--; setvol(); update_type = SKIN_REFRESH_NON_STATIC; break; case ACTION_FM_PLAY: if (radio_status == FMRADIO_PLAYING) radio_pause(); else radio_start(); update_type = SKIN_REFRESH_NON_STATIC; talk = false; talk_shutup(); break; case ACTION_FM_MENU: fms_fix_displays(FMS_EXIT); do_menu(&radio_settings_menu, NULL, NULL, false); preset_set_current(preset_find(curr_freq)); fms_fix_displays(FMS_ENTER); update_type = SKIN_REFRESH_ALL; break; #ifdef FM_PRESET case ACTION_FM_PRESET: if(radio_preset_count() < 1) { splash(HZ, ID2P(LANG_FM_NO_PRESETS)); update_type = SKIN_REFRESH_ALL; break; } fms_fix_displays(FMS_EXIT); handle_radio_presets(); fms_fix_displays(FMS_ENTER); update_type = SKIN_REFRESH_ALL; break; #endif /* FM_PRESET */ #ifdef FM_FREEZE case ACTION_FM_FREEZE: if(!screen_freeze) { splash(HZ, str(LANG_FM_FREEZE)); screen_freeze = true; } else { update_type = SKIN_REFRESH_ALL; screen_freeze = false; } break; #endif /* FM_FREEZE */ case SYS_USB_CONNECTED: #if CONFIG_CODEC != SWCODEC /* Only accept USB connection when not recording */ if(audio_status() != AUDIO_STATUS_RECORD) #endif { default_event_handler(SYS_USB_CONNECTED); screen_freeze = true; /* Cosmetic: makes sure the radio screen doesn't redraw */ done = true; } break; #ifdef FM_MODE case ACTION_FM_MODE: if(radio_mode == RADIO_SCAN_MODE) { /* Force scan mode if there are no presets. */ if(radio_preset_count() > 0) radio_mode = RADIO_PRESET_MODE; } else radio_mode = RADIO_SCAN_MODE; update_type = SKIN_REFRESH_ALL; cond_talk_ids_fq(radio_mode ? LANG_PRESET : LANG_RADIO_SCAN_MODE); talk = true; break; #endif /* FM_MODE */ #ifdef FM_NEXT_PRESET case ACTION_FM_NEXT_PRESET: preset_next(1); end_search(); update_type = SKIN_REFRESH_ALL; talk = true; break; #endif #ifdef FM_PREV_PRESET case ACTION_FM_PREV_PRESET: preset_next(-1); end_search(); update_type = SKIN_REFRESH_ALL; talk = true; break; #endif case ACTION_NONE: update_type = SKIN_REFRESH_NON_STATIC; break; /* this case is used by the softlock feature * it requests a full update here */ case ACTION_REDRAW: skin_request_full_update(FM_SCREEN); break; default: default_event_handler(button); #ifdef HAVE_RDS_CAP if (tuner_get(RADIO_EVENT)) update_type = SKIN_REFRESH_ALL; #endif if (!tuner_get(RADIO_PRESENT)) { #if CONFIG_CODEC != SWCODEC && !defined(SIMULATOR) if(audio_status() == AUDIO_STATUS_RECORD) audio_stop(); #endif keep_playing = false; done = true; if(presets_have_changed()) { if(yesno_pop(ID2P(LANG_SAVE_CHANGES))) { radio_save_presets(); } } /* Clear the preset list on exit. */ preset_list_clear(); } break; } /*switch(button)*/ #ifdef FM_RECORD_DBLPRE if (button != ACTION_NONE) lastbutton = button; #endif #if CONFIG_CODEC != SWCODEC peak_meter_peek(); #endif if(!screen_freeze) { /* Only display the peak meter when not recording */ #if CONFIG_CODEC != SWCODEC if(TIME_AFTER(current_tick, timeout)) { timeout = current_tick + HZ; #else /* SWCODEC */ { #endif /* CONFIG_CODEC == SWCODEC */ /* keep "mono" from always being displayed when paused */ if (radio_status != FMRADIO_PAUSED) { stereo = tuner_get(RADIO_STEREO) && !global_settings.fm_force_mono; if(stereo != last_stereo) { update_type = SKIN_REFRESH_ALL; last_stereo = stereo; } } } #if CONFIG_CODEC != SWCODEC && !defined(SIMULATOR) seconds = audio_recorded_time() / HZ; if (update_type || seconds > last_seconds) { last_seconds = seconds; #else if (update_type) { #endif FOR_NB_SCREENS(i) skin_update(FM_SCREEN, i, update_type); if (update_type == (int)SKIN_REFRESH_ALL) skin_request_full_update(CUSTOM_STATUSBAR); } } update_type = 0; if (global_settings.talk_file && talk && radio_status == FMRADIO_PAUSED) { talk = false; bool enqueue = false; if (radio_mode == RADIO_SCAN_MODE) { talk_value_decimal(curr_freq, UNIT_INT, 6, enqueue); enqueue = true; } if (radio_current_preset() >= 0) preset_talk(radio_current_preset(), radio_mode == RADIO_PRESET_MODE, enqueue); } #if CONFIG_CODEC != SWCODEC if(audio_status() & AUDIO_STATUS_ERROR) { done = true; } #endif #ifndef HAVE_NOISY_IDLE_MODE if (TIME_AFTER(current_tick, button_timeout)) { cpu_idle_mode(true); } #endif } /*while(!done)*/ #ifndef SIMULATOR #if CONFIG_CODEC != SWCODEC if(audio_status() & AUDIO_STATUS_ERROR) { splash(0, str(LANG_DISK_FULL)); audio_error_clear(); while(1) { button = get_action(CONTEXT_FM|ALLOW_SOFTLOCK, TIMEOUT_BLOCK); if(button == ACTION_FM_STOP) break; } } audio_init_playback(); #endif /* CONFIG_CODEC != SWCODEC */ sound_settings_apply(); #endif /* SIMULATOR */ if(keep_playing) { /* Catch FMRADIO_PLAYING status for the sim. */ #ifndef SIMULATOR #if CONFIG_CODEC != SWCODEC /* Enable the Left and right A/D Converter */ audio_set_recording_gain(sound_default(SOUND_LEFT_GAIN), sound_default(SOUND_RIGHT_GAIN), AUDIO_GAIN_LINEIN); mas_codec_writereg(6, 0x4000); #endif end_search(); #endif /* SIMULATOR */ } else { #if CONFIG_CODEC == SWCODEC audio_set_input_source(AUDIO_SRC_PLAYBACK, SRCF_PLAYBACK); #else radio_stop(); #endif } #ifndef HAVE_NOISY_IDLE_MODE cpu_idle_mode(false); #endif fms_fix_displays(FMS_EXIT); pop_current_activity(); in_screen = false; } /* radio_screen */ void toggle_mono_mode(bool mono) { tuner_set(RADIO_FORCE_MONO, mono); } void set_radio_region(int region) { #ifdef HAVE_RADIO_REGION tuner_set(RADIO_REGION, region); #endif next_station(0); remember_frequency(); (void)region; }
bool alarm_screen(void) { int h, m; bool done = false; struct tm *tm; int togo; int button; bool update = true; bool hour_wrapped = false; struct viewport vp[NB_SCREENS]; rtc_get_alarm(&h, &m); /* After a battery change the RTC values are out of range */ if (m > 60 || h > 24) { m = 0; h = 12; } else { m = m / 5 * 5; /* 5 min accuracy should be enough */ } FOR_NB_SCREENS(i) { viewport_set_defaults(&vp[i], i); } while(!done) { if(update) { FOR_NB_SCREENS(i) { screens[i].set_viewport(&vp[i]); screens[i].clear_viewport(); screens[i].puts(0, 4, str(LANG_ALARM_MOD_KEYS)); } /* Talk when entering the wakeup screen */ speak_time(h, m, true, true); update = false; } FOR_NB_SCREENS(i) { screens[i].set_viewport(&vp[i]); screens[i].putsf(0, 1, str(LANG_ALARM_MOD_TIME)); screens[i].putsf(0, 2, "%02d:%02d", h, m); screens[i].update_viewport(); screens[i].set_viewport(NULL); } button = get_action(CONTEXT_SETTINGS,HZ); switch(button) { case ACTION_STD_OK: /* prevent that an alarm occurs in the shutdown procedure */ /* accept alarms only if they are in 2 minutes or more */ tm = get_time(); togo = (m + h * 60 - tm->tm_min - tm->tm_hour * 60 + 1440) % 1440; if (togo > 1) { rtc_init(); rtc_set_alarm(h,m); rtc_enable_alarm(true); if (global_settings.talk_menu) { talk_id(LANG_ALARM_MOD_TIME_TO_GO, true); talk_value(togo / 60, UNIT_HOUR, true); talk_value(togo % 60, UNIT_MIN, true); talk_force_enqueue_next(); } splashf(HZ*2, str(LANG_ALARM_MOD_TIME_TO_GO), togo / 60, togo % 60); done = true; } else { splash(HZ, ID2P(LANG_ALARM_MOD_ERROR)); update = true; } break; /* inc(m) */ case ACTION_SETTINGS_INC: case ACTION_SETTINGS_INCREPEAT: m += 5; if (m == 60) { h += 1; m = 0; hour_wrapped = true; } if (h == 24) h = 0; speak_time(h, m, hour_wrapped, false); break; /* dec(m) */ case ACTION_SETTINGS_DEC: case ACTION_SETTINGS_DECREPEAT: m -= 5; if (m == -5) { h -= 1; m = 55; hour_wrapped = true; } if (h == -1) h = 23; speak_time(h, m, hour_wrapped, false); break; /* inc(h) */ case ACTION_STD_NEXT: case ACTION_STD_NEXTREPEAT: h = (h+1) % 24; if (global_settings.talk_menu) talk_value(h, UNIT_HOUR, false); break; /* dec(h) */ case ACTION_STD_PREV: case ACTION_STD_PREVREPEAT: h = (h+23) % 24; if (global_settings.talk_menu) talk_value(h, UNIT_HOUR, false); break; case ACTION_STD_CANCEL: rtc_enable_alarm(false); splash(HZ*2, ID2P(LANG_ALARM_MOD_DISABLE)); done = true; break; case ACTION_NONE: hour_wrapped = false; break; default: if(default_event_handler(button) == SYS_USB_CONNECTED) { rtc_enable_alarm(false); return true; } break; } } return false; }
enum yesno_res gui_syncyesno_run(const struct text_message * main_message, const struct text_message * yes_message, const struct text_message * no_message) { int button; int result=-1; bool result_displayed; struct gui_yesno yn[NB_SCREENS]; struct viewport vp[NB_SCREENS]; long talked_tick = 0; FOR_NB_SCREENS(i) { yn[i].main_message=main_message; yn[i].result_message[YESNO_YES]=yes_message; yn[i].result_message[YESNO_NO]=no_message; yn[i].display=&screens[i]; yn[i].vp = &vp[i]; #ifdef HAVE_LCD_CHARCELLS /* Quick fix. Viewports should really be enabled proper for charcell */ viewport_set_defaults(yn[i].vp, i); #else viewportmanager_theme_enable(i, true, yn[i].vp); #endif screens[i].stop_scroll(); gui_yesno_draw(&(yn[i])); } /* make sure to eat any extranous keypresses */ while (get_action(CONTEXT_STD+99, TIMEOUT_NOBLOCK)) action_wait_for_release(); while (result==-1) { /* Repeat the question every 5secs (more or less) */ if (global_settings.talk_menu && (talked_tick==0 || TIME_AFTER(current_tick, talked_tick+HZ*5))) { talked_tick = current_tick; talk_text_message(main_message, false); } button = get_action(CONTEXT_YESNOSCREEN, HZ*5); switch (button) { #ifdef HAVE_TOUCHSCREEN case ACTION_TOUCHSCREEN: { short int x, y; if (action_get_touchscreen_press_in_vp(&x, &y, yn[0].vp) == BUTTON_TOUCHSCREEN) { if (y > yn[0].vp->height/2) { if (x <= yn[0].vp->width/2) result = YESNO_YES; else result = YESNO_NO; } } } break; #endif case ACTION_YESNO_ACCEPT: result=YESNO_YES; break; case ACTION_NONE: case SYS_CHARGER_DISCONNECTED: case SYS_BATTERY_UPDATE: /* ignore some SYS events that can happen */ continue; default: if(default_event_handler(button) == SYS_USB_CONNECTED) return(YESNO_USB); result = YESNO_NO; } } FOR_NB_SCREENS(i) result_displayed=gui_yesno_draw_result(&(yn[i]), result); if (global_settings.talk_menu) { talk_text_message((result == YESNO_YES) ? yes_message : no_message, false); talk_force_enqueue_next(); } if(result_displayed) sleep(HZ); FOR_NB_SCREENS(i) { screens[i].scroll_stop(yn[i].vp); viewportmanager_theme_undo(i, true); } return(result); }
/*********** set_color returns true if USB was inserted, false otherwise color is a pointer to the colour (in native format) to modify set banned_color to -1 to allow all ***********/ bool set_color(struct screen *display, char *title, unsigned *color, unsigned banned_color) { int exit = 0, slider = 0; struct rgb_pick rgb; rgb.color = *color; while (!exit) { int button; unpack_rgb(&rgb); if (display != NULL) { draw_screen(display, title, &rgb, slider); } else { FOR_NB_SCREENS(i) draw_screen(&screens[i], title, &rgb, slider); } button = get_action(CONTEXT_SETTINGS_COLOURCHOOSER, TIMEOUT_BLOCK); #ifdef HAVE_TOUCHSCREEN if (button == ACTION_TOUCHSCREEN && display->screen_type == SCREEN_MAIN) button = touchscreen_slider(display, &rgb, &slider); #endif switch (button) { case ACTION_STD_PREV: case ACTION_STD_PREVREPEAT: slider = (slider + 2) % 3; break; case ACTION_STD_NEXT: case ACTION_STD_NEXTREPEAT: slider = (slider + 1) % 3; break; case ACTION_SETTINGS_INC: case ACTION_SETTINGS_INCREPEAT: if (rgb.rgb_val[slider] < rgb_max[slider]) rgb.rgb_val[slider]++; pack_rgb(&rgb); break; case ACTION_SETTINGS_DEC: case ACTION_SETTINGS_DECREPEAT: if (rgb.rgb_val[slider] > 0) rgb.rgb_val[slider]--; pack_rgb(&rgb); break; case ACTION_STD_OK: if (banned_color != (unsigned)-1 && banned_color == rgb.color) { splash(HZ*2, ID2P(LANG_COLOR_UNACCEPTABLE)); break; } *color = rgb.color; exit = 1; break; case ACTION_STD_CANCEL: exit = 1; break; default: if (default_event_handler(button) == SYS_USB_CONNECTED) return true; break; } } return false; }
int kbd_input(char* text, int buflen) { bool done = false; bool redraw = true; bool line_edit = false; int page = 0, x = 0; int linelen; int len, i; int editpos, curpos, leftpos; unsigned short* line = kbd_setupkeys(page, &linelen); unsigned char temptext[12]; int button, lastbutton = 0; editpos = strlen(text); if (global_settings.talk_menu) /* voice UI? */ talk_spell(text, true); /* spell initial text */ while (!done) { len = strlen(text); if (redraw) { if (line_edit) { lcd_putc(0, 0, ' '); lcd_putc(0, 1, KEYBOARD_ARROW); } else { lcd_putc(0, 0, KEYBOARD_ARROW); lcd_putc(0, 1, ' '); } /* Draw insert chars */ temptext[0] = KEYBOARD_INSERT_LEFT; temptext[1] = line[x]; temptext[2] = KEYBOARD_INSERT_RIGHT; for (i = 1; i < 8; i++) { temptext[i+2] = line[(x+i)%linelen]; } temptext[i+2] = 0; lcd_puts(1, 0, temptext); /* write out the text */ curpos = MIN(MIN(editpos, 10 - MIN(len - editpos, 3)), 9); leftpos = editpos - curpos; strncpy(temptext, text + leftpos, 10); temptext[10] = 0; if (leftpos) temptext[0] = '<'; if (len - leftpos > 10) temptext[9] = '>'; lcd_remove_cursor(); lcd_puts(1, 1, temptext); lcd_put_cursor(curpos + 1, 1, KEYBOARD_CURSOR); status_draw(true); } /* The default action is to redraw */ redraw = true; button = button_get_w_tmo(HZ/2); switch (button) { case BUTTON_STOP: /* abort */ return -1; break; case BUTTON_MENU: /* page flip */ if (++page == KEYBOARD_PAGES) page = 0; line = kbd_setupkeys(page, &linelen); if (x > linelen - 1) x = linelen - 1; kbd_spellchar(line[x]); break; case BUTTON_ON: /* toggle mode */ line_edit = !line_edit; if (!line_edit) kbd_spellchar(line[x]); break; case BUTTON_RIGHT: case BUTTON_RIGHT | BUTTON_REPEAT: if (line_edit) { if (editpos < len) { editpos++; kbd_spellchar(text[editpos]); } } else { if (++x >= linelen) x = 0; kbd_spellchar(line[x]); } break; case BUTTON_LEFT: case BUTTON_LEFT | BUTTON_REPEAT: if (line_edit) { if (editpos) { editpos--; kbd_spellchar(text[editpos]); } } else { if (--x < 0) x = linelen - 1; kbd_spellchar(line[x]); } break; case BUTTON_PLAY | BUTTON_REPEAT: /* accepts what was entered and continues */ done = true; break; case BUTTON_PLAY | BUTTON_REL: if (lastbutton != BUTTON_PLAY) break; if (line_edit) /* backspace in line_edit */ { if (editpos > 0) { for (i = editpos; i < len; i++) text[i-1] = text[i]; text[i-1] = '\0'; editpos--; } } else /* inserts the selected char */ { if (len + 1 < buflen) { for (i = len ; i > editpos; i--) text[i] = text[i-1]; text[len+1] = 0; text[editpos] = line[x]; editpos++; } } if (global_settings.talk_menu) /* voice UI? */ talk_spell(text, false); /* speak revised text */ break; case BUTTON_NONE: status_draw(false); redraw = false; break; default: default_event_handler(button); break; } if (button != BUTTON_NONE) lastbutton = button; } return 0; }
enum yesno_res gui_syncyesno_run(const struct text_message * main_message, const struct text_message * yes_message, const struct text_message * no_message) { int i; int button; int result=-1; bool result_displayed; struct gui_yesno yn[NB_SCREENS]; struct viewport vp[NB_SCREENS]; long talked_tick = 0; FOR_NB_SCREENS(i) { yn[i].main_message=main_message; yn[i].result_message[YESNO_YES]=yes_message; yn[i].result_message[YESNO_NO]=no_message; yn[i].display=&screens[i]; yn[i].vp = &vp[i]; viewportmanager_theme_enable(i, true, yn[i].vp); screens[i].stop_scroll(); gui_yesno_draw(&(yn[i])); } while (result==-1) { /* Repeat the question every 5secs (more or less) */ if (global_settings.talk_menu && (talked_tick==0 || TIME_AFTER(current_tick, talked_tick+HZ*5))) { talked_tick = current_tick; talk_text_message(main_message, false); } button = get_action(CONTEXT_YESNOSCREEN, HZ*5); switch (button) { case ACTION_YESNO_ACCEPT: result=YESNO_YES; break; case ACTION_NONE: case SYS_CHARGER_DISCONNECTED: /* ignore some SYS events that can happen */ continue; default: if(default_event_handler(button) == SYS_USB_CONNECTED) return(YESNO_USB); result = YESNO_NO; } } FOR_NB_SCREENS(i) result_displayed=gui_yesno_draw_result(&(yn[i]), result); if (global_settings.talk_menu) { talk_text_message((result == YESNO_YES) ? yes_message : no_message, false); talk_force_enqueue_next(); } if(result_displayed) sleep(HZ); FOR_NB_SCREENS(i) { screens[i].scroll_stop(yn[i].vp); viewportmanager_theme_undo(i, true); } return(result); }
bool pcm_rec_screen(void) { char buf[80]; char filename[MAX_PATH]; char *rec_sources[2] = {"Line-in","Mic"}; int line=0; int play_vol; int rec_monitor, rec_gain, rec_vol, rec_source, rec_count, rec_waveform; int rec_time; int done, button; int w, h; lcd_setfont(FONT_SYSFIXED); lcd_getstringsize("M", &w, &h); lcd_setmargins(0, 8); play_vol = 120; //cpu_boost(true); #if defined(HAVE_UDA1380) uda1380_enable_output(true); #elif defined(HAVE_TLV320) tlv320_enable_output(true); #endif #if defined(HAVE_UDA1380) uda1380_set_master_vol(play_vol, play_vol); #elif defined(HAVE_TLV320) tlv320_set_headphone_vol(play_vol, play_vol); #endif rec_monitor = 0; // No record feedback rec_source = 1; // Mic rec_gain = 0; // 0-15 rec_vol = 0; // 0-255 rec_count = 0; rec_waveform = 0; pcm_open_recording(); pcm_set_recording_options(rec_source, rec_waveform); pcm_set_recording_gain(rec_gain, rec_vol); //rec_create_directory(); done = 0; while(!done) { line = 0; snprintf(buf, sizeof(buf), "PlayVolume: %3d", play_vol); lcd_puts(0,line++, buf); snprintf(buf, sizeof(buf), "Gain : %2d Volume : %2d", rec_gain, rec_vol); lcd_puts(0,line++, buf); snprintf(buf, sizeof(buf), "Monitor: %2d Waveform: %2d", rec_monitor, rec_waveform); lcd_puts(0,line++, buf); line++; rec_time = pcm_recorded_time(); snprintf(buf, sizeof(buf), "Status: %s", pcm_status() & AUDIO_STATUS_RECORD ? "RUNNING" : "STOPPED"); lcd_puts(0,line++, buf); snprintf(buf, sizeof(buf), "Source: %s", rec_sources[rec_source]); lcd_puts(0,line++, buf); snprintf(buf, sizeof(buf), "File : %s", filename); lcd_puts(0,line++, buf); snprintf(buf, sizeof(buf), "Time : %02d:%02d.%02d", rec_time/HZ/60, (rec_time/HZ)%60, rec_time%HZ); lcd_puts(0,line++, buf); line++; snprintf(buf, sizeof(buf), "MODE : Select source"); lcd_puts(0,line++, buf); snprintf(buf, sizeof(buf), "UP/DOWN : Record volume"); lcd_puts(0,line++, buf); snprintf(buf, sizeof(buf), "LFT/RGHT: Record gain"); lcd_puts(0,line++, buf); snprintf(buf, sizeof(buf), "RMT MENU: Toggle monitor"); lcd_puts(0,line++, buf); snprintf(buf, sizeof(buf), "RMT PLAY: Toggle waveform"); lcd_puts(0,line++, buf); lcd_update(); button = button_get_w_tmo(HZ/8); switch (button) { case BUTTON_OFF: done = true; break; case BUTTON_REC: if (pcm_status() & AUDIO_STATUS_RECORD) { pcm_stop_recording(); } else { create_numbered_filename(filename, "/", "rec_", ".wav", 4); pcm_record(filename); } break; case BUTTON_ON: break; case BUTTON_MODE: rec_source = 1 - rec_source; pcm_set_recording_options(rec_source, rec_waveform); break; case BUTTON_RIGHT: case BUTTON_RIGHT | BUTTON_REPEAT: if (rec_gain < 15) rec_gain++; pcm_set_recording_gain(rec_gain, rec_vol); break; case BUTTON_LEFT: case BUTTON_LEFT | BUTTON_REPEAT: if (rec_gain > 0) rec_gain--; pcm_set_recording_gain(rec_gain, rec_vol); break; case BUTTON_RC_MENU: rec_monitor = 1 - rec_monitor; #if defined(HAVE_UDA1380) uda1380_set_monitor(rec_monitor); #endif break; case BUTTON_RC_ON: rec_waveform = 1 - rec_waveform; pcm_set_recording_options(rec_source, rec_waveform); break; case BUTTON_UP: case BUTTON_UP | BUTTON_REPEAT: if (rec_vol<255) rec_vol++; pcm_set_recording_gain(rec_gain, rec_vol); break; case BUTTON_DOWN: case BUTTON_DOWN | BUTTON_REPEAT: if (rec_vol) rec_vol--; pcm_set_recording_gain(rec_gain, rec_vol); break; case SYS_USB_CONNECTED: if (pcm_status() & AUDIO_STATUS_RECORD) { // ignore usb while recording } else { pcm_stop_recording(); #if defined(HAVE_UDA1380) uda1380_enable_output(false); #elif defined(HAVE_TLV320) tlv320_enable_output(false); #endif default_event_handler(SYS_USB_CONNECTED); return false; } break; } } pcm_stop_recording(); pcm_close_recording(); #if defined(HAVE_UDA1380) uda1380_enable_output(false); #elif defined(HAVE_TLV320) tlv320_enable_output(false); #endif return true; }
bool search_playlist(void) { char search_str[32] = ""; bool ret = false, exit = false; int i, playlist_count; int found_indicies[MAX_PLAYLIST_ENTRIES]; int found_indicies_count = 0, last_found_count = -1; int button; struct gui_synclist playlist_lists; struct playlist_track_info track; if (!playlist_viewer_init(&viewer, 0, false)) return ret; if (kbd_input(search_str, sizeof(search_str)) < 0) return ret; lcd_clear_display(); playlist_count = playlist_amount_ex(viewer.playlist); cpu_boost(true); for (i = 0; i < playlist_count && found_indicies_count < MAX_PLAYLIST_ENTRIES; i++) { if (found_indicies_count != last_found_count) { splashf(0, str(LANG_PLAYLIST_SEARCH_MSG), found_indicies_count, str(LANG_OFF_ABORT)); last_found_count = found_indicies_count; } if (action_userabort(TIMEOUT_NOBLOCK)) break; playlist_get_track_info(viewer.playlist, i, &track); if (strcasestr(track.filename,search_str)) found_indicies[found_indicies_count++] = track.index; yield(); } cpu_boost(false); if (!found_indicies_count) { return ret; } backlight_on(); gui_synclist_init(&playlist_lists, playlist_search_callback_name, found_indicies, false, 1, NULL); gui_synclist_set_title(&playlist_lists, str(LANG_SEARCH_RESULTS), NOICON); gui_synclist_set_icon_callback(&playlist_lists, NULL); gui_synclist_set_nb_items(&playlist_lists, found_indicies_count); gui_synclist_select_item(&playlist_lists, 0); gui_synclist_draw(&playlist_lists); while (!exit) { if (list_do_action(CONTEXT_LIST, HZ/4, &playlist_lists, &button, LIST_WRAP_UNLESS_HELD)) continue; switch (button) { case ACTION_STD_CANCEL: exit = true; break; case ACTION_STD_OK: { int sel = gui_synclist_get_sel_pos(&playlist_lists); playlist_start(found_indicies[sel], 0); exit = 1; } break; default: if (default_event_handler(button) == SYS_USB_CONNECTED) { ret = true; exit = true; } break; } } return ret; }
/* Main viewer function. Filename identifies playlist to be viewed. If NULL, view current playlist. */ enum playlist_viewer_result playlist_viewer_ex(const char* filename) { enum playlist_viewer_result ret = PLAYLIST_VIEWER_OK; bool exit = false; /* exit viewer */ int button; bool dirty = false; struct gui_synclist playlist_lists; if (!playlist_viewer_init(&viewer, filename, false)) goto exit; push_current_activity(ACTIVITY_PLAYLISTVIEWER); gui_synclist_init(&playlist_lists, playlist_callback_name, &viewer, false, 1, NULL); gui_synclist_set_voice_callback(&playlist_lists, playlist_callback_voice); gui_synclist_set_icon_callback(&playlist_lists, global_settings.playlist_viewer_icons? &playlist_callback_icons:NULL); gui_synclist_set_nb_items(&playlist_lists, viewer.num_tracks); gui_synclist_set_title(&playlist_lists, str(LANG_PLAYLIST), Icon_Playlist); gui_synclist_select_item(&playlist_lists, viewer.selected_track); gui_synclist_draw(&playlist_lists); gui_synclist_speak_item(&playlist_lists); while (!exit) { int track; if (global_status.resume_index != -1 && !viewer.playlist) playlist_get_resume_info(&track); else track = -1; if (track != viewer.current_playing_track || playlist_amount_ex(viewer.playlist) != viewer.num_tracks) { /* Playlist has changed (new track started?) */ if (!update_playlist(false)) goto exit; /*Needed because update_playlist gives wrong value when playing is stopped*/ viewer.current_playing_track = track; gui_synclist_set_nb_items(&playlist_lists, viewer.num_tracks); gui_synclist_draw(&playlist_lists); } /* Timeout so we can determine if play status has changed */ bool res = list_do_action(CONTEXT_TREE, HZ/2, &playlist_lists, &button, LIST_WRAP_UNLESS_HELD); /* during moving, another redraw is going to be needed, * since viewer.selected_track is updated too late (after the first draw) * drawing the moving item needs it */ viewer.selected_track=gui_synclist_get_sel_pos(&playlist_lists); if (res) { bool reload = playlist_buffer_needs_reload(&viewer.buffer, viewer.selected_track); if (reload) playlist_buffer_load_entries_screen(&viewer.buffer, button == ACTION_STD_NEXT ? FORWARD : BACKWARD); if (reload || viewer.moving_track >= 0) gui_synclist_draw(&playlist_lists); } switch (button) { case ACTION_TREE_WPS: case ACTION_STD_CANCEL: { if (viewer.moving_track >= 0) { viewer.selected_track = viewer.moving_track; gui_synclist_select_item(&playlist_lists, viewer.moving_track); viewer.moving_track = -1; viewer.moving_playlist_index = -1; gui_synclist_draw(&playlist_lists); } else { exit = true; ret = PLAYLIST_VIEWER_CANCEL; } break; } case ACTION_STD_OK: { struct playlist_entry * current_track = playlist_buffer_get_track(&viewer.buffer, viewer.selected_track); if (viewer.moving_track >= 0) { /* Move track */ int ret_val; ret_val = playlist_move(viewer.playlist, viewer.moving_playlist_index, current_track->index); if (ret_val < 0) splashf(HZ, (unsigned char *)"%s %s", str(LANG_MOVE), str(LANG_FAILED)); update_playlist(true); viewer.moving_track = -1; viewer.moving_playlist_index = -1; dirty = true; } else if (!viewer.playlist) { /* play new track */ if (!global_settings.party_mode) { playlist_start(current_track->index, 0); update_playlist(false); } } else if (!global_settings.party_mode) { int start_index = current_track->index; if (!warn_on_pl_erase()) { gui_synclist_draw(&playlist_lists); break; } /* New playlist */ if (playlist_set_current(viewer.playlist) < 0) goto exit; if (global_settings.playlist_shuffle) start_index = playlist_shuffle(current_tick, start_index); playlist_start(start_index, 0); /* Our playlist is now the current list */ if (!playlist_viewer_init(&viewer, NULL, true)) goto exit; exit = true; } gui_synclist_draw(&playlist_lists); break; } case ACTION_STD_CONTEXT: { /* ON+PLAY menu */ int ret_val; ret_val = onplay_menu(viewer.selected_track); if (ret_val < 0) { ret = PLAYLIST_VIEWER_USB; goto exit; } else if (ret_val > 0) { /* Playlist changed */ gui_synclist_del_item(&playlist_lists); update_playlist(true); if (viewer.num_tracks <= 0) exit = true; if (viewer.selected_track >= viewer.num_tracks) viewer.selected_track = viewer.num_tracks-1; dirty = true; } gui_synclist_draw(&playlist_lists); break; } case ACTION_STD_MENU: ret = PLAYLIST_VIEWER_MAINMENU; goto exit; default: if(default_event_handler(button) == SYS_USB_CONNECTED) { ret = PLAYLIST_VIEWER_USB; goto exit; } break; } } exit: pop_current_activity(); if (viewer.playlist) { if(dirty && yesno_pop(ID2P(LANG_SAVE_CHANGES))) save_playlist_screen(viewer.playlist); playlist_close(viewer.playlist); } return ret; }
int menu_show(int m) { bool exit = false; int key; #ifdef HAVE_LCD_BITMAP int fw, fh; int menu_lines; int height = LCD_HEIGHT; lcd_setfont(FONT_UI); lcd_getstringsize("A", &fw, &fh); if (global_settings.statusbar) height -= STATUSBAR_HEIGHT; #if CONFIG_KEYPAD == RECORDER_PAD if(global_settings.buttonbar && menus[m].use_buttonbar) { buttonbar_set(menus[m].buttonbar[0], menus[m].buttonbar[1], menus[m].buttonbar[2]); height -= BUTTONBAR_HEIGHT; } #endif menu_lines = height / fh; #else int menu_lines = MENU_LINES; #endif /* Put the cursor on the first line and draw the menu */ put_cursor(m, menus[m].cursor); while (!exit) { key = button_get_w_tmo(HZ/2); /* * "short-circuit" the default keypresses by running the * callback function * The callback may return a new key value, often this will be * BUTTON_NONE or the same key value, but it's perfectly legal * to "simulate" key presses by returning another value. */ if( menus[m].callback != NULL ) key = menus[m].callback(key, m); switch( key ) { case MENU_PREV: case MENU_PREV | BUTTON_REPEAT: #ifdef MENU_RC_PREV case MENU_RC_PREV: case MENU_RC_PREV | BUTTON_REPEAT: #endif if (menus[m].cursor) { /* keep the cursor at 1/3 of the screen */ if (menus[m].top && menus[m].cursor - menus[m].top < menu_lines - (2 * menu_lines) / 3) menus[m].top--; /* move up */ put_cursor(m, menus[m].cursor-1); } else { /* move to bottom */ menus[m].top = menus[m].itemcount-(menu_lines+1); if (menus[m].top < 0) menus[m].top = 0; put_cursor(m, menus[m].itemcount-1); } break; case MENU_NEXT: case MENU_NEXT | BUTTON_REPEAT: #ifdef MENU_RC_NEXT case MENU_RC_NEXT: case MENU_RC_NEXT | BUTTON_REPEAT: #endif if (menus[m].cursor < menus[m].itemcount-1) { /* keep the cursor at 2/3 of the screen */ if (menus[m].itemcount - menus[m].top > menu_lines && menus[m].cursor - menus[m].top >= (2 * menu_lines) / 3) menus[m].top++; /* move down */ put_cursor(m, menus[m].cursor+1); } else { /* move to top */ menus[m].top = 0; menus[m].cursor = 0; put_cursor(m, 0); } break; case MENU_ENTER: #ifdef MENU_ENTER2 case MENU_ENTER2: #endif #ifdef MENU_RC_ENTER case MENU_RC_ENTER: #endif /* Erase current display state */ lcd_clear_display(); return menus[m].cursor; case MENU_EXIT: #ifdef MENU_EXIT2 case MENU_EXIT2: #endif #ifdef MENU_EXIT_MENU case MENU_EXIT_MENU: #endif #ifdef MENU_RC_EXIT case MENU_RC_EXIT: #endif lcd_stop_scroll(); exit = true; break; default: if(default_event_handler(key) == SYS_USB_CONNECTED) return MENU_ATTACHED_USB; break; } status_draw(false); } return MENU_SELECTED_EXIT; }
/* Provides a graphical means of editing the EQ settings */ bool eq_menu_graphical(void) { bool exit_request = false; bool result = true; bool has_changed = false; int button; int *setting; int current_band, x, y, step, fast_step, min, max; enum eq_slider_mode mode; char buf[24]; int w, h, height, start_item, nb_eq_sliders[NB_SCREENS]; FOR_NB_SCREENS(i) viewportmanager_theme_enable(i, false, NULL); FOR_NB_SCREENS(i) { screens[i].set_viewport(NULL); screens[i].setfont(FONT_SYSFIXED); screens[i].clear_display(); /* Figure out how many sliders can be drawn on the screen */ screens[i].getstringsize("A", &w, &h); /* Total height includes margins (1), text, slider, and line selector (1) */ height = 3 + h + 1 + SCROLLBAR_SIZE + 3; nb_eq_sliders[i] = screens[i].lcdheight / height; /* Make sure the "Edit Mode" text fits too */ height = nb_eq_sliders[i]*height + h + 2; if (height > screens[i].lcdheight) nb_eq_sliders[i]--; if (nb_eq_sliders[i] > EQ_NUM_BANDS) nb_eq_sliders[i] = EQ_NUM_BANDS; } y = h + 1; /* Start off editing gain on the first band */ mode = GAIN; current_band = 0; while (!exit_request) { FOR_NB_SCREENS(i) { screens[i].clear_display(); /* Set pointer to the band data currently editable */ if (mode == GAIN) { /* gain */ setting = &global_settings.eq_band_settings[current_band].gain; step = EQ_GAIN_STEP; fast_step = EQ_GAIN_FAST_STEP; min = EQ_GAIN_MIN; max = EQ_GAIN_MAX; snprintf(buf, sizeof(buf), str(LANG_SYSFONT_EQUALIZER_EDIT_MODE), str(LANG_SYSFONT_GAIN), "(dB)"); screens[i].putsxy(0, 0, buf); } else if (mode == CUTOFF) { /* cutoff */ setting = &global_settings.eq_band_settings[current_band].cutoff; step = EQ_CUTOFF_STEP; fast_step = EQ_CUTOFF_FAST_STEP; min = EQ_CUTOFF_MIN; max = EQ_CUTOFF_MAX; snprintf(buf, sizeof(buf), str(LANG_SYSFONT_EQUALIZER_EDIT_MODE), str(LANG_SYSFONT_EQUALIZER_BAND_CUTOFF), "(Hz)"); screens[i].putsxy(0, 0, buf); } else { /* Q */ setting = &global_settings.eq_band_settings[current_band].q; step = EQ_Q_STEP; fast_step = EQ_Q_FAST_STEP; min = EQ_Q_MIN; max = EQ_Q_MAX; snprintf(buf, sizeof(buf), str(LANG_SYSFONT_EQUALIZER_EDIT_MODE), str(LANG_SYSFONT_EQUALIZER_BAND_Q), ""); screens[i].putsxy(0, 0, buf); } /* Draw scrollbar if needed */ if (nb_eq_sliders[i] != EQ_NUM_BANDS) { if (current_band == 0) { start_item = 0; } else if (current_band == 9) { start_item = EQ_NUM_BANDS - nb_eq_sliders[i]; } else { start_item = current_band - 1; } x = SCROLLBAR_SIZE; } else { x = 1; start_item = 0; } /* Draw equalizer band details */ draw_eq_sliders(&screens[i], x, y, nb_eq_sliders[i], start_item, current_band, mode); screens[i].update(); } button = get_action(CONTEXT_SETTINGS_EQ,TIMEOUT_BLOCK); switch (button) { case ACTION_SETTINGS_DEC: case ACTION_SETTINGS_DECREPEAT: *(setting) -= step; has_changed = true; if (*(setting) < min) *(setting) = min; break; case ACTION_SETTINGS_INC: case ACTION_SETTINGS_INCREPEAT: *(setting) += step; has_changed = true; if (*(setting) > max) *(setting) = max; break; case ACTION_SETTINGS_INCBIGSTEP: *(setting) += fast_step; has_changed = true; if (*(setting) > max) *(setting) = max; break; case ACTION_SETTINGS_DECBIGSTEP: *(setting) -= fast_step; has_changed = true; if (*(setting) < min) *(setting) = min; break; case ACTION_STD_PREV: case ACTION_STD_PREVREPEAT: current_band--; if (current_band < 0) current_band = EQ_NUM_BANDS - 1; /* wrap around */ break; case ACTION_STD_NEXT: case ACTION_STD_NEXTREPEAT: current_band = (current_band + 1) % EQ_NUM_BANDS; break; case ACTION_STD_OK: mode++; if (mode > Q) mode = GAIN; /* wrap around */ break; case ACTION_STD_CANCEL: exit_request = true; result = false; break; default: if(default_event_handler(button) == SYS_USB_CONNECTED) { exit_request = true; result = true; } break; } /* Update the filter if the user changed something */ if (has_changed) { dsp_set_eq_coefs(current_band, &global_settings.eq_band_settings[current_band]); has_changed = false; } } /* Reset screen settings */ FOR_NB_SCREENS(i) { screens[i].setfont(FONT_UI); screens[i].clear_display(); screens[i].set_viewport(NULL); viewportmanager_theme_undo(i, false); } return result; }
bool option_screen(const struct settings_list *setting, struct viewport parent[NB_SCREENS], bool use_temp_var, unsigned char* option_title) { int action; bool done = false; struct gui_synclist lists; int oldvalue, nb_items = 0, selected = 0, temp_var; int *variable; bool allow_wrap = setting->flags & F_NO_WRAP ? false : true; int var_type = setting->flags&F_T_MASK; void (*function)(int) = NULL; char *title; if (var_type == F_T_INT || var_type == F_T_UINT) { variable = use_temp_var ? &temp_var: (int*)setting->setting; temp_var = oldvalue = *(int*)setting->setting; } else if (var_type == F_T_BOOL) { /* bools always use the temp variable... if use_temp_var is false it will be copied to setting->setting every change */ variable = &temp_var; temp_var = oldvalue = *(bool*)setting->setting?1:0; } else return false; /* only int/bools can go here */ gui_synclist_init(&lists, value_setting_get_name_cb, (void*)setting, false, 1, parent); if (setting->lang_id == -1) title = (char*)setting->cfg_vals; else title = P2STR(option_title); gui_synclist_set_title(&lists, title, Icon_Questionmark); gui_synclist_set_icon_callback(&lists, NULL); if(global_settings.talk_menu) gui_synclist_set_voice_callback(&lists, option_talk); val_to_selection(setting, oldvalue, &nb_items, &selected, &function); gui_synclist_set_nb_items(&lists, nb_items); gui_synclist_select_item(&lists, selected); gui_synclist_limit_scroll(&lists, true); gui_synclist_draw(&lists); /* talk the item */ gui_synclist_speak_item(&lists); while (!done) { if (list_do_action(CONTEXT_LIST, HZ, /* HZ so the status bar redraws */ &lists, &action, allow_wrap? LIST_WRAP_UNLESS_HELD: LIST_WRAP_OFF)) { /* setting changed */ selected = gui_synclist_get_sel_pos(&lists); *variable = selection_to_val(setting, selected); if (var_type == F_T_BOOL && !use_temp_var) *(bool*)setting->setting = (*variable==1); } else if (action == ACTION_NONE) continue; else if (action == ACTION_STD_CANCEL) { /* setting canceled, restore old value if changed */ if (*variable != oldvalue) { *variable = oldvalue; if (var_type == F_T_BOOL && !use_temp_var) *(bool*)setting->setting = (oldvalue==1); splash(HZ/2, ID2P(LANG_CANCEL)); } done = true; } else if (action == ACTION_STD_CONTEXT) { /* reset setting to default */ reset_setting(setting, variable); if (var_type == F_T_BOOL && !use_temp_var) *(bool*)setting->setting = (*variable==1); val_to_selection(setting, *variable, &nb_items, &selected, &function); gui_synclist_select_item(&lists, selected); gui_synclist_draw(&lists); gui_synclist_speak_item(&lists); } else if (action == ACTION_STD_OK) { /* setting accepted, store now if it used a temp var */ if (use_temp_var) { if (var_type == F_T_INT || var_type == F_T_UINT) *(int*)setting->setting = *variable; else *(bool*)setting->setting = (*variable==1); } settings_save(); done = true; } else if(default_event_handler(action) == SYS_USB_CONNECTED) return true; /* callback */ if ( function ) function(*variable); /* if the volume is changing we need to let the skins know */ if (function == sound_get_fn(SOUND_VOLUME)) global_status.last_volume_change = current_tick; } return false; }
/* ------------------------------------------------------------------------*/ static int select_bookmark(const char* bookmark_file_name, bool show_dont_resume, char** selected_bookmark) { struct bookmark_list* bookmarks; struct gui_synclist list; int item = 0; int action; size_t size; bool exit = false; bool refresh = true; int ret = BOOKMARK_FAIL; bookmarks = plugin_get_buffer(&size); bookmarks->buffer_size = size; bookmarks->show_dont_resume = show_dont_resume; bookmarks->filename = bookmark_file_name; bookmarks->start = 0; bookmarks->show_playlist_name = strcmp(bookmark_file_name, RECENT_BOOKMARK_FILE) == 0; gui_synclist_init(&list, &get_bookmark_info, (void*) bookmarks, false, 2, NULL); if(global_settings.talk_menu) gui_synclist_set_voice_callback(&list, bookmark_list_voice_cb); gui_synclist_set_title(&list, str(LANG_BOOKMARK_SELECT_BOOKMARK), Icon_Bookmark); while (!exit) { if (refresh) { int count = get_bookmark_count(bookmark_file_name); bookmarks->total_count = count; if (bookmarks->total_count < 1) { /* No more bookmarks, delete file and exit */ splash(HZ, ID2P(LANG_BOOKMARK_LOAD_EMPTY)); remove(bookmark_file_name); *selected_bookmark = NULL; return BOOKMARK_FAIL; } if (bookmarks->show_dont_resume) { count++; item++; } gui_synclist_set_nb_items(&list, count * 2); if (item >= count) { /* Selected item has been deleted */ item = count - 1; gui_synclist_select_item(&list, item * 2); } buffer_bookmarks(bookmarks, bookmarks->start); gui_synclist_draw(&list); cond_talk_ids_fq(VOICE_EXT_BMARK); gui_synclist_speak_item(&list); refresh = false; } list_do_action(CONTEXT_BOOKMARKSCREEN, HZ / 2, &list, &action, LIST_WRAP_UNLESS_HELD); item = gui_synclist_get_sel_pos(&list) / 2; if (bookmarks->show_dont_resume) { item--; } if (action == ACTION_STD_CONTEXT) { MENUITEM_STRINGLIST(menu_items, ID2P(LANG_BOOKMARK_CONTEXT_MENU), NULL, ID2P(LANG_BOOKMARK_CONTEXT_RESUME), ID2P(LANG_BOOKMARK_CONTEXT_DELETE)); static const int menu_actions[] = { ACTION_STD_OK, ACTION_BMS_DELETE }; int selection = do_menu(&menu_items, NULL, NULL, false); refresh = true; if (selection >= 0 && selection <= (int) (sizeof(menu_actions) / sizeof(menu_actions[0]))) { action = menu_actions[selection]; } } switch (action) { case ACTION_STD_OK: if (item >= 0) { talk_shutup(); *selected_bookmark = bookmarks->items[item - bookmarks->start]; return BOOKMARK_SUCCESS; } exit = true; ret = BOOKMARK_SUCCESS; break; case ACTION_TREE_WPS: case ACTION_STD_CANCEL: exit = true; break; case ACTION_BMS_DELETE: if (item >= 0) { const char *lines[]={ ID2P(LANG_REALLY_DELETE) }; const char *yes_lines[]={ ID2P(LANG_DELETING) }; const struct text_message message={lines, 1}; const struct text_message yes_message={yes_lines, 1}; if(gui_syncyesno_run(&message, &yes_message, NULL)==YESNO_YES) { delete_bookmark(bookmark_file_name, item); bookmarks->reload = true; } refresh = true; } break; default: if (default_event_handler(action) == SYS_USB_CONNECTED) { ret = BOOKMARK_USB_CONNECTED; exit = true; } break; } } talk_shutup(); *selected_bookmark = NULL; return ret; }
/* main loop, handles key events */ static int dirbrowse(void) { int numentries=0; char buf[MAX_PATH]; int button, oldbutton; bool reload_root = false; int lastfilter = *tc.dirfilter; bool lastsortcase = global_settings.sort_case; bool exit_func = false; char* currdir = tc.currdir; /* just a shortcut */ #ifdef HAVE_TAGCACHE bool id3db = *tc.dirfilter == SHOW_ID3DB; if (id3db) curr_context=CONTEXT_ID3DB; else #endif curr_context=CONTEXT_TREE; if (tc.selected_item < 0) tc.selected_item = 0; #ifdef HAVE_TAGCACHE tc.firstpos = 0; lasttable = -1; lastextra = -1; lastfirstpos = 0; #endif start_wps = false; numentries = update_dir(); reload_dir = false; if (numentries == -1) return GO_TO_PREVIOUS; /* currdir is not a directory */ if (*tc.dirfilter > NUM_FILTER_MODES && numentries==0) { splash(HZ*2, ID2P(LANG_NO_FILES)); return GO_TO_PREVIOUS; /* No files found for rockbox_browse() */ } gui_synclist_draw(&tree_lists); while(1) { bool restore = false; if (tc.dirlevel < 0) tc.dirlevel = 0; /* shouldnt be needed.. this code needs work! */ button = get_action(CONTEXT_TREE, list_do_action_timeout(&tree_lists, HZ/2)); oldbutton = button; gui_synclist_do_button(&tree_lists, &button,LIST_WRAP_UNLESS_HELD); tc.selected_item = gui_synclist_get_sel_pos(&tree_lists); switch ( button ) { case ACTION_STD_OK: /* nothing to do if no files to display */ if ( numentries == 0 ) break; short attr = tree_get_entry_at(&tc, tc.selected_item)->attr; if ((tc.browse->flags & BROWSE_SELECTONLY) && !(attr & ATTR_DIRECTORY)) { tc.browse->flags |= BROWSE_SELECTED; get_current_file(tc.browse->buf, tc.browse->bufsize); return GO_TO_PREVIOUS; } #ifdef HAVE_TAGCACHE switch (id3db?tagtree_enter(&tc):ft_enter(&tc)) #else switch (ft_enter(&tc)) #endif { case GO_TO_FILEBROWSER: reload_dir = true; break; case GO_TO_WPS: return GO_TO_WPS; #if CONFIG_TUNER case GO_TO_FM: return GO_TO_FM; #endif case GO_TO_ROOT: exit_func = true; break; default: break; } restore = true; break; case ACTION_STD_CANCEL: if (*tc.dirfilter > NUM_FILTER_MODES && tc.dirlevel < 1) { exit_func = true; break; } if ((*tc.dirfilter == SHOW_ID3DB && tc.dirlevel == 0) || ((*tc.dirfilter != SHOW_ID3DB && !strcmp(currdir,"/")))) { #ifdef HAVE_LCD_BITMAP /* charcell doesnt have ACTION_TREE_PGLEFT so this isnt needed */ if (oldbutton == ACTION_TREE_PGLEFT) break; else #endif return GO_TO_ROOT; } #ifdef HAVE_TAGCACHE if (id3db) tagtree_exit(&tc); else #endif if (ft_exit(&tc) == 3) exit_func = true; restore = true; break; case ACTION_TREE_STOP: if (list_stop_handler()) restore = true; break; case ACTION_STD_MENU: return GO_TO_ROOT; break; #ifdef HAVE_RECORDING case ACTION_STD_REC: return GO_TO_RECSCREEN; #endif case ACTION_TREE_WPS: return GO_TO_PREVIOUS_MUSIC; break; #ifdef HAVE_QUICKSCREEN case ACTION_STD_QUICKSCREEN: /* don't enter f2 from plugin browser */ if (*tc.dirfilter < NUM_FILTER_MODES) { if (quick_screen_quick(button)) reload_dir = true; restore = true; } break; #endif #ifdef BUTTON_F3 case ACTION_F3: /* don't enter f3 from plugin browser */ if (*tc.dirfilter < NUM_FILTER_MODES) { if (quick_screen_f3(ACTION_F3)) reload_dir = true; restore = true; } break; #endif #ifdef HAVE_HOTKEY case ACTION_TREE_HOTKEY: if (!global_settings.hotkey_tree) break; /* fall through */ #endif case ACTION_STD_CONTEXT: { bool hotkey = button == ACTION_TREE_HOTKEY; int onplay_result; int attr = 0; if (tc.browse->flags & BROWSE_NO_CONTEXT_MENU) break; if(!numentries) onplay_result = onplay(NULL, 0, curr_context, hotkey); else { #ifdef HAVE_TAGCACHE if (id3db) { if (tagtree_get_attr(&tc) == FILE_ATTR_AUDIO) { attr = FILE_ATTR_AUDIO; tagtree_get_filename(&tc, buf, sizeof(buf)); } else attr = ATTR_DIRECTORY; } else #endif { struct entry *entry = tree_get_entry_at(&tc, tc.selected_item); attr = entry->attr; if (currdir[1]) /* Not in / */ snprintf(buf, sizeof buf, "%s/%s", currdir, entry->name); else /* In / */ snprintf(buf, sizeof buf, "/%s", entry->name); } onplay_result = onplay(buf, attr, curr_context, hotkey); } switch (onplay_result) { case ONPLAY_MAINMENU: return GO_TO_ROOT; case ONPLAY_OK: restore = true; break; case ONPLAY_RELOAD_DIR: reload_dir = true; break; case ONPLAY_START_PLAY: return GO_TO_WPS; break; } break; } #ifdef HAVE_HOTSWAP case SYS_FS_CHANGED: #ifdef HAVE_TAGCACHE if (!id3db) #endif reload_dir = true; /* The 'dir no longer valid' situation will be caught later * by checking the showdir() result. */ break; #endif default: if (default_event_handler(button) == SYS_USB_CONNECTED) { if(*tc.dirfilter > NUM_FILTER_MODES) /* leave sub-browsers after usb, doing otherwise might be confusing to the user */ exit_func = true; else reload_dir = true; } break; } if (start_wps) return GO_TO_WPS; if (button && !IS_SYSEVENT(button)) { storage_spin(); } check_rescan: /* do we need to rescan dir? */ if (reload_dir || reload_root || lastfilter != *tc.dirfilter || lastsortcase != global_settings.sort_case) { if (reload_root) { strcpy(currdir, "/"); tc.dirlevel = 0; #ifdef HAVE_TAGCACHE tc.currtable = 0; tc.currextra = 0; lasttable = -1; lastextra = -1; #endif reload_root = false; } if (!reload_dir) { gui_synclist_select_item(&tree_lists, 0); gui_synclist_draw(&tree_lists); tc.selected_item = 0; lastdir[0] = 0; } lastfilter = *tc.dirfilter; lastsortcase = global_settings.sort_case; restore = true; } if (exit_func) return GO_TO_PREVIOUS; if (restore || reload_dir) { /* restore display */ numentries = update_dir(); reload_dir = false; if (currdir[1] && (numentries < 0)) { /* not in root and reload failed */ reload_root = true; /* try root */ goto check_rescan; } } } return true; }
int gui_syncpitchscreen_run(void) { int button, i; int32_t pitch = sound_get_pitch(); int32_t semitone; int32_t new_pitch; int32_t pitch_delta; bool nudged = false; bool exit = false; /* should maybe be passed per parameter later, not needed for now */ struct viewport parent[NB_SCREENS]; struct viewport pitch_viewports[NB_SCREENS][PITCH_ITEM_COUNT]; int max_lines[NB_SCREENS]; #if CONFIG_CODEC == SWCODEC int32_t new_speed = 0, new_stretch; /* the speed variable holds the apparent speed of the playback */ int32_t speed; if (dsp_timestretch_available()) { speed = GET_SPEED(pitch, dsp_get_timestretch()); } else { speed = pitch; } /* Figure out whether to be in timestretch mode */ if (global_settings.pitch_mode_timestretch && !dsp_timestretch_available()) { global_settings.pitch_mode_timestretch = false; settings_save(); } #endif /* set the semitone index based on the current pitch */ semitone = get_semitone_from_pitch(pitch); /* initialize pitchscreen vps */ FOR_NB_SCREENS(i) { viewport_set_defaults(&parent[i], i); max_lines[i] = viewport_get_nb_lines(&parent[i]); pitchscreen_fix_viewports(&parent[i], pitch_viewports[i]); screens[i].set_viewport(&parent[i]); screens[i].clear_viewport(); /* also, draw the icons now, it's only needed once */ pitchscreen_draw_icons(&screens[i], &parent[i]); } #if CONFIG_CODEC == SWCODEC pcmbuf_set_low_latency(true); #endif while (!exit) { FOR_NB_SCREENS(i) pitchscreen_draw(&screens[i], max_lines[i], pitch_viewports[i], pitch, semitone #if CONFIG_CODEC == SWCODEC , speed #endif ); pitch_delta = 0; #if CONFIG_CODEC == SWCODEC new_speed = 0; #endif button = get_action(CONTEXT_PITCHSCREEN, HZ); #ifdef HAVE_TOUCHSCREEN if (button == ACTION_TOUCHSCREEN) { FOR_NB_SCREENS(i) button = pitchscreen_do_touchscreen(pitch_viewports[i]); } #endif switch (button) { case ACTION_PS_INC_SMALL: if(global_settings.pitch_mode_semitone) pitch_delta = SEMITONE_SMALL_DELTA; else pitch_delta = PITCH_SMALL_DELTA; break; case ACTION_PS_INC_BIG: if(global_settings.pitch_mode_semitone) pitch_delta = SEMITONE_BIG_DELTA; else pitch_delta = PITCH_BIG_DELTA; break; case ACTION_PS_DEC_SMALL: if(global_settings.pitch_mode_semitone) pitch_delta = -SEMITONE_SMALL_DELTA; else pitch_delta = -PITCH_SMALL_DELTA; break; case ACTION_PS_DEC_BIG: if(global_settings.pitch_mode_semitone) pitch_delta = -SEMITONE_BIG_DELTA; else pitch_delta = -PITCH_BIG_DELTA; break; case ACTION_PS_NUDGE_RIGHT: #if CONFIG_CODEC == SWCODEC if (!global_settings.pitch_mode_timestretch) { #endif new_pitch = pitch_increase(pitch, PITCH_NUDGE_DELTA, false #if CONFIG_CODEC == SWCODEC , speed #endif ); nudged = (new_pitch != pitch); pitch = new_pitch; semitone = get_semitone_from_pitch(pitch); #if CONFIG_CODEC == SWCODEC speed = pitch; #endif break; #if CONFIG_CODEC == SWCODEC } else { new_speed = speed + SPEED_SMALL_DELTA; at_limit = false; } break; case ACTION_PS_FASTER: if (global_settings.pitch_mode_timestretch) { new_speed = speed + SPEED_BIG_DELTA; /* snap to whole numbers */ if(new_speed % PITCH_SPEED_PRECISION != 0) new_speed -= new_speed % PITCH_SPEED_PRECISION; at_limit = false; } break; #endif case ACTION_PS_NUDGE_RIGHTOFF: if (nudged) { pitch = pitch_increase(pitch, -PITCH_NUDGE_DELTA, false #if CONFIG_CODEC == SWCODEC , speed #endif ); #if CONFIG_CODEC == SWCODEC speed = pitch; #endif semitone = get_semitone_from_pitch(pitch); nudged = false; } break; case ACTION_PS_NUDGE_LEFT: #if CONFIG_CODEC == SWCODEC if (!global_settings.pitch_mode_timestretch) { #endif new_pitch = pitch_increase(pitch, -PITCH_NUDGE_DELTA, false #if CONFIG_CODEC == SWCODEC , speed #endif ); nudged = (new_pitch != pitch); pitch = new_pitch; semitone = get_semitone_from_pitch(pitch); #if CONFIG_CODEC == SWCODEC speed = pitch; #endif break; #if CONFIG_CODEC == SWCODEC } else { new_speed = speed - SPEED_SMALL_DELTA; at_limit = false; } break; case ACTION_PS_SLOWER: if (global_settings.pitch_mode_timestretch) { new_speed = speed - SPEED_BIG_DELTA; /* snap to whole numbers */ if(new_speed % PITCH_SPEED_PRECISION != 0) new_speed += PITCH_SPEED_PRECISION - speed % PITCH_SPEED_PRECISION; at_limit = false; } break; #endif case ACTION_PS_NUDGE_LEFTOFF: if (nudged) { pitch = pitch_increase(pitch, PITCH_NUDGE_DELTA, false #if CONFIG_CODEC == SWCODEC , speed #endif ); #if CONFIG_CODEC == SWCODEC speed = pitch; #endif semitone = get_semitone_from_pitch(pitch); nudged = false; } break; case ACTION_PS_RESET: pitch = PITCH_SPEED_100; sound_set_pitch(pitch); #if CONFIG_CODEC == SWCODEC speed = PITCH_SPEED_100; if (dsp_timestretch_available()) { dsp_set_timestretch(PITCH_SPEED_100); at_limit = false; } #endif semitone = get_semitone_from_pitch(pitch); break; case ACTION_PS_TOGGLE_MODE: global_settings.pitch_mode_semitone = !global_settings.pitch_mode_semitone; #if CONFIG_CODEC == SWCODEC if (dsp_timestretch_available() && !global_settings.pitch_mode_semitone) { global_settings.pitch_mode_timestretch = !global_settings.pitch_mode_timestretch; if(!global_settings.pitch_mode_timestretch) { /* no longer in timestretch mode. Reset speed */ speed = pitch; dsp_set_timestretch(PITCH_SPEED_100); } } settings_save(); #endif break; case ACTION_PS_EXIT: exit = true; break; default: if (default_event_handler(button) == SYS_USB_CONNECTED) return 1; break; } if (pitch_delta) { if (global_settings.pitch_mode_semitone) { semitone = pitch_increase_semitone(pitch, semitone, pitch_delta #if CONFIG_CODEC == SWCODEC , speed #endif ); pitch = get_pitch_from_semitone(semitone); } else { pitch = pitch_increase(pitch, pitch_delta, true #if CONFIG_CODEC == SWCODEC , speed #endif ); semitone = get_semitone_from_pitch(pitch); } #if CONFIG_CODEC == SWCODEC if (global_settings.pitch_mode_timestretch) { /* do this to make sure we properly obey the stretch limits */ new_speed = speed; } else { speed = pitch; } #endif } #if CONFIG_CODEC == SWCODEC if(new_speed) { new_stretch = GET_STRETCH(pitch, new_speed); /* limit the amount of stretch */ if(new_stretch > STRETCH_MAX) { new_stretch = STRETCH_MAX; new_speed = GET_SPEED(pitch, new_stretch); } else if(new_stretch < STRETCH_MIN) { new_stretch = STRETCH_MIN; new_speed = GET_SPEED(pitch, new_stretch); } new_stretch = GET_STRETCH(pitch, new_speed); if(new_stretch >= STRETCH_MAX || new_stretch <= STRETCH_MIN) { at_limit = true; } /* set the amount of stretch */ dsp_set_timestretch(new_stretch); /* update the speed variable with the new speed */ speed = new_speed; /* Reset new_speed so we only call dsp_set_timestretch */ /* when needed */ new_speed = 0; } #endif } #if CONFIG_CODEC == SWCODEC pcmbuf_set_low_latency(false); #endif return 0; }
bool set_sound(const char* string, int* variable, int setting) { bool done = false; bool changed = true; int min, max; int val; int numdec; int integer; int dec; const char* unit; char str[32]; int talkunit = UNIT_INT; int steps; int button; unit = sound_unit(setting); numdec = sound_numdecimals(setting); steps = sound_steps(setting); min = sound_min(setting); max = sound_max(setting); if (*unit == 'd') /* crude reconstruction */ talkunit = UNIT_DB; else if (*unit == '%') talkunit = UNIT_PERCENT; else if (*unit == 'H') talkunit = UNIT_HERTZ; #ifdef HAVE_LCD_BITMAP if(global_settings.statusbar) lcd_setmargins(0, STATUSBAR_HEIGHT); else lcd_setmargins(0, 0); #endif lcd_clear_display(); lcd_puts_scroll(0,0,string); while (!done) { if (changed) { val = sound_val2phys(setting, *variable); if(numdec) { integer = val / (10 * numdec); dec = val % (10 * numdec); snprintf(str,sizeof str, fmt[numdec], integer, dec, unit); } else { snprintf(str,sizeof str,"%d %s ", val, unit); } if (global_settings.talk_menu) talk_value(val, talkunit, false); /* speak it */ } lcd_puts(0,1,str); status_draw(true); lcd_update(); changed = false; button = button_get_w_tmo(HZ/2); switch( button ) { case SETTINGS_INC: case SETTINGS_INC | BUTTON_REPEAT: (*variable)+=steps; if(*variable > max ) *variable = max; changed = true; break; case SETTINGS_DEC: case SETTINGS_DEC | BUTTON_REPEAT: (*variable)-=steps; if(*variable < min ) *variable = min; changed = true; break; case SETTINGS_OK: case SETTINGS_CANCEL: #ifdef SETTINGS_OK2 case SETTINGS_OK2: #endif #ifdef SETTINGS_CANCEL2 case SETTINGS_CANCEL2: #endif done = true; break; default: if(default_event_handler(button) == SYS_USB_CONNECTED) return true; break; } if (changed) sound_set(setting, *variable); } lcd_stop_scroll(); return false; }