summaryrefslogtreecommitdiff
path: root/apps/gui
diff options
context:
space:
mode:
Diffstat (limited to 'apps/gui')
-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
7 files changed, 215 insertions, 147 deletions
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)
359 if (button == BUTTON_NONE) 359 if (button == BUTTON_NONE)
360 return ACTION_NONE; 360 return ACTION_NONE;
361 361
362 if (x > list_text_vp->x + list_width) 362 /* make sure it is inside the UI viewport */
363 if (!viewport_point_within_vp(list_text_vp, x, y))
363 /* wider than the list's viewport, ignore it */ 364 /* wider than the list's viewport, ignore it */
364 return ACTION_NONE; 365 return ACTION_NONE;
365 366
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 {
40 40
41 41
42#ifdef HAVE_TOUCHSCREEN 42#ifdef HAVE_TOUCHSCREEN
43int wps_get_touchaction(struct wps_data *data); 43int skin_get_touchaction(struct wps_data *data, int* edge_offset);
44void skin_disarm_touchregions(struct wps_data *data);
44#endif 45#endif
45 46
46/* Do a update_type update of the skinned screen */ 47/* 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 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2009 - Jonathan Gordon
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21
22#include "config.h"
23#include <stdio.h>
24#include "action.h"
25#include "skin_engine.h"
26#include "wps_internals.h"
27
28/** Disarms all touchregions. */
29void skin_disarm_touchregions(struct wps_data *data)
30{
31 struct skin_token_list *regions = data->touchregions;
32 while (regions)
33 {
34 ((struct touchregion *)regions->token->value.data)->armed = false;
35 regions = regions->next;
36 }
37}
38
39/* Get the touched action.
40 * egde_offset is a percentage value for the position of the touch
41 * inside the bar for regions which arnt WPS_TOUCHREGION_ACTION type.
42 */
43int skin_get_touchaction(struct wps_data *data, int* edge_offset)
44{
45 int returncode = ACTION_NONE;
46 short x,y;
47 short vx, vy;
48 int type = action_get_touchscreen_press(&x, &y);
49 static int last_action = ACTION_NONE;
50 struct touchregion *r;
51 bool repeated = (type == BUTTON_REPEAT);
52 bool released = (type == BUTTON_REL);
53 bool pressed = (type == BUTTON_TOUCHSCREEN);
54 struct skin_token_list *regions = data->touchregions;
55
56 while (regions)
57 {
58 r = (struct touchregion *)regions->token->value.data;
59 /* make sure this region's viewport is visible */
60 if (r->wvp->hidden_flags&VP_DRAW_HIDDEN)
61 {
62 regions = regions->next;
63 continue;
64 }
65 /* check if it's inside this viewport */
66 if (viewport_point_within_vp(&(r->wvp->vp), x, y))
67 { /* reposition the touch inside the viewport since touchregions
68 * are relative to a preceding viewport */
69 vx = x - r->wvp->vp.x;
70 vy = y - r->wvp->vp.y;
71 /* now see if the point is inside this region */
72 if (vx >= r->x && vx < r->x+r->width &&
73 vy >= r->y && vy < r->y+r->height)
74 {
75 /* reposition the touch within the area */
76 vx -= r->x;
77 vy -= r->y;
78
79
80 switch(r->type)
81 {
82 case WPS_TOUCHREGION_ACTION:
83 if (r->armed && ((repeated && r->repeat) || (released && !r->repeat)))
84 {
85 last_action = r->action;
86 returncode = r->action;
87 }
88 if (pressed)
89 r->armed = true;
90 break;
91 default:
92 if (edge_offset)
93 {
94 if(r->width > r->height)
95 *edge_offset = vx*100/r->width;
96 else
97 *edge_offset = vy*100/r->height;
98 }
99 returncode = r->type;
100 break;
101 }
102 }
103 }
104 regions = regions->next;
105 }
106
107 /* On release, all regions are disarmed. */
108 if (released)
109 skin_disarm_touchregions(data);
110
111 if (returncode != ACTION_NONE)
112 return returncode;
113
114 last_action = ACTION_TOUCHSCREEN;
115 return ACTION_TOUCHSCREEN;
116}
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 @@
21 21
22#include "config.h" 22#include "config.h"
23 23
24#include "action.h"
24#include "system.h" 25#include "system.h"
25#include "settings.h" 26#include "settings.h"
26#include "appevents.h" 27#include "appevents.h"
@@ -253,3 +254,36 @@ void sb_skin_init(void)
253 sb_skin[i].sync_data = &sb_skin_sync_data; 254 sb_skin[i].sync_data = &sb_skin_sync_data;
254 } 255 }
255} 256}
257
258#ifdef HAVE_TOUCHSCREEN
259static bool bypass_sb_touchregions = true;
260void sb_bypass_touchregions(bool enable)
261{
262 bypass_sb_touchregions = enable;
263}
264
265int sb_touch_to_button(int context)
266{
267 static int last_context = -1;
268 int button, offset;
269 if (bypass_sb_touchregions)
270 return ACTION_TOUCHSCREEN;
271
272 if (last_context != context)
273 skin_disarm_touchregions(&sb_skin_data[SCREEN_MAIN]);
274 last_context = context;
275 button = skin_get_touchaction(&sb_skin_data[SCREEN_MAIN], &offset);
276
277 switch (button)
278 {
279#ifdef HAVE_VOLUME_IN_LIST
280 case ACTION_WPS_VOLUP:
281 return ACTION_LIST_VOLUP;
282 case ACTION_WPS_VOLDOWN:
283 return ACTION_LIST_VOLDOWN;
284#endif
285 /* TODO */
286 }
287 return button;
288}
289#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);
43void sb_skin_set_update_delay(int delay); 43void sb_skin_set_update_delay(int delay);
44bool sb_set_title_text(char* title, enum themable_icons icon, enum screen_type screen); 44bool sb_set_title_text(char* title, enum themable_icons icon, enum screen_type screen);
45 45
46#ifdef HAVE_TOUCHSCREEN
47void sb_bypass_touchregions(bool enable);
48int sb_touch_to_button(int context);
49#endif
50
46#if (LCD_DEPTH > 1) || (defined(HAVE_REMOTE_LCD) && LCD_REMOTE_DEPTH > 1) 51#if (LCD_DEPTH > 1) || (defined(HAVE_REMOTE_LCD) && LCD_REMOTE_DEPTH > 1)
47char* sb_get_backdrop(enum screen_type screen); 52char* sb_get_backdrop(enum screen_type screen);
48bool sb_set_backdrop(enum screen_type screen, char* filename); 53bool 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)
169 screens[screen].set_viewport(NULL); 169 screens[screen].set_viewport(NULL);
170 } 170 }
171 intptr_t force = first_boot?0:1; 171 intptr_t force = first_boot?0:1;
172
172 send_event(GUI_EVENT_ACTIONUPDATE, (void*)force); 173 send_event(GUI_EVENT_ACTIONUPDATE, (void*)force);
173 } 174 }
174 else 175 else
@@ -182,7 +183,9 @@ static void toggle_theme(enum screen_type screen, bool force)
182 send_event(GUI_EVENT_THEME_CHANGED, NULL); 183 send_event(GUI_EVENT_THEME_CHANGED, NULL);
183 FOR_NB_SCREENS(i) 184 FOR_NB_SCREENS(i)
184 was_enabled[i] = is_theme_enabled(i); 185 was_enabled[i] = is_theme_enabled(i);
185 186#ifdef HAVE_TOUCHSCREEN
187 sb_bypass_touchregions(!is_theme_enabled(SCREEN_MAIN));
188#endif
186 after_boot[screen] = true; 189 after_boot[screen] = true;
187} 190}
188 191
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);
85static void track_changed_callback(void *param); 85static void track_changed_callback(void *param);
86static void nextid3available_callback(void* param); 86static void nextid3available_callback(void* param);
87 87
88#ifdef HAVE_TOUCHSCREEN
89static void wps_disarm_touchregions(struct wps_data *data);
90#endif
91
92#define WPS_DEFAULTCFG WPS_DIR "/rockbox_default.wps" 88#define WPS_DEFAULTCFG WPS_DIR "/rockbox_default.wps"
93#ifdef HAVE_REMOTE_LCD 89#ifdef HAVE_REMOTE_LCD
94#define RWPS_DEFAULTCFG WPS_DIR "/rockbox_default.rwps" 90#define RWPS_DEFAULTCFG WPS_DIR "/rockbox_default.rwps"
@@ -227,6 +223,55 @@ static bool update_onvol_change(struct gui_wps * gwps)
227} 223}
228 224
229 225
226#ifdef HAVE_TOUCHSCREEN
227int skintouch_to_wps(struct wps_data *data)
228{
229 int offset = 0;
230 int button = skin_get_touchaction(data, &offset);
231 switch (button)
232 {
233 case ACTION_STD_PREV:
234 return ACTION_WPS_SKIPPREV;
235 case ACTION_STD_PREVREPEAT:
236 return ACTION_WPS_SEEKBACK;
237 case ACTION_STD_NEXT:
238 return ACTION_WPS_SKIPNEXT;
239 case ACTION_STD_NEXTREPEAT:
240 return ACTION_WPS_SEEKFWD;
241 case ACTION_STD_MENU:
242 return ACTION_WPS_MENU;
243 case ACTION_STD_CONTEXT:
244 return ACTION_WPS_CONTEXT;
245 case ACTION_STD_QUICKSCREEN:
246 return ACTION_WPS_QUICKSCREEN;
247 case WPS_TOUCHREGION_SCROLLBAR:
248 wps_state.id3->elapsed = wps_state.id3->length*offset/100;
249 if (!wps_state.paused)
250#if (CONFIG_CODEC == SWCODEC)
251 audio_pre_ff_rewind();
252#else
253 audio_pause();
254#endif
255 audio_ff_rewind(wps_state.id3->elapsed);
256#if (CONFIG_CODEC != SWCODEC)
257 if (!wps_state.paused)
258 audio_resume();
259#endif
260 return ACTION_TOUCHSCREEN;
261 case WPS_TOUCHREGION_VOLUME:
262 {
263 const int min_vol = sound_min(SOUND_VOLUME);
264 const int max_vol = sound_max(SOUND_VOLUME);
265 global_settings.volume = (offset * (max_vol - min_vol)) / 100;
266 global_settings.volume += min_vol;
267 setvol();
268 }
269 return ACTION_TOUCHSCREEN;
270 }
271 return button;
272}
273#endif
274
230bool ffwd_rew(int button) 275bool ffwd_rew(int button)
231{ 276{
232 unsigned int step = 0; /* current ff/rewind step */ 277 unsigned int step = 0; /* current ff/rewind step */
@@ -359,7 +404,7 @@ bool ffwd_rew(int button)
359 button = get_action(CONTEXT_WPS|ALLOW_SOFTLOCK,TIMEOUT_BLOCK); 404 button = get_action(CONTEXT_WPS|ALLOW_SOFTLOCK,TIMEOUT_BLOCK);
360#ifdef HAVE_TOUCHSCREEN 405#ifdef HAVE_TOUCHSCREEN
361 if (button == ACTION_TOUCHSCREEN) 406 if (button == ACTION_TOUCHSCREEN)
362 button = wps_get_touchaction(gui_wps[SCREEN_MAIN].data); 407 button = skintouch_to_wps(gui_wps[SCREEN_MAIN].data);
363 if (button != ACTION_WPS_SEEKFWD && 408 if (button != ACTION_WPS_SEEKFWD &&
364 button != ACTION_WPS_SEEKBACK) 409 button != ACTION_WPS_SEEKBACK)
365 button = ACTION_WPS_STOPSEEK; 410 button = ACTION_WPS_STOPSEEK;
@@ -616,150 +661,13 @@ static void gwps_enter_wps(void)
616 skin_update(gwps, WPS_REFRESH_ALL); 661 skin_update(gwps, WPS_REFRESH_ALL);
617 662
618#ifdef HAVE_TOUCHSCREEN 663#ifdef HAVE_TOUCHSCREEN
619 wps_disarm_touchregions(gui_wps[i].data); 664 skin_disarm_touchregions(gui_wps[i].data);
620#endif 665#endif
621 } 666 }
622 /* force statusbar/skin update since we just cleared the whole screen */ 667 /* force statusbar/skin update since we just cleared the whole screen */
623 send_event(GUI_EVENT_ACTIONUPDATE, (void*)1); 668 send_event(GUI_EVENT_ACTIONUPDATE, (void*)1);
624} 669}
625 670
626#ifdef HAVE_TOUCHSCREEN
627/** Disarms all touchregions. */
628static void wps_disarm_touchregions(struct wps_data *data)
629{
630 struct skin_token_list *regions = data->touchregions;
631 while (regions)
632 {
633 ((struct touchregion *)regions->token->value.data)->armed = false;
634 regions = regions->next;
635 }
636}
637
638int wps_get_touchaction(struct wps_data *data)
639{
640 int returncode = ACTION_NONE;
641 short x,y;
642 short vx, vy;
643 int type = action_get_touchscreen_press(&x, &y);
644 static int last_action = ACTION_NONE;
645 struct touchregion *r;
646 bool repeated = (type == BUTTON_REPEAT);
647 bool released = (type == BUTTON_REL);
648 bool pressed = (type == BUTTON_TOUCHSCREEN);
649 struct skin_token_list *regions = data->touchregions;
650
651 while (regions)
652 {
653 r = (struct touchregion *)regions->token->value.data;
654 /* make sure this region's viewport is visible */
655 if (r->wvp->hidden_flags&VP_DRAW_HIDDEN)
656 {
657 regions = regions->next;
658 continue;
659 }
660 /* check if it's inside this viewport */
661 if (viewport_point_within_vp(&(r->wvp->vp), x, y))
662 { /* reposition the touch inside the viewport since touchregions
663 * are relative to a preceding viewport */
664 vx = x - r->wvp->vp.x;
665 vy = y - r->wvp->vp.y;
666 /* now see if the point is inside this region */
667 if (vx >= r->x && vx < r->x+r->width &&
668 vy >= r->y && vy < r->y+r->height)
669 {
670 /* reposition the touch within the area */
671 vx -= r->x;
672 vy -= r->y;
673
674 switch(r->type)
675 {
676 case WPS_TOUCHREGION_ACTION:
677 if (r->armed && ((repeated && r->repeat) || (released && !r->repeat)))
678 {
679 last_action = r->action;
680 returncode = r->action;
681 }
682 if (pressed)
683 r->armed = true;
684 break;
685 case WPS_TOUCHREGION_SCROLLBAR:
686 if(r->width > r->height)
687 /* landscape */
688 wps_state.id3->elapsed = (vx *
689 wps_state.id3->length) / r->width;
690 else
691 /* portrait */
692 wps_state.id3->elapsed = (vy *
693 wps_state.id3->length) / r->height;
694
695 if (!wps_state.paused)
696#if (CONFIG_CODEC == SWCODEC)
697 audio_pre_ff_rewind();
698#else
699 audio_pause();
700#endif
701 audio_ff_rewind(wps_state.id3->elapsed);
702#if (CONFIG_CODEC != SWCODEC)
703 if (!wps_state.paused)
704 audio_resume();
705#endif
706 break;
707 case WPS_TOUCHREGION_VOLUME:
708 {
709 const int min_vol = sound_min(SOUND_VOLUME);
710 const int max_vol = sound_max(SOUND_VOLUME);
711 if(r->width > r->height)
712 /* landscape */
713 global_settings.volume = (vx *
714 (max_vol - min_vol)) / r->width;
715 else
716 /* portrait */
717 global_settings.volume = ((r->height - vy) *
718 (max_vol-min_vol)) / r->height;
719
720 global_settings.volume += min_vol;
721 setvol();
722 returncode = ACTION_REDRAW;
723 }
724 }
725 }
726 }
727 regions = regions->next;
728 }
729
730 /* On release, all regions are disarmed. */
731 if (released)
732 wps_disarm_touchregions(data);
733
734 /* Now we need to convert buttons to the WPS context */
735 switch (returncode)
736 {
737 case ACTION_STD_PREV:
738 return ACTION_WPS_SKIPPREV;
739 case ACTION_STD_PREVREPEAT:
740 return ACTION_WPS_SEEKBACK;
741 case ACTION_STD_NEXT:
742 return ACTION_WPS_SKIPNEXT;
743 case ACTION_STD_NEXTREPEAT:
744 return ACTION_WPS_SEEKFWD;
745 case ACTION_STD_MENU:
746 return ACTION_WPS_MENU;
747 case ACTION_STD_CONTEXT:
748 return ACTION_WPS_CONTEXT;
749 case ACTION_STD_QUICKSCREEN:
750 return ACTION_WPS_QUICKSCREEN;
751 }
752
753 if (returncode != ACTION_NONE)
754 return returncode;
755
756
757 if ((last_action == ACTION_WPS_SEEKBACK || last_action == ACTION_WPS_SEEKFWD))
758 return ACTION_WPS_STOPSEEK;
759 last_action = ACTION_TOUCHSCREEN;
760 return ACTION_TOUCHSCREEN;
761}
762#endif
763/* The WPS can be left in two ways: 671/* The WPS can be left in two ways:
764 * a) call a function, which draws over the wps. In this case, the wps 672 * a) call a function, which draws over the wps. In this case, the wps
765 * will be still active (i.e. the below function didn't return) 673 * will be still active (i.e. the below function didn't return)
@@ -818,7 +726,7 @@ long gui_wps_show(void)
818 exit = true; 726 exit = true;
819#ifdef HAVE_TOUCHSCREEN 727#ifdef HAVE_TOUCHSCREEN
820 if (button == ACTION_TOUCHSCREEN) 728 if (button == ACTION_TOUCHSCREEN)
821 button = wps_get_touchaction(gui_wps[SCREEN_MAIN].data); 729 button = skintouch_to_wps(gui_wps[SCREEN_MAIN].data);
822#endif 730#endif
823/* The iPods/X5/M5 use a single button for the A-B mode markers, 731/* The iPods/X5/M5 use a single button for the A-B mode markers,
824 defined as ACTION_WPSAB_SINGLE in their config files. */ 732 defined as ACTION_WPSAB_SINGLE in their config files. */