1
0
Fork 0
forked from len0rd/rockbox
foxbox/apps/gui/skin_engine/skin_touchsupport.c
William Wilgus 7100090f99 Remove NVRAM infavor of a separate cfg file
remove nvram and use the existing settings framework for it

add a crc check to the user_settings data to see if we need to save
the user setting file or if we can just save the status file (resume.cfg)

move volume to the system_status struct so we don't write the whole settings file
over volume changes

allow user to still export volume with save sound settings

allow the user to also export pitch and speed

name the file .resume.cfg

Rename all the SYSTEM_STATUS save file variables to TLAs to save space and
discourage tinkering

Cleanup DEBUG_AVAIL_SETTINGS output

when saving user_settings it calls status_save as well this cause the resume
file to be written twice. instead remove the callback for status_save
when setting_save is called

remove header text when saving .resume.cfg

convert status_save() to status_save(bool force)
add SYSTEM_STATUS_UPDATE_TICKS

for ATA device set this to 5 minutes
since we arlready wait for the disk to be up before saving
we don't want to miss our window

for all other every 15 minutes

that way if the battery is too low by the time shutdown comes around you
don't lose much progress

Change-Id: I27214ffd6e5d5494ee5ca83b14f04a41ba426ad7
2025-01-21 00:04:32 -05:00

327 lines
12 KiB
C

