1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
10 * Copyright (C) 2008 by Maurus Cuelenaere
11 * Copyright (C) 2009 by Karl Kurbjun
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.
18 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
19 * KIND, either express or implied.
21 ****************************************************************************/
25 #ifdef HAVE_TOUCHSCREEN
27 #include "pluginlib_touchscreen.h"
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 ******************************************************************************/
35 * This function checks the touchbutton structure passed to it for hits. When
36 * one is found it returns action.
38 * struct touchbutton *data: This is intended to be an array of
39 * touchbuttons of size num_buttons. Each element in the array defines
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
46 * If a touch occured over one of the defined buttons, return action, else
49 int touchbutton_get(struct touchbutton
*data
, int button
, int num_buttons
) {
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.
55 x
= rb
->button_get_data() >> 16;
56 y
= (short) rb
->button_get_data();
61 /* Loop over the data array to check if any of the buttons were pressed */
62 for (i
=0; i
<num_buttons
; i
++) {
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
;
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.
80 * struct touchbutton *data: This is intended to be an array of
81 * touchbuttons of size num_buttons. Each element in the array defines
83 * int num_buttons: This tells touchbutton_get how many elements are in
86 * If a touch occured over one of the defined buttons, return action, else
89 void touchbutton_draw(struct touchbutton
*data
, int num_buttons
) {
91 /* These store the width and height of the title offset */
92 int title_width
, title_height
;
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.
101 rb
->screens
[SCREEN_MAIN
]->set_viewport(&data
[i
].vp
);
103 /* Get the string size so that the title can be centered. */
104 rb
->lcd_getstringsize(data
[i
].title
, &title_width
, &title_height
);
106 /* Center the title vertically */
107 title_height
=(data
[i
].vp
.height
-title_height
)/2;
109 /* If the above calculation was negative, reset to 0 */
114 /* Center the title horizontally */
115 title_width
=(data
[i
].vp
.width
-title_width
)/2;
117 /* If the above calculation was negative, reset to 0 */
122 /* If the width offset was 0, use a scrolling puts, else center and
126 rb
->lcd_puts_scroll(0, 0, data
[i
].title
);
128 rb
->lcd_putsxy(title_width
, title_height
, data
[i
].title
);
131 /* Draw bounding box around the button location. */
132 rb
->lcd_drawrect( 0, 0, data
[i
].vp
.width
, data
[i
].vp
.height
);
135 rb
->screens
[SCREEN_MAIN
]->set_viewport(NULL
); /* Go back to the default viewport */
138 /*******************************************************************************
139 * Touchmap functions: Not sure how exactly these functions are used, comments
141 ******************************************************************************/
142 unsigned int touchscreen_map(struct ts_mappings
*map
, int x
, int y
)
145 for(i
=0; i
< map
->amount
; i
++)
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
))
156 unsigned int touchscreen_map_raster(struct ts_raster
*map
, int x
, int y
, struct ts_raster_result
*result
)
158 int res1_x
, res2_x
, res1_y
, res2_y
;
160 if((x
- map
->tl_x
) < 0 ||
161 (x
- map
->tl_x
) > map
->width
)
163 res1_x
= (x
- map
->tl_x
)/(map
->raster_width
);
164 res2_x
= (x
- map
->tl_x
)%(map
->raster_width
);
166 if((y
- map
->tl_y
) < 0 ||
167 (y
- map
->tl_y
) > map
->height
)
169 res1_y
= (y
- map
->tl_y
)/(map
->raster_height
);
170 res2_y
= (y
- map
->tl_y
)%(map
->raster_height
);
172 if(res2_x
== 0 || res2_y
== 0) /* pen hit a raster boundary */
176 (*result
).x
= res1_x
;
177 (*result
).y
= res1_y
;
182 struct ts_raster_button_result
touchscreen_raster_map_button(struct ts_raster_button_mapping
*map
, int x
, int y
, int button
)
184 struct ts_raster_button_result ret
= {0, {0, 0}, {0, 0}};
185 struct ts_raster_result tmp
;
187 ret
.action
= TS_ACTION_NONE
;
188 if(touchscreen_map_raster(map
->raster
, x
, y
, &tmp
) != 1)
191 #define NOT_HANDLED (ret.action == TS_ACTION_NONE)
192 if((button
== BUTTON_REPEAT
) && (map
->_prev_btn_state
!= BUTTON_REPEAT
) && map
->drag_drop_enable
)
194 map
->_prev_x
= tmp
.x
;
195 map
->_prev_y
= tmp
.y
;
197 if((button
== BUTTON_REL
) && (map
->_prev_btn_state
== BUTTON_REPEAT
) && map
->drag_drop_enable
)
199 ret
.action
= TS_ACTION_DRAG_DROP
;
200 ret
.from
.x
= map
->_prev_x
;
201 ret
.from
.y
= map
->_prev_y
;
205 if((button
== BUTTON_REL
) && map
->double_click_enable
&& NOT_HANDLED
)
207 if(map
->_prev_x
== tmp
.x
&& map
->_prev_y
== tmp
.y
)
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
;
215 map
->_prev_x
= tmp
.x
;
216 map
->_prev_y
= tmp
.y
;
219 if((button
& BUTTON_REL
|| button
& BUTTON_REPEAT
) && map
->two_d_movement_enable
&& NOT_HANDLED
)
221 if((map
->two_d_from
.x
== tmp
.x
) ^ (map
->two_d_from
.y
== tmp
.y
))
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));
230 ret
.action
= TS_ACTION_NONE
;
232 if(map
->click_enable
&& (button
& BUTTON_REL
) && NOT_HANDLED
)
234 ret
.action
= TS_ACTION_CLICK
;
235 ret
.from
.x
= ret
.to
.x
= tmp
.x
;
236 ret
.from
.y
= ret
.to
.y
= tmp
.y
;
238 if(map
->move_progress_enable
&& NOT_HANDLED
)
240 ret
.action
= TS_ACTION_MOVE
;
241 ret
.from
.x
= ret
.to
.x
= tmp
.x
;
242 ret
.from
.y
= ret
.to
.y
= tmp
.y
;
245 map
->_prev_btn_state
= button
;
249 #endif /* HAVE_TOUCHSCREEN */