diff options
author | Karl Kurbjun <kkurbjun@gmail.com> | 2009-08-02 07:05:30 +0000 |
---|---|---|
committer | Karl Kurbjun <kkurbjun@gmail.com> | 2009-08-02 07:05:30 +0000 |
commit | 0131a3873e0cb05bd357326b441f2cbc1884c657 (patch) | |
tree | bf224f3e36c3b052f3583d5692eae12d9c922f55 /apps/plugins/lib | |
parent | e9b061a7174298c61dd1f935a38654e07f573197 (diff) | |
download | rockbox-0131a3873e0cb05bd357326b441f2cbc1884c657.tar.gz rockbox-0131a3873e0cb05bd357326b441f2cbc1884c657.zip |
Pluginlib: Add support for general buttons. Add menu and quit buttons to Reversi. MRobe 500: Modify touch handler to return the previous data always rather than 0 when there is no touch.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@22110 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'apps/plugins/lib')
-rw-r--r-- | apps/plugins/lib/SOURCES | 2 | ||||
-rw-r--r-- | apps/plugins/lib/pluginlib_touchscreen.c | 249 | ||||
-rw-r--r-- | apps/plugins/lib/pluginlib_touchscreen.h (renamed from apps/plugins/lib/touchscreen.h) | 23 | ||||
-rw-r--r-- | apps/plugins/lib/touchscreen.c | 135 |
4 files changed, 273 insertions, 136 deletions
diff --git a/apps/plugins/lib/SOURCES b/apps/plugins/lib/SOURCES index 72538fc2a0..00d3ac7c56 100644 --- a/apps/plugins/lib/SOURCES +++ b/apps/plugins/lib/SOURCES | |||
@@ -54,7 +54,7 @@ pluginlib_albumart.c | |||
54 | pluginlib_actions.c | 54 | pluginlib_actions.c |
55 | helper.c | 55 | helper.c |
56 | #ifdef HAVE_TOUCHSCREEN | 56 | #ifdef HAVE_TOUCHSCREEN |
57 | touchscreen.c | 57 | pluginlib_touchscreen.c |
58 | #endif | 58 | #endif |
59 | md5.c | 59 | md5.c |
60 | 60 | ||
diff --git a/apps/plugins/lib/pluginlib_touchscreen.c b/apps/plugins/lib/pluginlib_touchscreen.c new file mode 100644 index 0000000000..eb023b064c --- /dev/null +++ b/apps/plugins/lib/pluginlib_touchscreen.c | |||
@@ -0,0 +1,249 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2008 by Maurus Cuelenaere | ||
11 | * Copyright (C) 2009 by Karl Kurbjun | ||
12 | * | ||
13 | * This program is free software; you can redistribute it and/or | ||
14 | * modify it under the terms of the GNU General Public License | ||
15 | * as published by the Free Software Foundation; either version 2 | ||
16 | * of the License, or (at your option) any later version. | ||
17 | * | ||
18 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
19 | * KIND, either express or implied. | ||
20 | * | ||
21 | ****************************************************************************/ | ||
22 | |||
23 | #include "plugin.h" | ||
24 | |||
25 | #ifdef HAVE_TOUCHSCREEN | ||
26 | |||
27 | #include "pluginlib_touchscreen.h" | ||
28 | |||
29 | /******************************************************************************* | ||
30 | * Touchbutton functions: These functions allow the plugin to specify a button | ||
31 | * location that, in turn gets mapped to a button press return value. | ||
32 | ******************************************************************************/ | ||
33 | |||
34 | /* touchbutton_get: | ||
35 | * This function checks the touchbutton structure passed to it for hits. When | ||
36 | * one is found it returns action. | ||
37 | * inputs: | ||
38 | * struct touchbutton *data: This is intended to be an array of | ||
39 | * touchbuttons of size num_buttons. Each element in the array defines | ||
40 | * one button. | ||
41 | * int button: This is the button return value from a button_get() call. | ||
42 | * It is used to determine REPEAT/RELEASE events. | ||
43 | * int num_buttons: This tells touchbutton_get how many elements are in | ||
44 | * data. | ||
45 | * return: | ||
46 | * If a touch occured over one of the defined buttons, return action, else | ||
47 | * return 0. | ||
48 | */ | ||
49 | int touchbutton_get(struct touchbutton *data, int button, int num_buttons) { | ||
50 | short x,y; | ||
51 | |||
52 | /* Get the x/y location of the button press, this is set by button_get when | ||
53 | * a button is pulled from the queue. | ||
54 | */ | ||
55 | x = rb->button_get_data() >> 16; | ||
56 | y = (short) rb->button_get_data(); | ||
57 | struct viewport *v; | ||
58 | |||
59 | int i; | ||
60 | |||
61 | /* Loop over the data array to check if any of the buttons were pressed */ | ||
62 | for (i=0; i<num_buttons; i++) { | ||
63 | v=&data[i].vp; | ||
64 | /* See if the point is inside the button viewport */ | ||
65 | if( x >= v->x && x < (v->x + v->width) && | ||
66 | y >= v->y && y < (v->y + v->height) ) { | ||
67 | if( ((button & BUTTON_REPEAT) && data[i].repeat) || | ||
68 | ((button & BUTTON_REL) && !data[i].repeat) ) { | ||
69 | return data[i].action; | ||
70 | } | ||
71 | } | ||
72 | } | ||
73 | return 0; | ||
74 | } | ||
75 | |||
76 | /* touchbutton_draw: | ||
77 | * This function draws the button with the associated text as long as the | ||
78 | * invisible flag is not set. Support for pixmaps needs to be added. | ||
79 | * inputs: | ||
80 | * struct touchbutton *data: This is intended to be an array of | ||
81 | * touchbuttons of size num_buttons. Each element in the array defines | ||
82 | * one button. | ||
83 | * int num_buttons: This tells touchbutton_get how many elements are in | ||
84 | * data. | ||
85 | * return: | ||
86 | * If a touch occured over one of the defined buttons, return action, else | ||
87 | * return 0. | ||
88 | */ | ||
89 | void touchbutton_draw(struct touchbutton *data, int num_buttons) { | ||
90 | int i; | ||
91 | /* These store the width and height of the title offset */ | ||
92 | int title_width, title_height; | ||
93 | |||
94 | /* Loop over all the elements in data */ | ||
95 | for(i=0; i<num_buttons; i++) { | ||
96 | /* Is this a visible button? */ | ||
97 | if(!data[i].invisible) { | ||
98 | /* Set the current viewport to the button so that all drawing | ||
99 | * operations are within the button location. | ||
100 | */ | ||
101 | rb->lcd_set_viewport(&data[i].vp); | ||
102 | |||
103 | /* Get the string size so that the title can be centered. */ | ||
104 | rb->lcd_getstringsize(data[i].title, &title_width, &title_height); | ||
105 | |||
106 | /* Center the title vertically */ | ||
107 | title_height=(data[i].vp.height-title_height)/2; | ||
108 | |||
109 | /* If the above calculation was negative, reset to 0 */ | ||
110 | if(title_height<0) { | ||
111 | title_height=0; | ||
112 | } | ||
113 | |||
114 | /* Center the title horizontally */ | ||
115 | title_width=(data[i].vp.width-title_width)/2; | ||
116 | |||
117 | /* If the above calculation was negative, reset to 0 */ | ||
118 | if(title_width<0) { | ||
119 | title_width=0; | ||
120 | } | ||
121 | |||
122 | /* If the width offset was 0, use a scrolling puts, else center and | ||
123 | * print the title. | ||
124 | */ | ||
125 | if(title_width==0) { | ||
126 | rb->lcd_puts_scroll(0, 0, data[i].title); | ||
127 | } else { | ||
128 | rb->lcd_putsxy(title_width, title_height, data[i].title); | ||
129 | } | ||
130 | |||
131 | /* Draw bounding box around the button location. */ | ||
132 | rb->lcd_drawrect( 0, 0, data[i].vp.width, data[i].vp.height); | ||
133 | } | ||
134 | } | ||
135 | rb->lcd_set_viewport(NULL); /* Go back to the default viewport */ | ||
136 | } | ||
137 | |||
138 | /******************************************************************************* | ||
139 | * Touchmap functions: Not sure how exactly these functions are used, comments | ||
140 | * needed!!! | ||
141 | ******************************************************************************/ | ||
142 | unsigned int touchscreen_map(struct ts_mappings *map, int x, int y) | ||
143 | { | ||
144 | int i; | ||
145 | for(i=0; i < map->amount; i++) | ||
146 | { | ||
147 | #define _MAP(x) (map->mappings[x]) | ||
148 | if(x > _MAP(i).tl_x && x < (_MAP(i).tl_x+_MAP(i).width) | ||
149 | && y > _MAP(i).tl_y && y < (_MAP(i).tl_y+_MAP(i).height)) | ||
150 | return i; | ||
151 | } | ||
152 | |||
153 | return -1; | ||
154 | } | ||
155 | |||
156 | unsigned int touchscreen_map_raster(struct ts_raster *map, int x, int y, struct ts_raster_result *result) | ||
157 | { | ||
158 | int res1_x, res2_x, res1_y, res2_y; | ||
159 | |||
160 | if((x - map->tl_x) < 0 || | ||
161 | (x - map->tl_x) > map->width) | ||
162 | return -1; | ||
163 | res1_x = (x - map->tl_x)/(map->raster_width); | ||
164 | res2_x = (x - map->tl_x)%(map->raster_width); | ||
165 | |||
166 | if((y - map->tl_y) < 0 || | ||
167 | (y - map->tl_y) > map->height) | ||
168 | return -1; | ||
169 | res1_y = (y - map->tl_y)/(map->raster_height); | ||
170 | res2_y = (y - map->tl_y)%(map->raster_height); | ||
171 | |||
172 | if(res2_x == 0 || res2_y == 0) /* pen hit a raster boundary */ | ||
173 | return -2; | ||
174 | else | ||
175 | { | ||
176 | (*result).x = res1_x; | ||
177 | (*result).y = res1_y; | ||
178 | return 1; | ||
179 | } | ||
180 | } | ||
181 | |||
182 | struct ts_raster_button_result touchscreen_raster_map_button(struct ts_raster_button_mapping *map, int x, int y, int button) | ||
183 | { | ||
184 | struct ts_raster_button_result ret = {0, {0, 0}, {0, 0}}; | ||
185 | struct ts_raster_result tmp; | ||
186 | |||
187 | ret.action = TS_ACTION_NONE; | ||
188 | if(touchscreen_map_raster(map->raster, x, y, &tmp) != 1) | ||
189 | return ret; | ||
190 | |||
191 | #define NOT_HANDLED (ret.action == TS_ACTION_NONE) | ||
192 | if((button == BUTTON_REPEAT) && (map->_prev_btn_state != BUTTON_REPEAT) && map->drag_drop_enable) | ||
193 | { | ||
194 | map->_prev_x = tmp.x; | ||
195 | map->_prev_y = tmp.y; | ||
196 | } | ||
197 | if((button == BUTTON_REL) && (map->_prev_btn_state == BUTTON_REPEAT) && map->drag_drop_enable) | ||
198 | { | ||
199 | ret.action = TS_ACTION_DRAG_DROP; | ||
200 | ret.from.x = map->_prev_x; | ||
201 | ret.from.y = map->_prev_y; | ||
202 | ret.to.x = tmp.x; | ||
203 | ret.to.y = tmp.y; | ||
204 | } | ||
205 | if((button == BUTTON_REL) && map->double_click_enable && NOT_HANDLED) | ||
206 | { | ||
207 | if(map->_prev_x == tmp.x && map->_prev_y == tmp.y) | ||
208 | { | ||
209 | ret.action = TS_ACTION_DOUBLE_CLICK; | ||
210 | ret.from.x = ret.to.x = tmp.x; | ||
211 | ret.from.y = ret.to.y = tmp.y; | ||
212 | } | ||
213 | else | ||
214 | { | ||
215 | map->_prev_x = tmp.x; | ||
216 | map->_prev_y = tmp.y; | ||
217 | } | ||
218 | } | ||
219 | if((button & BUTTON_REL || button & BUTTON_REPEAT) && map->two_d_movement_enable && NOT_HANDLED) | ||
220 | { | ||
221 | if((map->two_d_from.x == tmp.x) ^ (map->two_d_from.y == tmp.y)) | ||
222 | { | ||
223 | ret.action = TS_ACTION_TWO_D_MOVEMENT; | ||
224 | ret.from.x = map->two_d_from.x; | ||
225 | ret.from.y = map->two_d_from.y; | ||
226 | ret.to.x = map->two_d_from.x + (map->two_d_from.x == tmp.x ? 0 : (tmp.x > map->two_d_from.x ? 1 : -1)); | ||
227 | ret.to.y = map->two_d_from.y + (map->two_d_from.y == tmp.y ? 0 : (tmp.y > map->two_d_from.y ? 1 : -1)); | ||
228 | } | ||
229 | else | ||
230 | ret.action = TS_ACTION_NONE; | ||
231 | } | ||
232 | if(map->click_enable && (button & BUTTON_REL) && NOT_HANDLED) | ||
233 | { | ||
234 | ret.action = TS_ACTION_CLICK; | ||
235 | ret.from.x = ret.to.x = tmp.x; | ||
236 | ret.from.y = ret.to.y = tmp.y; | ||
237 | } | ||
238 | if(map->move_progress_enable && NOT_HANDLED) | ||
239 | { | ||
240 | ret.action = TS_ACTION_MOVE; | ||
241 | ret.from.x = ret.to.x = tmp.x; | ||
242 | ret.from.y = ret.to.y = tmp.y; | ||
243 | } | ||
244 | |||
245 | map->_prev_btn_state = button; | ||
246 | return ret; | ||
247 | } | ||
248 | |||
249 | #endif /* HAVE_TOUCHSCREEN */ | ||
diff --git a/apps/plugins/lib/touchscreen.h b/apps/plugins/lib/pluginlib_touchscreen.h index cd5251e46f..f2787655ee 100644 --- a/apps/plugins/lib/touchscreen.h +++ b/apps/plugins/lib/pluginlib_touchscreen.h | |||
@@ -8,6 +8,7 @@ | |||
8 | * $Id$ | 8 | * $Id$ |
9 | * | 9 | * |
10 | * Copyright (C) 2008 by Maurus Cuelenaere | 10 | * Copyright (C) 2008 by Maurus Cuelenaere |
11 | * Copyright (C) 2009 by Karl Kurbjun | ||
11 | * | 12 | * |
12 | * This program is free software; you can redistribute it and/or | 13 | * This program is free software; you can redistribute it and/or |
13 | * modify it under the terms of the GNU General Public License | 14 | * modify it under the terms of the GNU General Public License |
@@ -26,6 +27,28 @@ | |||
26 | 27 | ||
27 | #ifdef HAVE_TOUCHSCREEN | 28 | #ifdef HAVE_TOUCHSCREEN |
28 | 29 | ||
30 | /******************************************************************************* | ||
31 | * Touchbutton | ||
32 | ******************************************************************************/ | ||
33 | struct touchbutton { | ||
34 | /* Each button has it's own viewport to define colors, drawstyle, location*/ | ||
35 | struct viewport vp; | ||
36 | bool repeat; /* requires the area be held for the action */ | ||
37 | int action; /* action this button will return */ | ||
38 | bool invisible; /* Is this an invisible button? */ | ||
39 | char *title; /* Specify a title */ | ||
40 | fb_data *pixmap; /* Currently unused, but will allow for a graphic */ | ||
41 | }; | ||
42 | |||
43 | /* Get: tests for a button press and returns action. */ | ||
44 | int touchbutton_get(struct touchbutton *data, int button, int num_buttons); | ||
45 | /* Draw: Draws all visible buttons */ | ||
46 | void touchbutton_draw(struct touchbutton *data, int num_buttons); | ||
47 | |||
48 | |||
49 | /******************************************************************************* | ||
50 | * Touch mapping | ||
51 | ******************************************************************************/ | ||
29 | struct ts_mapping | 52 | struct ts_mapping |
30 | { | 53 | { |
31 | int tl_x; /* top left */ | 54 | int tl_x; /* top left */ |
diff --git a/apps/plugins/lib/touchscreen.c b/apps/plugins/lib/touchscreen.c deleted file mode 100644 index 5b7517349a..0000000000 --- a/apps/plugins/lib/touchscreen.c +++ /dev/null | |||
@@ -1,135 +0,0 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2008 by Maurus Cuelenaere | ||
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 "plugin.h" | ||
23 | |||
24 | #ifdef HAVE_TOUCHSCREEN | ||
25 | |||
26 | #include "touchscreen.h" | ||
27 | |||
28 | unsigned int touchscreen_map(struct ts_mappings *map, int x, int y) | ||
29 | { | ||
30 | int i; | ||
31 | for(i=0; i < map->amount; i++) | ||
32 | { | ||
33 | #define _MAP(x) (map->mappings[x]) | ||
34 | if(x > _MAP(i).tl_x && x < (_MAP(i).tl_x+_MAP(i).width) | ||
35 | && y > _MAP(i).tl_y && y < (_MAP(i).tl_y+_MAP(i).height)) | ||
36 | return i; | ||
37 | } | ||
38 | |||
39 | return -1; | ||
40 | } | ||
41 | |||
42 | unsigned int touchscreen_map_raster(struct ts_raster *map, int x, int y, struct ts_raster_result *result) | ||
43 | { | ||
44 | int res1_x, res2_x, res1_y, res2_y; | ||
45 | |||
46 | if((x - map->tl_x) < 0 || | ||
47 | (x - map->tl_x) > map->width) | ||
48 | return -1; | ||
49 | res1_x = (x - map->tl_x)/(map->raster_width); | ||
50 | res2_x = (x - map->tl_x)%(map->raster_width); | ||
51 | |||
52 | if((y - map->tl_y) < 0 || | ||
53 | (y - map->tl_y) > map->height) | ||
54 | return -1; | ||
55 | res1_y = (y - map->tl_y)/(map->raster_height); | ||
56 | res2_y = (y - map->tl_y)%(map->raster_height); | ||
57 | |||
58 | if(res2_x == 0 || res2_y == 0) /* pen hit a raster boundary */ | ||
59 | return -2; | ||
60 | else | ||
61 | { | ||
62 | (*result).x = res1_x; | ||
63 | (*result).y = res1_y; | ||
64 | return 1; | ||
65 | } | ||
66 | } | ||
67 | |||
68 | struct ts_raster_button_result touchscreen_raster_map_button(struct ts_raster_button_mapping *map, int x, int y, int button) | ||
69 | { | ||
70 | struct ts_raster_button_result ret = {0, {0, 0}, {0, 0}}; | ||
71 | struct ts_raster_result tmp; | ||
72 | |||
73 | ret.action = TS_ACTION_NONE; | ||
74 | if(touchscreen_map_raster(map->raster, x, y, &tmp) != 1) | ||
75 | return ret; | ||
76 | |||
77 | #define NOT_HANDLED (ret.action == TS_ACTION_NONE) | ||
78 | if((button == BUTTON_REPEAT) && (map->_prev_btn_state != BUTTON_REPEAT) && map->drag_drop_enable) | ||
79 | { | ||
80 | map->_prev_x = tmp.x; | ||
81 | map->_prev_y = tmp.y; | ||
82 | } | ||
83 | if((button == BUTTON_REL) && (map->_prev_btn_state == BUTTON_REPEAT) && map->drag_drop_enable) | ||
84 | { | ||
85 | ret.action = TS_ACTION_DRAG_DROP; | ||
86 | ret.from.x = map->_prev_x; | ||
87 | ret.from.y = map->_prev_y; | ||
88 | ret.to.x = tmp.x; | ||
89 | ret.to.y = tmp.y; | ||
90 | } | ||
91 | if((button == BUTTON_REL) && map->double_click_enable && NOT_HANDLED) | ||
92 | { | ||
93 | if(map->_prev_x == tmp.x && map->_prev_y == tmp.y) | ||
94 | { | ||
95 | ret.action = TS_ACTION_DOUBLE_CLICK; | ||
96 | ret.from.x = ret.to.x = tmp.x; | ||
97 | ret.from.y = ret.to.y = tmp.y; | ||
98 | } | ||
99 | else | ||
100 | { | ||
101 | map->_prev_x = tmp.x; | ||
102 | map->_prev_y = tmp.y; | ||
103 | } | ||
104 | } | ||
105 | if((button & BUTTON_REL || button & BUTTON_REPEAT) && map->two_d_movement_enable && NOT_HANDLED) | ||
106 | { | ||
107 | if((map->two_d_from.x == tmp.x) ^ (map->two_d_from.y == tmp.y)) | ||
108 | { | ||
109 | ret.action = TS_ACTION_TWO_D_MOVEMENT; | ||
110 | ret.from.x = map->two_d_from.x; | ||
111 | ret.from.y = map->two_d_from.y; | ||
112 | ret.to.x = map->two_d_from.x + (map->two_d_from.x == tmp.x ? 0 : (tmp.x > map->two_d_from.x ? 1 : -1)); | ||
113 | ret.to.y = map->two_d_from.y + (map->two_d_from.y == tmp.y ? 0 : (tmp.y > map->two_d_from.y ? 1 : -1)); | ||
114 | } | ||
115 | else | ||
116 | ret.action = TS_ACTION_NONE; | ||
117 | } | ||
118 | if(map->click_enable && (button & BUTTON_REL) && NOT_HANDLED) | ||
119 | { | ||
120 | ret.action = TS_ACTION_CLICK; | ||
121 | ret.from.x = ret.to.x = tmp.x; | ||
122 | ret.from.y = ret.to.y = tmp.y; | ||
123 | } | ||
124 | if(map->move_progress_enable && NOT_HANDLED) | ||
125 | { | ||
126 | ret.action = TS_ACTION_MOVE; | ||
127 | ret.from.x = ret.to.x = tmp.x; | ||
128 | ret.from.y = ret.to.y = tmp.y; | ||
129 | } | ||
130 | |||
131 | map->_prev_btn_state = button; | ||
132 | return ret; | ||
133 | } | ||
134 | |||
135 | #endif /* HAVE_TOUCHSCREEN */ | ||