Parent Directory | Revision Log
osm-map path, gps etc. adjustements
1 | harbaum | 71 | /* -*- Mode: C; indent-tabs-mode: nil; c-basic-offset: 4; tab-width: 4 -*- */ |
2 | /* vim:set et sw=4 ts=4 cino=t0,(0: */ | ||
3 | harbaum | 70 | /* |
4 | * Copyright (C) Till Harbaum 2009 <till@harbaum.org> | ||
5 | * | ||
6 | * osm-gps-map is free software: you can redistribute it and/or modify it | ||
7 | * under the terms of the GNU General Public License as published by the | ||
8 | * Free Software Foundation, either version 3 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | * | ||
11 | * osm-gps-map is distributed in the hope that it will be useful, but | ||
12 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | ||
14 | * See the GNU General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License along | ||
17 | * with this program. If not, see <http://www.gnu.org/licenses/>. | ||
18 | */ | ||
19 | |||
20 | harbaum | 73 | #include "config.h" |
21 | #include <stdlib.h> // abs | ||
22 | #include <math.h> // M_PI | ||
23 | harbaum | 70 | |
24 | harbaum | 71 | /* parameters that can be overwritten from the config file: */ |
25 | harbaum | 77 | /* OSD_DIAMETER */ |
26 | /* OSD_X, OSD_Y */ | ||
27 | harbaum | 71 | |
28 | #ifndef USE_CAIRO | ||
29 | #error "OSD control display lacks a non-cairo implementation!" | ||
30 | harbaum | 70 | #endif |
31 | |||
32 | harbaum | 71 | #include <cairo.h> |
33 | |||
34 | #include "osm-gps-map.h" | ||
35 | harbaum | 73 | #include "osm-gps-map-osd-classic.h" |
36 | harbaum | 71 | |
37 | harbaum | 70 | //the osd controls |
38 | typedef struct { | ||
39 | harbaum | 74 | /* the offscreen representation of the OSD */ |
40 | cairo_surface_t *overlay; | ||
41 | harbaum | 70 | } osd_priv_t; |
42 | |||
43 | /* position and extent of bounding box */ | ||
44 | harbaum | 77 | #ifndef OSD_X |
45 | harbaum | 70 | #define OSD_X (10) |
46 | harbaum | 77 | #endif |
47 | |||
48 | #ifndef OSD_Y | ||
49 | harbaum | 70 | #define OSD_Y (10) |
50 | harbaum | 77 | #endif |
51 | harbaum | 70 | |
52 | /* parameters of the direction shape */ | ||
53 | harbaum | 77 | #ifndef OSD_DIAMETER |
54 | harbaum | 70 | #define D_RAD (30) // diameter of dpad |
55 | #else | ||
56 | harbaum | 77 | #define D_RAD (OSD_DIAMETER) |
57 | harbaum | 70 | #endif |
58 | #define D_TIP (4*D_RAD/5) // distance of arrow tip from dpad center | ||
59 | #define D_LEN (D_RAD/4) // length of arrow | ||
60 | #define D_WID (D_LEN) // width of arrow | ||
61 | |||
62 | /* parameters of the "zoom" pad */ | ||
63 | #define Z_STEP (D_RAD/4) // distance between dpad and zoom | ||
64 | #define Z_RAD (D_RAD/2) // radius of "caps" of zoom bar | ||
65 | |||
66 | harbaum | 74 | #ifdef OSD_SHADOW_ENABLE |
67 | harbaum | 70 | /* shadow also depends on control size */ |
68 | #define OSD_SHADOW (D_RAD/6) | ||
69 | harbaum | 74 | #else |
70 | #define OSD_SHADOW (0) | ||
71 | #endif | ||
72 | harbaum | 70 | |
73 | harbaum | 77 | /* normally the GPS button is in the center of the dpad. if there's */ |
74 | /* no dpad it will go into the zoom area */ | ||
75 | #if defined(OSD_GPS_BUTTON) && defined(OSD_NO_DPAD) | ||
76 | #define Z_GPS 1 | ||
77 | #else | ||
78 | #define Z_GPS 0 | ||
79 | #endif | ||
80 | |||
81 | harbaum | 70 | /* total width and height of controls incl. shadow */ |
82 | harbaum | 77 | #define OSD_W (2*D_RAD + OSD_SHADOW + Z_GPS * 2 * Z_RAD) |
83 | #if !Z_GPS | ||
84 | harbaum | 70 | #define OSD_H (2*D_RAD + Z_STEP + 2*Z_RAD + OSD_SHADOW) |
85 | harbaum | 77 | #else |
86 | #define OSD_H (2*Z_RAD + OSD_SHADOW) | ||
87 | #endif | ||
88 | harbaum | 70 | |
89 | harbaum | 74 | #ifdef OSD_SHADOW_ENABLE |
90 | harbaum | 70 | #define OSD_LBL_SHADOW (OSD_SHADOW/2) |
91 | harbaum | 74 | #endif |
92 | harbaum | 70 | |
93 | harbaum | 77 | #define Z_TOP ((1-Z_GPS) * (2 * D_RAD + Z_STEP)) |
94 | |||
95 | harbaum | 70 | #define Z_MID (Z_TOP + Z_RAD) |
96 | #define Z_BOT (Z_MID + Z_RAD) | ||
97 | #define Z_LEFT (Z_RAD) | ||
98 | harbaum | 77 | #define Z_RIGHT (2 * D_RAD - Z_RAD + Z_GPS * 2 * Z_RAD) |
99 | #define Z_CENTER ((Z_RIGHT + Z_LEFT)/2) | ||
100 | harbaum | 70 | |
101 | /* create the cairo shape used for the zoom buttons */ | ||
102 | static void | ||
103 | harbaum | 71 | osm_gps_map_osd_zoom_shape(cairo_t *cr, gint x, gint y) |
104 | { | ||
105 | harbaum | 70 | cairo_move_to (cr, x+Z_LEFT, y+Z_TOP); |
106 | cairo_line_to (cr, x+Z_RIGHT, y+Z_TOP); | ||
107 | cairo_arc (cr, x+Z_RIGHT, y+Z_MID, Z_RAD, -M_PI/2, M_PI/2); | ||
108 | cairo_line_to (cr, x+Z_LEFT, y+Z_BOT); | ||
109 | cairo_arc (cr, x+Z_LEFT, y+Z_MID, Z_RAD, M_PI/2, -M_PI/2); | ||
110 | } | ||
111 | |||
112 | harbaum | 76 | #ifndef OSD_NO_DPAD |
113 | harbaum | 70 | /* create the cairo shape used for the dpad */ |
114 | static void | ||
115 | harbaum | 71 | osm_gps_map_osd_dpad_shape(cairo_t *cr, gint x, gint y) |
116 | { | ||
117 | harbaum | 70 | cairo_arc (cr, x+D_RAD, y+D_RAD, D_RAD, 0, 2 * M_PI); |
118 | } | ||
119 | harbaum | 76 | #endif |
120 | harbaum | 70 | |
121 | static gboolean | ||
122 | osm_gps_map_in_circle(gint x, gint y, gint cx, gint cy, gint rad) | ||
123 | { | ||
124 | return( pow(cx - x, 2) + pow(cy - y, 2) < rad * rad); | ||
125 | } | ||
126 | |||
127 | harbaum | 76 | #ifndef OSD_NO_DPAD |
128 | harbaum | 70 | /* check whether x/y is within the dpad */ |
129 | static osd_button_t | ||
130 | osm_gps_map_osd_check_dpad(gint x, gint y) | ||
131 | { | ||
132 | /* within entire dpad circle */ | ||
133 | harbaum | 77 | if( osm_gps_map_in_circle(x, y, D_RAD, D_RAD, D_RAD)) |
134 | harbaum | 70 | { |
135 | /* convert into position relative to dpads centre */ | ||
136 | harbaum | 77 | x -= D_RAD; |
137 | y -= D_RAD; | ||
138 | harbaum | 70 | |
139 | harbaum | 76 | #ifdef OSD_GPS_BUTTON |
140 | harbaum | 70 | /* check for dpad center goes here! */ |
141 | if( osm_gps_map_in_circle(x, y, 0, 0, D_RAD/3)) | ||
142 | return OSD_GPS; | ||
143 | harbaum | 76 | #endif |
144 | harbaum | 70 | |
145 | if( y < 0 && abs(x) < abs(y)) | ||
146 | return OSD_UP; | ||
147 | |||
148 | if( y > 0 && abs(x) < abs(y)) | ||
149 | return OSD_DOWN; | ||
150 | |||
151 | if( x < 0 && abs(y) < abs(x)) | ||
152 | return OSD_LEFT; | ||
153 | |||
154 | if( x > 0 && abs(y) < abs(x)) | ||
155 | return OSD_RIGHT; | ||
156 | |||
157 | return OSD_BG; | ||
158 | } | ||
159 | return OSD_NONE; | ||
160 | } | ||
161 | harbaum | 76 | #endif |
162 | harbaum | 70 | |
163 | /* check whether x/y is within the zoom pads */ | ||
164 | static osd_button_t | ||
165 | osm_gps_map_osd_check_zoom(gint x, gint y) { | ||
166 | harbaum | 77 | if( x > 0 && x < OSD_W && y > Z_TOP && y < Z_BOT) { |
167 | harbaum | 70 | |
168 | /* within circle around (-) label */ | ||
169 | harbaum | 77 | if( osm_gps_map_in_circle(x, y, Z_LEFT, Z_MID, Z_RAD)) |
170 | harbaum | 70 | return OSD_OUT; |
171 | |||
172 | harbaum | 77 | /* within circle around (+) label */ |
173 | if( osm_gps_map_in_circle(x, y, Z_RIGHT, Z_MID, Z_RAD)) | ||
174 | return OSD_IN; | ||
175 | |||
176 | #if Z_GPS == 1 | ||
177 | /* within square around center */ | ||
178 | if( x > Z_CENTER - Z_RAD && x < Z_CENTER + Z_RAD) | ||
179 | return OSD_GPS; | ||
180 | #endif | ||
181 | |||
182 | harbaum | 70 | /* between center of (-) button and center of entire zoom control area */ |
183 | harbaum | 77 | if(x > OSD_LEFT && x < D_RAD) |
184 | harbaum | 70 | return OSD_OUT; |
185 | |||
186 | /* between center of (+) button and center of entire zoom control area */ | ||
187 | harbaum | 77 | if(x < OSD_RIGHT && x > D_RAD) |
188 | harbaum | 70 | return OSD_IN; |
189 | } | ||
190 | |||
191 | return OSD_NONE; | ||
192 | } | ||
193 | |||
194 | static osd_button_t | ||
195 | harbaum | 77 | osm_gps_map_osd_check(osm_gps_map_osd_t *osd, gint x, gint y) { |
196 | harbaum | 70 | osd_button_t but = OSD_NONE; |
197 | |||
198 | harbaum | 77 | x -= OSD_X; |
199 | y -= OSD_Y; | ||
200 | |||
201 | if(OSD_X < 0) | ||
202 | x -= (osd->widget->allocation.width - OSD_W); | ||
203 | |||
204 | if(OSD_Y < 0) | ||
205 | y -= (osd->widget->allocation.height - OSD_H); | ||
206 | |||
207 | harbaum | 70 | /* first do a rough test for the OSD area. */ |
208 | /* this is just to avoid an unnecessary detailed test */ | ||
209 | harbaum | 77 | if(x > 0 && x < OSD_W && y > 0 && y < OSD_H) { |
210 | harbaum | 76 | #ifndef OSD_NO_DPAD |
211 | harbaum | 70 | but = osm_gps_map_osd_check_dpad(x, y); |
212 | harbaum | 76 | #endif |
213 | harbaum | 70 | |
214 | if(but == OSD_NONE) | ||
215 | but = osm_gps_map_osd_check_zoom(x, y); | ||
216 | } | ||
217 | |||
218 | return but; | ||
219 | } | ||
220 | |||
221 | harbaum | 74 | #ifdef OSD_SHADOW_ENABLE |
222 | harbaum | 70 | static void |
223 | osm_gps_map_osd_shape_shadow(cairo_t *cr) { | ||
224 | cairo_set_source_rgba (cr, 0, 0, 0, 0.2); | ||
225 | cairo_fill (cr); | ||
226 | cairo_stroke (cr); | ||
227 | } | ||
228 | harbaum | 74 | #endif |
229 | harbaum | 70 | |
230 | harbaum | 74 | #ifndef OSD_COLOR |
231 | /* if no color has been specified we just use the gdks default colors */ | ||
232 | harbaum | 70 | static void |
233 | harbaum | 74 | osm_gps_map_osd_shape(cairo_t *cr, GdkColor *bg, GdkColor *fg) { |
234 | gdk_cairo_set_source_color(cr, bg); | ||
235 | cairo_fill_preserve (cr); | ||
236 | gdk_cairo_set_source_color(cr, fg); | ||
237 | cairo_set_line_width (cr, 1); | ||
238 | cairo_stroke (cr); | ||
239 | } | ||
240 | #else | ||
241 | static void | ||
242 | harbaum | 70 | osm_gps_map_osd_shape(cairo_t *cr) { |
243 | harbaum | 74 | cairo_set_source_rgb (cr, OSD_COLOR_BG); |
244 | harbaum | 70 | cairo_fill_preserve (cr); |
245 | cairo_set_source_rgb (cr, OSD_COLOR); | ||
246 | cairo_set_line_width (cr, 1); | ||
247 | cairo_stroke (cr); | ||
248 | } | ||
249 | harbaum | 74 | #endif |
250 | harbaum | 70 | |
251 | harbaum | 76 | #ifndef OSD_NO_DPAD |
252 | harbaum | 70 | static void |
253 | osm_gps_map_osd_dpad_labels(cairo_t *cr, gint x, gint y) { | ||
254 | /* move reference to dpad center */ | ||
255 | x += D_RAD; | ||
256 | y += D_RAD; | ||
257 | |||
258 | const static gint offset[][3][2] = { | ||
259 | /* left arrow/triangle */ | ||
260 | { { -D_TIP+D_LEN, -D_WID }, { -D_LEN, D_WID }, { +D_LEN, D_WID } }, | ||
261 | /* right arrow/triangle */ | ||
262 | { { +D_TIP-D_LEN, -D_WID }, { +D_LEN, D_WID }, { -D_LEN, D_WID } }, | ||
263 | /* top arrow/triangle */ | ||
264 | { { -D_WID, -D_TIP+D_LEN }, { D_WID, -D_LEN }, { D_WID, +D_LEN } }, | ||
265 | /* bottom arrow/triangle */ | ||
266 | { { -D_WID, +D_TIP-D_LEN }, { D_WID, +D_LEN }, { D_WID, -D_LEN } } | ||
267 | }; | ||
268 | |||
269 | int i; | ||
270 | for(i=0;i<4;i++) { | ||
271 | cairo_move_to (cr, x + offset[i][0][0], y + offset[i][0][1]); | ||
272 | cairo_rel_line_to (cr, offset[i][1][0], offset[i][1][1]); | ||
273 | cairo_rel_line_to (cr, offset[i][2][0], offset[i][2][1]); | ||
274 | } | ||
275 | } | ||
276 | harbaum | 76 | #endif |
277 | harbaum | 70 | |
278 | harbaum | 76 | #ifdef OSD_GPS_BUTTON |
279 | /* draw the satellite dish icon in the center of the dpad */ | ||
280 | harbaum | 77 | #define GPS_V0 (D_RAD/7) |
281 | harbaum | 70 | #define GPS_V1 (D_RAD/10) |
282 | #define GPS_V2 (D_RAD/5) | ||
283 | |||
284 | /* draw a satellite receiver dish */ | ||
285 | harbaum | 77 | /* this is either drawn in the center of the dpad (if present) */ |
286 | /* or in the middle of the zoom area */ | ||
287 | harbaum | 70 | static void |
288 | osm_gps_map_osd_dpad_gps(cairo_t *cr, gint x, gint y) { | ||
289 | /* move reference to dpad center */ | ||
290 | harbaum | 77 | x += (1-Z_GPS) * D_RAD + Z_GPS * Z_RAD * 3; |
291 | y += (1-Z_GPS) * D_RAD + Z_GPS * Z_RAD + GPS_V0; | ||
292 | harbaum | 70 | |
293 | cairo_move_to (cr, x-GPS_V0, y+GPS_V0); | ||
294 | cairo_rel_line_to (cr, +GPS_V0, -GPS_V0); | ||
295 | cairo_rel_line_to (cr, +GPS_V0, +GPS_V0); | ||
296 | cairo_close_path (cr); | ||
297 | |||
298 | cairo_move_to (cr, x+GPS_V1-GPS_V2, y-2*GPS_V2); | ||
299 | cairo_curve_to (cr, x-GPS_V2, y, x+GPS_V1, y+GPS_V1, x+GPS_V1+GPS_V2, y); | ||
300 | cairo_close_path (cr); | ||
301 | |||
302 | x += GPS_V1; | ||
303 | cairo_move_to (cr, x, y-GPS_V2); | ||
304 | cairo_rel_line_to (cr, +GPS_V1, -GPS_V1); | ||
305 | } | ||
306 | harbaum | 76 | #endif |
307 | harbaum | 70 | |
308 | #define Z_LEN (2*Z_RAD/3) | ||
309 | |||
310 | static void | ||
311 | osm_gps_map_osd_zoom_labels(cairo_t *cr, gint x, gint y) { | ||
312 | cairo_move_to (cr, x + Z_LEFT - Z_LEN, y + Z_MID); | ||
313 | cairo_line_to (cr, x + Z_LEFT + Z_LEN, y + Z_MID); | ||
314 | |||
315 | cairo_move_to (cr, x + Z_RIGHT, y + Z_MID - Z_LEN); | ||
316 | cairo_line_to (cr, x + Z_RIGHT, y + Z_MID + Z_LEN); | ||
317 | cairo_move_to (cr, x + Z_RIGHT - Z_LEN, y + Z_MID); | ||
318 | cairo_line_to (cr, x + Z_RIGHT + Z_LEN, y + Z_MID); | ||
319 | } | ||
320 | |||
321 | harbaum | 74 | #ifndef OSD_COLOR |
322 | /* if no color has been specified we just use the gdks default colors */ | ||
323 | harbaum | 70 | static void |
324 | harbaum | 74 | osm_gps_map_osd_labels(cairo_t *cr, gint width, gboolean enabled, |
325 | GdkColor *fg, GdkColor *disabled) { | ||
326 | if(enabled) gdk_cairo_set_source_color(cr, fg); | ||
327 | else gdk_cairo_set_source_color(cr, disabled); | ||
328 | cairo_set_line_width (cr, width); | ||
329 | cairo_stroke (cr); | ||
330 | } | ||
331 | #else | ||
332 | static void | ||
333 | harbaum | 70 | osm_gps_map_osd_labels(cairo_t *cr, gint width, gboolean enabled) { |
334 | if(enabled) cairo_set_source_rgb (cr, OSD_COLOR); | ||
335 | else cairo_set_source_rgb (cr, OSD_COLOR_DISABLED); | ||
336 | cairo_set_line_width (cr, width); | ||
337 | cairo_stroke (cr); | ||
338 | } | ||
339 | harbaum | 74 | #endif |
340 | harbaum | 70 | |
341 | harbaum | 74 | #ifdef OSD_SHADOW_ENABLE |
342 | harbaum | 70 | static void |
343 | osm_gps_map_osd_labels_shadow(cairo_t *cr, gint width, gboolean enabled) { | ||
344 | cairo_set_source_rgba (cr, 0, 0, 0, enabled?0.3:0.15); | ||
345 | cairo_set_line_width (cr, width); | ||
346 | cairo_stroke (cr); | ||
347 | } | ||
348 | harbaum | 74 | #endif |
349 | harbaum | 70 | |
350 | static void | ||
351 | harbaum | 73 | osm_gps_map_osd_render(osm_gps_map_osd_t *osd) { |
352 | osd_priv_t *priv = (osd_priv_t*)osd->priv; | ||
353 | harbaum | 70 | |
354 | /* first fill with transparency */ | ||
355 | harbaum | 73 | cairo_t *cr = cairo_create(priv->overlay); |
356 | harbaum | 70 | cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE); |
357 | cairo_set_source_rgba(cr, 1.0, 0.0, 0.0, 0.0); | ||
358 | cairo_paint(cr); | ||
359 | |||
360 | harbaum | 77 | #ifndef OSD_COLOR |
361 | GdkColor bg = GTK_WIDGET(osd->widget)->style->bg[GTK_STATE_NORMAL]; | ||
362 | GdkColor fg = GTK_WIDGET(osd->widget)->style->fg[GTK_STATE_NORMAL]; | ||
363 | GdkColor da = GTK_WIDGET(osd->widget)->style->fg[GTK_STATE_INSENSITIVE]; | ||
364 | #endif | ||
365 | |||
366 | harbaum | 70 | cairo_set_operator(cr, CAIRO_OPERATOR_OVER); |
367 | |||
368 | /* --------- draw zoom and dpad shape shadow ----------- */ | ||
369 | gint x = 0, y = 0; | ||
370 | |||
371 | harbaum | 74 | #ifdef OSD_SHADOW_ENABLE |
372 | harbaum | 70 | osm_gps_map_osd_zoom_shape(cr, x + OSD_SHADOW, y + OSD_SHADOW); |
373 | osm_gps_map_osd_shape_shadow(cr); | ||
374 | harbaum | 76 | #ifndef OSD_NO_DPAD |
375 | harbaum | 70 | osm_gps_map_osd_dpad_shape(cr, x + OSD_SHADOW, y + OSD_SHADOW); |
376 | osm_gps_map_osd_shape_shadow(cr); | ||
377 | harbaum | 74 | #endif |
378 | harbaum | 76 | #endif |
379 | harbaum | 70 | |
380 | /* --------- draw zoom and dpad shape ----------- */ | ||
381 | |||
382 | osm_gps_map_osd_zoom_shape(cr, x, y); | ||
383 | harbaum | 74 | #ifndef OSD_COLOR |
384 | harbaum | 77 | osm_gps_map_osd_shape(cr, &bg, &fg); |
385 | harbaum | 74 | #else |
386 | harbaum | 70 | osm_gps_map_osd_shape(cr); |
387 | harbaum | 74 | #endif |
388 | harbaum | 76 | #ifndef OSD_NO_DPAD |
389 | harbaum | 70 | osm_gps_map_osd_dpad_shape(cr, x, y); |
390 | harbaum | 74 | #ifndef OSD_COLOR |
391 | harbaum | 77 | osm_gps_map_osd_shape(cr, &bg, &fg); |
392 | harbaum | 74 | #else |
393 | harbaum | 70 | osm_gps_map_osd_shape(cr); |
394 | harbaum | 74 | #endif |
395 | harbaum | 76 | #endif |
396 | harbaum | 70 | |
397 | /* --------- draw zoom and dpad labels --------- */ | ||
398 | |||
399 | harbaum | 74 | #ifdef OSD_SHADOW_ENABLE |
400 | harbaum | 70 | osm_gps_map_osd_zoom_labels(cr, x + OSD_LBL_SHADOW, y + OSD_LBL_SHADOW); |
401 | harbaum | 76 | #ifndef OSD_NO_DPAD |
402 | harbaum | 70 | osm_gps_map_osd_dpad_labels(cr, x + OSD_LBL_SHADOW, y + OSD_LBL_SHADOW); |
403 | harbaum | 76 | #endif |
404 | harbaum | 70 | osm_gps_map_osd_labels_shadow(cr, Z_RAD/3, TRUE); |
405 | harbaum | 76 | #ifdef OSD_GPS_BUTTON |
406 | harbaum | 70 | osm_gps_map_osd_dpad_gps(cr, x + OSD_LBL_SHADOW, y + OSD_LBL_SHADOW); |
407 | harbaum | 73 | osm_gps_map_osd_labels_shadow(cr, Z_RAD/6, osd->cb != NULL); |
408 | harbaum | 74 | #endif |
409 | harbaum | 76 | #endif |
410 | harbaum | 70 | |
411 | osm_gps_map_osd_zoom_labels(cr, x, y); | ||
412 | harbaum | 76 | #ifndef OSD_NO_DPAD |
413 | harbaum | 70 | osm_gps_map_osd_dpad_labels(cr, x, y); |
414 | harbaum | 76 | #endif |
415 | harbaum | 74 | #ifndef OSD_COLOR |
416 | harbaum | 77 | osm_gps_map_osd_labels(cr, Z_RAD/3, TRUE, &fg, &da); |
417 | harbaum | 74 | #else |
418 | harbaum | 70 | osm_gps_map_osd_labels(cr, Z_RAD/3, TRUE); |
419 | harbaum | 74 | #endif |
420 | harbaum | 76 | #ifdef OSD_GPS_BUTTON |
421 | harbaum | 70 | osm_gps_map_osd_dpad_gps(cr, x, y); |
422 | harbaum | 74 | #ifndef OSD_COLOR |
423 | harbaum | 77 | osm_gps_map_osd_labels(cr, Z_RAD/6, osd->cb != NULL, &fg, &da); |
424 | harbaum | 74 | #else |
425 | harbaum | 73 | osm_gps_map_osd_labels(cr, Z_RAD/6, osd->cb != NULL); |
426 | harbaum | 74 | #endif |
427 | harbaum | 76 | #endif |
428 | harbaum | 70 | |
429 | cairo_destroy(cr); | ||
430 | } | ||
431 | |||
432 | static void | ||
433 | harbaum | 75 | osm_gps_map_osd_draw(osm_gps_map_osd_t *osd, GdkDrawable *drawable) |
434 | harbaum | 70 | { |
435 | harbaum | 73 | osd_priv_t *priv = (osd_priv_t*)osd->priv; |
436 | harbaum | 70 | |
437 | /* OSD itself uses some off-screen rendering, so check if the */ | ||
438 | /* offscreen buffer is present and create it if not */ | ||
439 | harbaum | 73 | if(!priv->overlay) { |
440 | harbaum | 70 | /* create overlay ... */ |
441 | harbaum | 73 | priv->overlay = |
442 | harbaum | 70 | cairo_image_surface_create(CAIRO_FORMAT_ARGB32, OSD_W, OSD_H); |
443 | /* ... and render it */ | ||
444 | harbaum | 73 | osm_gps_map_osd_render(osd); |
445 | harbaum | 70 | } |
446 | |||
447 | // now draw this onto the original context | ||
448 | harbaum | 75 | cairo_t *cr = gdk_cairo_create(drawable); |
449 | harbaum | 77 | |
450 | int x = OSD_X, y = OSD_Y; | ||
451 | if(OSD_X < 0) | ||
452 | x = osd->widget->allocation.width - OSD_W + OSD_X; | ||
453 | |||
454 | if(OSD_Y < 0) | ||
455 | y = osd->widget->allocation.height - OSD_H + OSD_Y; | ||
456 | |||
457 | cairo_set_source_surface(cr, priv->overlay, x, y); | ||
458 | harbaum | 70 | cairo_paint(cr); |
459 | cairo_destroy(cr); | ||
460 | } | ||
461 | |||
462 | static void | ||
463 | harbaum | 73 | osm_gps_map_osd_free(osm_gps_map_osd_t *osd) |
464 | harbaum | 70 | { |
465 | harbaum | 73 | osd_priv_t *priv = (osd_priv_t *)(osd->priv); |
466 | harbaum | 70 | |
467 | harbaum | 73 | if (priv->overlay) |
468 | cairo_surface_destroy(priv->overlay); | ||
469 | harbaum | 70 | |
470 | harbaum | 73 | g_free(priv); |
471 | } | ||
472 | |||
473 | static osm_gps_map_osd_t osd_classic = { | ||
474 | .draw = osm_gps_map_osd_draw, | ||
475 | .check = osm_gps_map_osd_check, | ||
476 | .render = osm_gps_map_osd_render, | ||
477 | .free = osm_gps_map_osd_free, | ||
478 | |||
479 | .cb = NULL, | ||
480 | .data = NULL, | ||
481 | |||
482 | .priv = NULL | ||
483 | }; | ||
484 | |||
485 | /* this is the only function that's externally visible */ | ||
486 | void | ||
487 | osm_gps_map_osd_classic_init(OsmGpsMap *map) | ||
488 | { | ||
489 | osd_priv_t *priv = osd_classic.priv = g_new0(osd_priv_t, 1); | ||
490 | |||
491 | osd_classic.priv = priv; | ||
492 | |||
493 | osm_gps_map_register_osd(map, &osd_classic); | ||
494 | } | ||
495 | |||
496 | harbaum | 76 | #ifdef OSD_GPS_BUTTON |
497 | harbaum | 74 | /* below are osd specific functions which aren't used by osm-gps-map */ |
498 | /* but instead are to be used by the main application */ | ||
499 | harbaum | 76 | void osm_gps_map_osd_enable_gps (OsmGpsMap *map, OsmGpsMapOsdCallback cb, |
500 | gpointer data) { | ||
501 | harbaum | 73 | osm_gps_map_osd_t *osd = osm_gps_map_osd_get(map); |
502 | |||
503 | g_return_if_fail (osd); | ||
504 | |||
505 | osd->cb = cb; | ||
506 | osd->data = data; | ||
507 | |||
508 | harbaum | 70 | /* this may have changed the state of the gps button */ |
509 | /* we thus re-render the overlay */ | ||
510 | harbaum | 73 | osd->render(osd); |
511 | harbaum | 70 | |
512 | harbaum | 73 | osm_gps_map_redraw(map); |
513 | harbaum | 70 | } |
514 | harbaum | 76 | #endif |