summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--apps/SOURCES3
-rw-r--r--apps/action.c10
-rw-r--r--apps/gui/bitmap/list.c3
-rw-r--r--apps/gui/skin_engine/skin_engine.h3
-rw-r--r--apps/gui/skin_engine/skin_touchsupport.c116
-rw-r--r--apps/gui/statusbar-skinned.c34
-rw-r--r--apps/gui/statusbar-skinned.h5
-rw-r--r--apps/gui/viewport.c5
-rw-r--r--apps/gui/wps.c196
-rw-r--r--apps/radio/radio_skin.c26
10 files changed, 252 insertions, 149 deletions
diff --git a/apps/SOURCES b/apps/SOURCES
index 93ec93fe27..58186d2154 100644
--- a/apps/SOURCES
+++ b/apps/SOURCES
@@ -102,6 +102,9 @@ gui/skin_engine/skin_fonts.c
#endif
gui/skin_engine/skin_parser.c
gui/skin_engine/skin_tokens.c
+#ifdef HAVE_TOUCHSCREEN
+gui/skin_engine/skin_touchsupport.c
+#endif
#if (LCD_DEPTH > 1) || (defined(HAVE_REMOTE_LCD) && (LCD_REMOTE_DEPTH > 1))
gui/backdrop.c
diff --git a/apps/action.c b/apps/action.c
index cd76faafec..8f427c8d68 100644
--- a/apps/action.c
+++ b/apps/action.c
@@ -38,6 +38,9 @@
#include "language.h"
#endif
#include "viewport.h"
+#ifdef HAVE_TOUCHSCREEN
+#include "statusbar-skinned.h"
+#endif
static int last_button = BUTTON_NONE|BUTTON_REL; /* allow the ipod wheel to
work on startup */
@@ -320,7 +323,12 @@ static int get_action_worker(int context, int timeout,
int get_action(int context, int timeout)
{
- return get_action_worker(context,timeout,NULL);
+ int button = get_action_worker(context,timeout,NULL);
+#ifdef HAVE_TOUCHSCREEN
+ if (button == ACTION_TOUCHSCREEN)
+ button = sb_touch_to_button(context);
+#endif
+ return button;
}
int get_custom_action(int context,int timeout,
diff --git a/apps/gui/bitmap/list.c b/apps/gui/bitmap/list.c
index ae7b19821e..fa015bf71a 100644
--- a/apps/gui/bitmap/list.c
+++ b/apps/gui/bitmap/list.c
@@ -359,7 +359,8 @@ unsigned gui_synclist_do_touchscreen(struct gui_synclist * gui_list)
if (button == BUTTON_NONE)
return ACTION_NONE;
- if (x > list_text_vp->x + list_width)
+ /* make sure it is inside the UI viewport */
+ if (!viewport_point_within_vp(list_text_vp, x, y))
/* wider than the list's viewport, ignore it */
return ACTION_NONE;
diff --git a/apps/gui/skin_engine/skin_engine.h b/apps/gui/skin_engine/skin_engine.h
index 380b854d24..69991ab587 100644
--- a/apps/gui/skin_engine/skin_engine.h
+++ b/apps/gui/skin_engine/skin_engine.h
@@ -40,7 +40,8 @@ enum skinnable_screens {
#ifdef HAVE_TOUCHSCREEN
-int wps_get_touchaction(struct wps_data *data);
+int skin_get_touchaction(struct wps_data *data, int* edge_offset);
+void skin_disarm_touchregions(struct wps_data *data);
#endif
/* Do a update_type update of the skinned screen */
diff --git a/apps/gui/skin_engine/skin_touchsupport.c b/apps/gui/skin_engine/skin_touchsupport.c
new file mode 100644
index 0000000000..9c0cda779a
--- /dev/null
+++ b/apps/gui/skin_engine/skin_touchsupport.c
@@ -0,0 +1,116 @@
+/***************************************************************************
+ * __________ __ ___.
+ * 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"
+
+/** Disarms all touchregions. */
+void skin_disarm_touchregions(struct wps_data *data)
+{
+ struct skin_token_list *regions = data->touchregions;
+ while (regions)
+ {
+ ((struct touchregion *)regions->token->value.data)->armed = false;
+ regions = 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 wps_data *data, int* edge_offset)
+{
+ int returncode = ACTION_NONE;
+ short x,y;
+ short vx, vy;
+ int type = action_get_touchscreen_press(&x, &y);
+ static int last_action = ACTION_NONE;
+ struct touchregion *r;
+ bool repeated = (type == BUTTON_REPEAT);
+ bool released = (type == BUTTON_REL);
+ bool pressed = (type == BUTTON_TOUCHSCREEN);
+ struct skin_token_list *regions = data->touchregions;
+
+ while (regions)
+ {
+ r = (struct touchregion *)regions->token->value.data;
+ /* make sure this region's viewport is visible */
+ if (r->wvp->hidden_flags&VP_DRAW_HIDDEN)
+ {
+ regions = regions->next;
+ continue;
+ }
+ /* check if it's inside this viewport */
+ if (viewport_point_within_vp(&(r->wvp->vp), x, y))
+ { /* reposition the touch inside the viewport since touchregions
+ * are relative to a preceding viewport */
+ vx = x - r->wvp->vp.x;
+ vy = y - r->wvp->vp.y;
+ /* 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->type)
+ {
+ case WPS_TOUCHREGION_ACTION:
+ if (r->armed && ((repeated && r->repeat) || (released && !r->repeat)))
+ {
+ last_action = r->action;
+ returncode = r->action;
+ }
+ if (pressed)
+ r->armed = true;
+ break;
+ default:
+ if (edge_offset)
+ {
+ if(r->width > r->height)
+ *edge_offset = vx*100/r->width;
+ else
+ *edge_offset = vy*100/r->height;
+ }
+ returncode = r->type;
+ break;
+ }
+ }
+ }
+ regions = regions->next;
+ }
+
+ /* On release, all regions are disarmed. */
+ if (released)
+ skin_disarm_touchregions(data);
+
+ if (returncode != ACTION_NONE)
+ return returncode;
+
+ last_action = ACTION_TOUCHSCREEN;
+ return ACTION_TOUCHSCREEN;
+}
diff --git a/apps/gui/statusbar-skinned.c b/apps/gui/statusbar-skinned.c
index fcd4cfbd9e..168b17fa38 100644
--- a/apps/gui/statusbar-skinned.c
+++ b/apps/gui/statusbar-skinned.c
@@ -21,6 +21,7 @@
#include "config.h"
+#include "action.h"
#include "system.h"
#include "settings.h"
#include "appevents.h"
@@ -253,3 +254,36 @@ void sb_skin_init(void)
sb_skin[i].sync_data = &sb_skin_sync_data;
}
}
+
+#ifdef HAVE_TOUCHSCREEN
+static bool bypass_sb_touchregions = true;
+void sb_bypass_touchregions(bool enable)
+{
+ bypass_sb_touchregions = enable;
+}
+
+int sb_touch_to_button(int context)
+{
+ static int last_context = -1;
+ int button, offset;
+ if (bypass_sb_touchregions)
+ return ACTION_TOUCHSCREEN;
+
+ if (last_context != context)
+ skin_disarm_touchregions(&sb_skin_data[SCREEN_MAIN]);
+ last_context = context;
+ button = skin_get_touchaction(&sb_skin_data[SCREEN_MAIN], &offset);
+
+ switch (button)
+ {
+#ifdef HAVE_VOLUME_IN_LIST
+ case ACTION_WPS_VOLUP:
+ return ACTION_LIST_VOLUP;
+ case ACTION_WPS_VOLDOWN:
+ return ACTION_LIST_VOLDOWN;
+#endif
+ /* TODO */
+ }
+ return button;
+}
+#endif
diff --git a/apps/gui/statusbar-skinned.h b/apps/gui/statusbar-skinned.h
index eb27b06196..7925aa8093 100644
--- a/apps/gui/statusbar-skinned.h
+++ b/apps/gui/statusbar-skinned.h
@@ -43,6 +43,11 @@ void sb_skin_update(enum screen_type screen, bool force);
void sb_skin_set_update_delay(int delay);
bool sb_set_title_text(char* title, enum themable_icons icon, enum screen_type screen);
+#ifdef HAVE_TOUCHSCREEN
+void sb_bypass_touchregions(bool enable);
+int sb_touch_to_button(int context);
+#endif
+
#if (LCD_DEPTH > 1) || (defined(HAVE_REMOTE_LCD) && LCD_REMOTE_DEPTH > 1)
char* sb_get_backdrop(enum screen_type screen);
bool sb_set_backdrop(enum screen_type screen, char* filename);
diff --git a/apps/gui/viewport.c b/apps/gui/viewport.c
index 7b4419f107..9e07c0fe08 100644
--- a/apps/gui/viewport.c
+++ b/apps/gui/viewport.c
@@ -169,6 +169,7 @@ static void toggle_theme(enum screen_type screen, bool force)
screens[screen].set_viewport(NULL);
}
intptr_t force = first_boot?0:1;
+
send_event(GUI_EVENT_ACTIONUPDATE, (void*)force);
}
else
@@ -182,7 +183,9 @@ static void toggle_theme(enum screen_type screen, bool force)
send_event(GUI_EVENT_THEME_CHANGED, NULL);
FOR_NB_SCREENS(i)
was_enabled[i] = is_theme_enabled(i);
-
+#ifdef HAVE_TOUCHSCREEN
+ sb_bypass_touchregions(!is_theme_enabled(SCREEN_MAIN));
+#endif
after_boot[screen] = true;
}
diff --git a/apps/gui/wps.c b/apps/gui/wps.c
index 0a8ce899c5..dafc1cd278 100644
--- a/apps/gui/wps.c
+++ b/apps/gui/wps.c
@@ -85,10 +85,6 @@ static void wps_state_init(void);
static void track_changed_callback(void *param);
static void nextid3available_callback(void* param);
-#ifdef HAVE_TOUCHSCREEN
-static void wps_disarm_touchregions(struct wps_data *data);
-#endif
-
#define WPS_DEFAULTCFG WPS_DIR "/rockbox_default.wps"
#ifdef HAVE_REMOTE_LCD
#define RWPS_DEFAULTCFG WPS_DIR "/rockbox_default.rwps"
@@ -227,6 +223,55 @@ static bool update_onvol_change(struct gui_wps * gwps)
}
+#ifdef HAVE_TOUCHSCREEN
+int skintouch_to_wps(struct wps_data *data)
+{
+ int offset = 0;
+ int button = skin_get_touchaction(data, &offset);
+ switch (button)
+ {
+ case ACTION_STD_PREV:
+ return ACTION_WPS_SKIPPREV;
+ case ACTION_STD_PREVREPEAT:
+ return ACTION_WPS_SEEKBACK;
+ case ACTION_STD_NEXT:
+ return ACTION_WPS_SKIPNEXT;
+ case ACTION_STD_NEXTREPEAT:
+ return ACTION_WPS_SEEKFWD;
+ case ACTION_STD_MENU:
+ return ACTION_WPS_MENU;
+ case ACTION_STD_CONTEXT:
+ return ACTION_WPS_CONTEXT;
+ case ACTION_STD_QUICKSCREEN:
+ return ACTION_WPS_QUICKSCREEN;
+ case WPS_TOUCHREGION_SCROLLBAR:
+ wps_state.id3->elapsed = wps_state.id3->length*offset/100;
+ if (!wps_state.paused)
+#if (CONFIG_CODEC == SWCODEC)
+ audio_pre_ff_rewind();
+#else
+ audio_pause();
+#endif
+ audio_ff_rewind(wps_state.id3->elapsed);
+#if (CONFIG_CODEC != SWCODEC)
+ if (!wps_state.paused)
+ audio_resume();
+#endif
+ return ACTION_TOUCHSCREEN;
+ case WPS_TOUCHREGION_VOLUME:
+ {
+ const int min_vol = sound_min(SOUND_VOLUME);
+ const int max_vol = sound_max(SOUND_VOLUME);
+ global_settings.volume = (offset * (max_vol - min_vol)) / 100;
+ global_settings.volume += min_vol;
+ setvol();
+ }
+ return ACTION_TOUCHSCREEN;
+ }
+ return button;
+}
+#endif
+
bool ffwd_rew(int button)
{
unsigned int step = 0; /* current ff/rewind step */
@@ -359,7 +404,7 @@ bool ffwd_rew(int button)
button = get_action(CONTEXT_WPS|ALLOW_SOFTLOCK,TIMEOUT_BLOCK);
#ifdef HAVE_TOUCHSCREEN
if (button == ACTION_TOUCHSCREEN)
- button = wps_get_touchaction(gui_wps[SCREEN_MAIN].data);
+ button = skintouch_to_wps(gui_wps[SCREEN_MAIN].data);
if (button != ACTION_WPS_SEEKFWD &&
button != ACTION_WPS_SEEKBACK)
button = ACTION_WPS_STOPSEEK;
@@ -616,150 +661,13 @@ static void gwps_enter_wps(void)
skin_update(gwps, WPS_REFRESH_ALL);
#ifdef HAVE_TOUCHSCREEN
- wps_disarm_touchregions(gui_wps[i].data);
+ skin_disarm_touchregions(gui_wps[i].data);
#endif
}
/* force statusbar/skin update since we just cleared the whole screen */
send_event(GUI_EVENT_ACTIONUPDATE, (void*)1);
}
-#ifdef HAVE_TOUCHSCREEN
-/** Disarms all touchregions. */
-static void wps_disarm_touchregions(struct wps_data *data)
-{
- struct skin_token_list *regions = data->touchregions;
- while (regions)
- {
- ((struct touchregion *)regions->token->value.data)->armed = false;
- regions = regions->next;
- }
-}
-
-int wps_get_touchaction(struct wps_data *data)
-{
- int returncode = ACTION_NONE;
- short x,y;
- short vx, vy;
- int type = action_get_touchscreen_press(&x, &y);
- static int last_action = ACTION_NONE;
- struct touchregion *r;
- bool repeated = (type == BUTTON_REPEAT);
- bool released = (type == BUTTON_REL);
- bool pressed = (type == BUTTON_TOUCHSCREEN);
- struct skin_token_list *regions = data->touchregions;
-
- while (regions)
- {
- r = (struct touchregion *)regions->token->value.data;
- /* make sure this region's viewport is visible */
- if (r->wvp->hidden_flags&VP_DRAW_HIDDEN)
- {
- regions = regions->next;
- continue;
- }
- /* check if it's inside this viewport */
- if (viewport_point_within_vp(&(r->wvp->vp), x, y))
- { /* reposition the touch inside the viewport since touchregions
- * are relative to a preceding viewport */
- vx = x - r->wvp->vp.x;
- vy = y - r->wvp->vp.y;
- /* 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->type)
- {
- case WPS_TOUCHREGION_ACTION:
- if (r->armed && ((repeated && r->repeat) || (released && !r->repeat)))
- {
- last_action = r->action;
- returncode = r->action;
- }
- if (pressed)
- r->armed = true;
- break;
- case WPS_TOUCHREGION_SCROLLBAR:
- if(r->width > r->height)
- /* landscape */
- wps_state.id3->elapsed = (vx *
- wps_state.id3->length) / r->width;
- else
- /* portrait */
- wps_state.id3->elapsed = (vy *
- wps_state.id3->length) / r->height;
-
- if (!wps_state.paused)
-#if (CONFIG_CODEC == SWCODEC)
- audio_pre_ff_rewind();
-#else
- audio_pause();
-#endif
- audio_ff_rewind(wps_state.id3->elapsed);
-#if (CONFIG_CODEC != SWCODEC)
- if (!wps_state.paused)
- audio_resume();
-#endif
- break;
- case WPS_TOUCHREGION_VOLUME:
- {
- const int min_vol = sound_min(SOUND_VOLUME);
- const int max_vol = sound_max(SOUND_VOLUME);
- if(r->width > r->height)
- /* landscape */
- global_settings.volume = (vx *
- (max_vol - min_vol)) / r->width;
- else
- /* portrait */
- global_settings.volume = ((r->height - vy) *
- (max_vol-min_vol)) / r->height;
-
- global_settings.volume += min_vol;
- setvol();
- returncode = ACTION_REDRAW;
- }
- }
- }
- }
- regions = regions->next;
- }
-
- /* On release, all regions are disarmed. */
- if (released)
- wps_disarm_touchregions(data);
-
- /* Now we need to convert buttons to the WPS context */
- switch (returncode)
- {
- case ACTION_STD_PREV:
- return ACTION_WPS_SKIPPREV;
- case ACTION_STD_PREVREPEAT:
- return ACTION_WPS_SEEKBACK;
- case ACTION_STD_NEXT:
- return ACTION_WPS_SKIPNEXT;
- case ACTION_STD_NEXTREPEAT:
- return ACTION_WPS_SEEKFWD;
- case ACTION_STD_MENU:
- return ACTION_WPS_MENU;
- case ACTION_STD_CONTEXT:
- return ACTION_WPS_CONTEXT;
- case ACTION_STD_QUICKSCREEN:
- return ACTION_WPS_QUICKSCREEN;
- }
-
- if (returncode != ACTION_NONE)
- return returncode;
-
-
- if ((last_action == ACTION_WPS_SEEKBACK || last_action == ACTION_WPS_SEEKFWD))
- return ACTION_WPS_STOPSEEK;
- last_action = ACTION_TOUCHSCREEN;
- return ACTION_TOUCHSCREEN;
-}
-#endif
/* The WPS can be left in two ways:
* a) call a function, which draws over the wps. In this case, the wps
* will be still active (i.e. the below function didn't return)
@@ -818,7 +726,7 @@ long gui_wps_show(void)
exit = true;
#ifdef HAVE_TOUCHSCREEN
if (button == ACTION_TOUCHSCREEN)
- button = wps_get_touchaction(gui_wps[SCREEN_MAIN].data);
+ button = skintouch_to_wps(gui_wps[SCREEN_MAIN].data);
#endif
/* The iPods/X5/M5 use a single button for the A-B mode markers,
defined as ACTION_WPSAB_SINGLE in their config files. */
diff --git a/apps/radio/radio_skin.c b/apps/radio/radio_skin.c
index 838d1f96da..c7994b3135 100644
--- a/apps/radio/radio_skin.c
+++ b/apps/radio/radio_skin.c
@@ -108,8 +108,32 @@ void fms_skin_init(void)
int fms_do_button_loop(bool update_screen)
{
- return skin_wait_for_action(fms_skin, CONTEXT_FM,
+ int button = skin_wait_for_action(fms_skin, CONTEXT_FM,
update_screen ? TIMEOUT_NOBLOCK : HZ);
+#ifdef HAVE_TOUCHSCREEN
+ int offset;
+ if (button == ACTION_TOUCHSCREEN)
+ button = skin_get_touchaction(&fms_skin_data[SCREEN_MAIN], &offset);
+ switch (button)
+ {
+ case ACTION_WPS_STOP:
+ return ACTION_FM_STOP;
+ case ACTION_STD_CANCEL:
+ return ACTION_FM_EXIT;
+ case ACTION_WPS_VOLUP:
+ return ACTION_SETTINGS_INC;
+ case ACTION_WPS_VOLDOWN:
+ return ACTION_SETTINGS_DEC;
+ case ACTION_WPS_PLAY:
+ return ACTION_FM_PLAY;
+ case ACTION_STD_MENU:
+ return ACTION_FM_MENU;
+ case WPS_TOUCHREGION_SCROLLBAR:
+ /* TODO */
+ break;
+ }
+#endif
+ return button;
}
struct gui_wps *fms_get(enum screen_type screen)