/***************************************************************************
* __________ __ ___.
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
* $Id$
*
* Copyright (C) 2009 - Jonathan Gordon
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
****************************************************************************/
#include "config.h"
#include <stdio.h>
#include "action.h"
#include "skin_engine.h"
#include "wps_internals.h"
#include "misc.h"
#include "option_select.h"
#include "sound.h"
#include "settings_list.h"
#include "wps.h"
#include "lang.h"
#include "splash.h"
#include "playlist.h"
#include "dsp_misc.h"
/** Disarms all touchregions. */
void skin_disarm_touchregions(struct gui_wps *gwps)
{
struct wps_data *data = gwps->data;
char* skin_buffer = get_skin_buffer(data);
struct skin_token_list *regions = SKINOFFSETTOPTR(skin_buffer, data->touchregions);
while (regions)
{
struct wps_token *token = SKINOFFSETTOPTR(skin_buffer, regions->token);
struct touchregion *region = SKINOFFSETTOPTR(skin_buffer, token->value.data);
region->armed = false;
regions = SKINOFFSETTOPTR(skin_buffer, regions->next);
}
}
/* Get the touched action.
* egde_offset is a percentage value for the position of the touch
* inside the bar for regions which arnt WPS_TOUCHREGION_ACTION type.
*/
int skin_get_touchaction(struct gui_wps *gwps, int* edge_offset)
{
struct wps_data *data = gwps->data;
int returncode = ACTION_NONE;
short x,y;
short vx, vy;
int type = action_get_touchscreen_press(&x, &y);
struct skin_viewport *wvp;
struct touchregion *r, *temp = NULL;
char* skin_buffer = get_skin_buffer(data);
bool repeated = (type == BUTTON_REPEAT);
bool released = (type == BUTTON_REL);
bool pressed = (type == BUTTON_TOUCHSCREEN);
struct skin_token_list *regions = SKINOFFSETTOPTR(skin_buffer, data->touchregions);
bool needs_repeat;
while (regions)
{
struct wps_token *token = SKINOFFSETTOPTR(skin_buffer, regions->token);
r = SKINOFFSETTOPTR(skin_buffer, token->value.data);
wvp = SKINOFFSETTOPTR(skin_buffer, r->wvp);
/* make sure this region's viewport is visible */
if (wvp->hidden_flags&VP_DRAW_HIDDEN)
{
regions = SKINOFFSETTOPTR(skin_buffer, regions->next);
continue;
}
if (data->touchscreen_locked &&
(r->action != ACTION_TOUCH_SOFTLOCK && !r->allow_while_locked))
{
regions = SKINOFFSETTOPTR(skin_buffer, regions->next);
continue;
}
needs_repeat = r->press_length != PRESS;
/* check if it's inside this viewport */
if (viewport_point_within_vp(&(wvp->vp), x, y))
{ /* reposition the touch inside the viewport since touchregions
* are relative to a preceding viewport */
vx = x - wvp->vp.x;
vy = y - wvp->vp.y;
/* project touches in the padding region so they clamp to the
* edge of the region instead */
if(r->x - r->wpad <= vx && vx < r->x)
vx = r->x;
else if(r->x + r->width <= vx && vx < r->x + r->width + r->wpad)
vx = r->x + r->width - 1;
if(r->y - r->hpad <= vy && vy < r->y)
vy = r->y;
else if(r->y + r->height <= vy && vy < r->y + r->height + r->hpad)
vy = r->y + r->height - 1;
/* now see if the point is inside this region */
if (vx >= r->x && vx < r->x+r->width &&
vy >= r->y && vy < r->y+r->height)
{
/* reposition the touch within the area */
vx -= r->x;
vy -= r->y;
switch(r->action)
{
case ACTION_TOUCH_SCROLLBAR:
case ACTION_TOUCH_VOLUME:
case ACTION_TOUCH_SETTING:
if (edge_offset)
{
struct progressbar *bar =
SKINOFFSETTOPTR(skin_buffer, r->bar);
if(r->width > r->height) {
if(r->width > 1)
*edge_offset = vx*1000/(r->width - 1);
else
*edge_offset = 0;
} else {
/* vertical bars are bottom-up by default */
if(r->height > 1)
*edge_offset = 1000 - vy*1000/(r->height - 1);
else
*edge_offset = 0;
}
if (r->reverse_bar || (bar && bar->invert_fill_direction))
*edge_offset = 1000 - *edge_offset;
}
temp = r;
returncode = r->action;
r->last_press = current_tick;
break;
default:
if (r->armed && ((repeated && needs_repeat) ||
(released && !needs_repeat)))
{
returncode = r->action;
temp = r;
}
if (pressed)
{
r->armed = true;
r->last_press = current_tick;
}
break;
}
}
}
regions = SKINOFFSETTOPTR(skin_buffer, regions->next);
}
/* On release, all regions are disarmed. */
if (released)
skin_disarm_touchregions(gwps);
if (temp && temp->press_length == LONG_PRESS)
temp->armed = false;
if (returncode != ACTION_NONE)
{
if (global_settings.party_mode)
{
switch (returncode)
{
case ACTION_WPS_PLAY:
case ACTION_WPS_SKIPPREV:
case ACTION_WPS_SKIPNEXT:
case ACTION_WPS_STOP:
returncode = ACTION_NONE;
break;
default:
break;
}
}
switch (returncode)
{
case ACTION_TOUCH_SOFTLOCK:
data->touchscreen_locked = !data->touchscreen_locked;
returncode = ACTION_NONE;
break;
case ACTION_WPS_PLAY:
if (!audio_status())
{
if ( global_status.resume_index != -1 )
{
if (playlist_resume() != -1)
{
playlist_start(global_status.resume_index,
global_status.resume_elapsed,
global_status.resume_offset);
}
}
else
{
splash(HZ*2, ID2P(LANG_NOTHING_TO_RESUME));
}
}
else
{
wps_do_playpause(false);
}
returncode = ACTION_REDRAW;
break;
case ACTION_WPS_SKIPPREV:
audio_prev();
returncode = ACTION_REDRAW;
break;
case ACTION_WPS_SKIPNEXT:
audio_next();
returncode = ACTION_REDRAW;
break;
case ACTION_WPS_STOP:
audio_stop();
returncode = ACTION_REDRAW;
break;
case ACTION_SETTINGS_INC:
case ACTION_SETTINGS_DEC:
{
const struct settings_list *setting =
temp->setting_data.setting;
option_select_next_val(setting,
returncode == ACTION_SETTINGS_DEC,
true);
returncode = ACTION_REDRAW;
}
break;
case ACTION_SETTINGS_SET:
{
struct touchsetting *data = &temp->setting_data;
const struct settings_list *s = data->setting;
void (*f)(int) = NULL;
switch (s->flags&F_T_MASK)
{
case F_T_CUSTOM:
s->custom_setting
->load_from_cfg(s->setting, SKINOFFSETTOPTR(skin_buffer, data->value.text));
break;
case F_T_INT:
case F_T_UINT:
*(int*)s->setting = data->value.number;
if ((s->flags & F_T_SOUND) == F_T_SOUND)
sound_set(s->sound_setting->setting, data->value.number);
else if (s->flags&F_CHOICE_SETTING)
f = s->choice_setting->option_callback;
else if (s->flags&F_TABLE_SETTING)
f = s->table_setting->option_callback;
else
f = s->int_setting->option_callback;
if (f)
f(data->value.number);
break;
case F_T_BOOL:
*(bool*)s->setting = data->value.number ? true : false;
if (s->bool_setting->option_callback)
s->bool_setting
->option_callback(data->value.number ? true : false);
break;
}
returncode = ACTION_REDRAW;
}
break;
case ACTION_TOUCH_MUTE:
{
const int min_vol = sound_min(SOUND_VOLUME);
if (global_status.volume == min_vol)
global_status.volume = temp->value;
else
{
temp->value = global_status.volume;
global_status.volume = min_vol;
}
setvol();
returncode = ACTION_REDRAW;
}
break;
case ACTION_TOUCH_SHUFFLE: /* toggle shuffle mode */
{
global_settings.playlist_shuffle =
!global_settings.playlist_shuffle;
replaygain_update();
if (global_settings.playlist_shuffle)
playlist_randomise(NULL, current_tick, true);
else
playlist_sort(NULL, true);
returncode = ACTION_REDRAW;
}
break;
case ACTION_TOUCH_REPMODE: /* cycle the repeat mode setting */
{
const struct settings_list *rep_setting =
find_setting(&global_settings.repeat_mode);
option_select_next_val(rep_setting, false, true);
audio_flush_and_reload_tracks();
returncode = ACTION_REDRAW;
}
break;
case ACTION_TOUCH_SETTING:
{
struct progressbar *bar =
SKINOFFSETTOPTR(skin_buffer, temp->bar);
if (bar && edge_offset)
{
int val, count;
get_setting_info_for_bar(bar->setting, bar->setting_offset, &count, &val);
val = *edge_offset * count / 1000;
update_setting_value_from_touch(bar->setting, bar->setting_offset, val);
}
}
break;
}
return returncode;
}
return ACTION_TOUCHSCREEN;
}