Diff of /trunk/src/osm-gps-map-osd-classic.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 86 by harbaum, Sun Aug 30 19:05:44 2009 UTC revision 88 by harbaum, Mon Aug 31 14:22:28 2009 UTC
# Line 19  Line 19 
19    
20  #include "config.h"  #include "config.h"
21  #include <stdlib.h>  // abs  #include <stdlib.h>  // abs
22  #include <math.h>    // M_PI  #include <math.h>    // M_PI/cos()
   
 #define OSD_SOURCE_SEL  
   
 #define OSD_Y  (-10)  
23    
24  /* parameters that can be overwritten from the config file: */  /* parameters that can be overwritten from the config file: */
25  /* OSD_DIAMETER */  /* OSD_DIAMETER */
# Line 43  typedef struct { Line 39  typedef struct {
39      /* the offscreen representation of the OSD */      /* the offscreen representation of the OSD */
40      cairo_surface_t *overlay;      cairo_surface_t *overlay;
41    
42    #ifdef OSD_SOURCE_SEL
43        /* values to handle the "source" menu */
44      cairo_surface_t *map_source;      cairo_surface_t *map_source;
45      gboolean expanded;      gboolean expanded;
46      gint shift, dir, count;      gint shift, dir, count;
47      gint handler_id;      gint handler_id;
48        gint width, height;
49    #endif
50    
51  } osd_priv_t;  } osd_priv_t;
52    
53  /* position and extent of bounding box */  /* position and extent of bounding box */
# Line 128  osd_labels(cairo_t *cr, gint width, gboo Line 129  osd_labels(cairo_t *cr, gint width, gboo
129      if(enabled)  gdk_cairo_set_source_color(cr, fg);      if(enabled)  gdk_cairo_set_source_color(cr, fg);
130      else         gdk_cairo_set_source_color(cr, disabled);      else         gdk_cairo_set_source_color(cr, disabled);
131      cairo_set_line_width (cr, width);      cairo_set_line_width (cr, width);
     cairo_stroke (cr);  
132  }  }
133  #else  #else
134  static void  static void
# Line 136  osd_labels(cairo_t *cr, gint width, gboo Line 136  osd_labels(cairo_t *cr, gint width, gboo
136      if(enabled)  cairo_set_source_rgb (cr, OSD_COLOR);      if(enabled)  cairo_set_source_rgb (cr, OSD_COLOR);
137      else         cairo_set_source_rgb (cr, OSD_COLOR_DISABLED);      else         cairo_set_source_rgb (cr, OSD_COLOR_DISABLED);
138      cairo_set_line_width (cr, width);      cairo_set_line_width (cr, width);
     cairo_stroke (cr);  
139  }  }
140  #endif  #endif
141    
# Line 145  static void Line 144  static void
144  osd_labels_shadow(cairo_t *cr, gint width, gboolean enabled) {  osd_labels_shadow(cairo_t *cr, gint width, gboolean enabled) {
145      cairo_set_source_rgba (cr, 0, 0, 0, enabled?0.3:0.15);      cairo_set_source_rgba (cr, 0, 0, 0, enabled?0.3:0.15);
146      cairo_set_line_width (cr, width);      cairo_set_line_width (cr, width);
     cairo_stroke (cr);  
147  }  }
148  #endif  #endif
149    
# Line 262  osd_check_zoom(gint x, gint y) { Line 260  osd_check_zoom(gint x, gint y) {
260      return OSD_NONE;      return OSD_NONE;
261  }  }
262    
263    #ifdef OSD_SOURCE_SEL
264    
265  /* place source selection at right border */  /* place source selection at right border */
266  #define OSD_S_RAD (Z_RAD)  #define OSD_S_RAD (Z_RAD)
267  #define OSD_S_X   (-OSD_X)  #define OSD_S_X   (-OSD_X)
# Line 271  osd_check_zoom(gint x, gint y) { Line 271  osd_check_zoom(gint x, gint y) {
271  #define OSD_S_PH  (2 * Z_RAD)  #define OSD_S_PH  (2 * Z_RAD)
272  #define OSD_S_H   (OSD_S_PH + OSD_SHADOW)  #define OSD_S_H   (OSD_S_PH + OSD_SHADOW)
273    
274  /* size of usable area when exapnded */  /* size of usable area when expanded */
275  #define OSD_S_AREA_W (200)  #define OSD_S_AREA_W (priv->width)
276  #define OSD_S_AREA_H (200)  #define OSD_S_AREA_H (priv->height)
277  #define OSD_S_EXP_W  (OSD_S_PW + OSD_S_AREA_W + OSD_SHADOW)  #define OSD_S_EXP_W  (OSD_S_PW + OSD_S_AREA_W + OSD_SHADOW)
278  #define OSD_S_EXP_H  (OSD_S_AREA_H + OSD_SHADOW)  #define OSD_S_EXP_H  (OSD_S_AREA_H + OSD_SHADOW)
279    
280  /* internal value to draw the arrow on the "puller" */  /* internal value to draw the arrow on the "puller" */
281  #define OSD_S_D0  (OSD_S_RAD/2)  #define OSD_S_D0  (OSD_S_RAD/2)
282    #ifndef OSD_FONT_SIZE
283    #define OSD_FONT_SIZE 16.0
284    #endif
285    #define OSD_TEXT_BORDER   (OSD_FONT_SIZE/2)
286    #define OSD_TEXT_SKIP     (OSD_FONT_SIZE/8)
287    
288    /* draw the shape of the source selection OSD, either only the puller (not expanded) */
289    /* or the entire menu incl. the puller (expanded) */
290  static void  static void
291  osd_source_shape(osd_priv_t *priv, cairo_t *cr, gint x, gint y) {  osd_source_shape(osd_priv_t *priv, cairo_t *cr, gint x, gint y) {
292      if(!priv->expanded) {      if(!priv->expanded) {
# Line 305  osd_source_shape(osd_priv_t *priv, cairo Line 312  osd_source_shape(osd_priv_t *priv, cairo
312  }  }
313    
314  static void  static void
315  osd_source_content(osd_priv_t *priv, cairo_t *cr, gint x, gint y) {  osd_source_content(osm_gps_map_osd_t *osd, cairo_t *cr, gint offset) {
316      y += OSD_S_RAD - OSD_S_D0;      osd_priv_t *priv = (osd_priv_t*)osd->priv;
317    
318        int py = offset + OSD_S_RAD - OSD_S_D0;
319    
320      if(!priv->expanded) {      if(!priv->expanded) {
321          /* draw the "puller" open (<) arrow */          /* draw the "puller" open (<) arrow */
322          cairo_move_to (cr, x + OSD_S_RAD + OSD_S_D0/2, y);          cairo_move_to (cr, offset + OSD_S_RAD + OSD_S_D0/2, py);
323          cairo_rel_line_to (cr, -OSD_S_D0, +OSD_S_D0);          cairo_rel_line_to (cr, -OSD_S_D0, +OSD_S_D0);
324          cairo_rel_line_to (cr, +OSD_S_D0, +OSD_S_D0);          cairo_rel_line_to (cr, +OSD_S_D0, +OSD_S_D0);
325      } else {      } else {
326          if(OSD_S_Y < 0)          if(OSD_S_Y < 0)
327              y += OSD_S_AREA_H - OSD_S_PH;              py += OSD_S_AREA_H - OSD_S_PH;
328    
329          /* draw the "puller" close (>) arrow */          /* draw the "puller" close (>) arrow */
330          cairo_move_to (cr, x + OSD_S_RAD - OSD_S_D0/2, y);          cairo_move_to (cr, offset + OSD_S_RAD - OSD_S_D0/2, py);
331          cairo_rel_line_to (cr, +OSD_S_D0, +OSD_S_D0);          cairo_rel_line_to (cr, +OSD_S_D0, +OSD_S_D0);
332          cairo_rel_line_to (cr, -OSD_S_D0, +OSD_S_D0);          cairo_rel_line_to (cr, -OSD_S_D0, +OSD_S_D0);
333            cairo_stroke(cr);
334    
335            /* don't draw a shadow for the text content */
336            if(offset == 1) {
337                gint source;
338                g_object_get(osd->widget, "map-source", &source, NULL);
339    
340                cairo_select_font_face (cr, "Sans",
341                                        CAIRO_FONT_SLANT_NORMAL,
342                                        CAIRO_FONT_WEIGHT_BOLD);
343                cairo_set_font_size (cr, OSD_FONT_SIZE);
344    
345                int i, step = (priv->height - 2*OSD_TEXT_BORDER)
346                    / OSM_GPS_MAP_SOURCE_LAST;
347                for(i=OSM_GPS_MAP_SOURCE_NULL+1;i<=OSM_GPS_MAP_SOURCE_LAST;i++) {
348                    cairo_text_extents_t extents;
349                    const char *src = osm_gps_map_source_get_friendly_name(i);
350                    cairo_text_extents (cr, src, &extents);
351    
352                    int x = offset + OSD_S_PW + OSD_TEXT_BORDER;
353                    int y = offset + step * (i-1) + OSD_TEXT_BORDER;
354    
355                    /* draw filled rectangle if selected */
356                    if(source == i) {
357                        cairo_rectangle(cr, x - OSD_TEXT_BORDER/2,
358                                        y - OSD_TEXT_SKIP,
359                                        priv->width - OSD_TEXT_BORDER,
360                                        step + OSD_TEXT_SKIP);
361                        cairo_fill(cr);
362    
363                        /* temprarily draw with background color */
364    #ifndef OSD_COLOR
365                        GdkColor bg = osd->widget->style->bg[GTK_STATE_NORMAL];
366                        gdk_cairo_set_source_color(cr, &bg);
367    #else
368                        cairo_set_source_rgb (cr, OSD_COLOR_BG);
369    #endif
370                    }
371    
372                    cairo_move_to (cr, x, y + OSD_TEXT_SKIP - extents.y_bearing);
373                    cairo_show_text (cr, src);
374    
375                    /* restore color */
376                    if(source == i) {
377    #ifndef OSD_COLOR
378                        GdkColor fg = osd->widget->style->fg[GTK_STATE_NORMAL];
379                        gdk_cairo_set_source_color(cr, &fg);
380    #else
381                        cairo_set_source_rgb (cr, OSD_COLOR);
382    #endif
383                    }
384                }
385            }
386      }      }
387  }  }
388    
# Line 354  osd_render_source_sel(osm_gps_map_osd_t Line 416  osd_render_source_sel(osm_gps_map_osd_t
416  #endif  #endif
417    
418  #ifdef OSD_SHADOW_ENABLE  #ifdef OSD_SHADOW_ENABLE
     osd_source_content(priv, cr, 1+OSD_LBL_SHADOW, 1+OSD_LBL_SHADOW);  
419      osd_labels_shadow(cr, Z_RAD/3, TRUE);      osd_labels_shadow(cr, Z_RAD/3, TRUE);
420        osd_source_content(osd, cr, 1+OSD_LBL_SHADOW);
421        cairo_stroke (cr);
422  #endif  #endif
     osd_source_content(priv, cr, 1, 1);  
423  #ifndef OSD_COLOR  #ifndef OSD_COLOR
424      osd_labels(cr, Z_RAD/3, TRUE, &fg, &da);      osd_labels(cr, Z_RAD/3, TRUE, &fg, &da);
425  #else  #else
426      osd_labels(cr, Z_RAD/3, TRUE);      osd_labels(cr, Z_RAD/3, TRUE);
427  #endif  #endif
428        osd_source_content(osd, cr, 1);
429        cairo_stroke (cr);
430    
431      cairo_destroy(cr);      cairo_destroy(cr);
432  }  }
# Line 373  osd_source_reallocate(osm_gps_map_osd_t Line 437  osd_source_reallocate(osm_gps_map_osd_t
437    
438      /* re-allocate offscreen bitmap */      /* re-allocate offscreen bitmap */
439      g_assert (priv->map_source);      g_assert (priv->map_source);
     cairo_surface_destroy(priv->map_source);  
440    
441      int w = OSD_S_W, h = OSD_S_H;      int w = OSD_S_W, h = OSD_S_H;
442      if(priv->expanded) {      if(priv->expanded) {
443            /* ... and right of it the waypoint id */
444            cairo_text_extents_t extents;
445    
446            /* determine content size */
447            cairo_t *cr = cairo_create(priv->map_source);
448            cairo_select_font_face (cr, "Sans",
449                                    CAIRO_FONT_SLANT_NORMAL,
450                                    CAIRO_FONT_WEIGHT_BOLD);
451            cairo_set_font_size (cr, OSD_FONT_SIZE);
452    
453            /* calculate menu size */
454            int i, max_h = 0, max_w = 0;
455            for(i=OSM_GPS_MAP_SOURCE_NULL+1;i<=OSM_GPS_MAP_SOURCE_LAST;i++) {
456                const char *src = osm_gps_map_source_get_friendly_name(i);
457                cairo_text_extents (cr, src, &extents);
458    
459                //            printf("Source %d: %s = %f %f\n", i, src,
460                //                   extents.width, extents.height);
461    
462                if(extents.width > max_w) max_w = extents.width;
463                if(extents.height > max_h) max_h = extents.height;
464            }
465            cairo_destroy(cr);
466    
467            priv->width  = max_w + 2*OSD_TEXT_BORDER;
468            priv->height = OSM_GPS_MAP_SOURCE_LAST *
469                (max_h + 2*OSD_TEXT_SKIP) + 2*OSD_TEXT_BORDER;
470    
471          w = OSD_S_EXP_W;          w = OSD_S_EXP_W;
472          h = OSD_S_EXP_H;          h = OSD_S_EXP_H;
473      }      }
474    
475        cairo_surface_destroy(priv->map_source);
476      priv->map_source =      priv->map_source =
477          cairo_image_surface_create(CAIRO_FORMAT_ARGB32, w+2, h+2);          cairo_image_surface_create(CAIRO_FORMAT_ARGB32, w+2, h+2);
478    
# Line 389  osd_source_reallocate(osm_gps_map_osd_t Line 481  osd_source_reallocate(osm_gps_map_osd_t
481  }  }
482    
483  #define OSD_HZ      15  #define OSD_HZ      15
484  #define OSD_TIME    1000  #define OSD_TIME    500
485    
486  static gboolean osd_source_animate(gpointer data) {  static gboolean osd_source_animate(gpointer data) {
487      osm_gps_map_osd_t *osd = (osm_gps_map_osd_t*)data;      osm_gps_map_osd_t *osd = (osm_gps_map_osd_t*)data;
# Line 487  osd_source_check(osm_gps_map_osd_t *osd, Line 579  osd_source_check(osm_gps_map_osd_t *osd,
579              return OSD_BG;              return OSD_BG;
580          }          }
581      }      }
582    
583        /* check for clicks into data area */
584        if(priv->expanded) {
585            if(x > OSD_S_PW &&
586               x < OSD_S_PW + OSD_S_EXP_W &&
587               y > 0 &&
588               y < OSD_S_EXP_H) {
589    
590                printf("in OSD source menu area\n");
591    
592                return OSD_BG;
593            }
594        }
595    
596      return OSD_NONE;      return OSD_NONE;
597  }  }
598    #endif // OSD_SOURCE_SEL
599    
600  static osd_button_t  static osd_button_t
601  osd_check(osm_gps_map_osd_t *osd, gint x, gint y) {  osd_check(osm_gps_map_osd_t *osd, gint x, gint y) {
# Line 641  osd_render(osm_gps_map_osd_t *osd) { Line 748  osd_render(osm_gps_map_osd_t *osd) {
748      /* --------- draw zoom and dpad labels --------- */      /* --------- draw zoom and dpad labels --------- */
749    
750  #ifdef OSD_SHADOW_ENABLE  #ifdef OSD_SHADOW_ENABLE
751        osd_labels_shadow(cr, Z_RAD/3, TRUE);
752      osd_zoom_labels(cr, 1+OSD_LBL_SHADOW, 1+OSD_LBL_SHADOW);      osd_zoom_labels(cr, 1+OSD_LBL_SHADOW, 1+OSD_LBL_SHADOW);
753  #ifndef OSD_NO_DPAD  #ifndef OSD_NO_DPAD
754      osd_dpad_labels(cr, 1+OSD_LBL_SHADOW, 1+OSD_LBL_SHADOW);      osd_dpad_labels(cr, 1+OSD_LBL_SHADOW, 1+OSD_LBL_SHADOW);
755  #endif  #endif
756      osd_labels_shadow(cr, Z_RAD/3, TRUE);      cairo_stroke(cr);
757  #ifdef OSD_GPS_BUTTON  #ifdef OSD_GPS_BUTTON
     osd_dpad_gps(cr, 1+OSD_LBL_SHADOW, 1+OSD_LBL_SHADOW);  
758      osd_labels_shadow(cr, Z_RAD/6, osd->cb != NULL);      osd_labels_shadow(cr, Z_RAD/6, osd->cb != NULL);
759        osd_dpad_gps(cr, 1+OSD_LBL_SHADOW, 1+OSD_LBL_SHADOW);
760        cairo_stroke(cr);
761  #endif  #endif
762  #endif  #endif
763    
     osd_zoom_labels(cr, 1, 1);  
 #ifndef OSD_NO_DPAD  
     osd_dpad_labels(cr, 1, 1);  
 #endif  
764  #ifndef OSD_COLOR  #ifndef OSD_COLOR
765      osd_labels(cr, Z_RAD/3, TRUE, &fg, &da);      osd_labels(cr, Z_RAD/3, TRUE, &fg, &da);
766  #else  #else
767      osd_labels(cr, Z_RAD/3, TRUE);      osd_labels(cr, Z_RAD/3, TRUE);
768  #endif  #endif
769  #ifdef OSD_GPS_BUTTON      osd_zoom_labels(cr, 1, 1);
770      osd_dpad_gps(cr, 1, 1);  #ifndef OSD_NO_DPAD
771        osd_dpad_labels(cr, 1, 1);
772    #endif
773        cairo_stroke(cr);
774    
775  #ifndef OSD_COLOR  #ifndef OSD_COLOR
776      osd_labels(cr, Z_RAD/6, osd->cb != NULL, &fg, &da);      osd_labels(cr, Z_RAD/6, osd->cb != NULL, &fg, &da);
777  #else  #else
778      osd_labels(cr, Z_RAD/6, osd->cb != NULL);      osd_labels(cr, Z_RAD/6, osd->cb != NULL);
779  #endif  #endif
780    #ifdef OSD_GPS_BUTTON
781        osd_dpad_gps(cr, 1, 1);
782  #endif  #endif
783        cairo_stroke(cr);
784    
785      cairo_destroy(cr);      cairo_destroy(cr);
786    
787    #ifdef OSD_SOURCE_SEL
788      osd_render_source_sel(osd);      osd_render_source_sel(osd);
789    #endif
790  }  }
791    
792  static void  static void
# Line 687  osd_draw(osm_gps_map_osd_t *osd, GdkDraw Line 801  osd_draw(osm_gps_map_osd_t *osd, GdkDraw
801          priv->overlay =          priv->overlay =
802              cairo_image_surface_create(CAIRO_FORMAT_ARGB32, OSD_W+2, OSD_H+2);              cairo_image_surface_create(CAIRO_FORMAT_ARGB32, OSD_W+2, OSD_H+2);
803    
804    #ifdef OSD_SOURCE_SEL
805          /* the initial OSD state is alway not-expanded */          /* the initial OSD state is alway not-expanded */
806          priv->map_source =          priv->map_source =
807              cairo_image_surface_create(CAIRO_FORMAT_ARGB32,              cairo_image_surface_create(CAIRO_FORMAT_ARGB32,
808                                             OSD_S_W+2, OSD_S_H+2);                                             OSD_S_W+2, OSD_S_H+2);
809    #endif
810    
811          /* ... and render it */          /* ... and render it */
812          osd_render(osd);          osd_render(osd);
# Line 739  osd_free(osm_gps_map_osd_t *osd) Line 855  osd_free(osm_gps_map_osd_t *osd)
855  {  {
856      osd_priv_t *priv = (osd_priv_t *)(osd->priv);      osd_priv_t *priv = (osd_priv_t *)(osd->priv);
857    
     if(priv->handler_id)  
         gtk_timeout_remove(priv->handler_id);  
   
858      if (priv->overlay)      if (priv->overlay)
859           cairo_surface_destroy(priv->overlay);           cairo_surface_destroy(priv->overlay);
860    
861    #ifdef OSD_SOURCE_SEL
862        if(priv->handler_id)
863            gtk_timeout_remove(priv->handler_id);
864    
865      if (priv->map_source)      if (priv->map_source)
866           cairo_surface_destroy(priv->map_source);           cairo_surface_destroy(priv->map_source);
867    #endif
868    
869      g_free(priv);      g_free(priv);
870  }  }
871    
872    static gboolean
873    osd_busy(osm_gps_map_osd_t *osd)
874    {
875    #ifdef OSD_SOURCE_SEL
876        osd_priv_t *priv = (osd_priv_t *)(osd->priv);
877        return (priv->handler_id != 0);
878    #else
879        return FALSE;
880    #endif
881    }
882    
883  static osm_gps_map_osd_t osd_classic = {  static osm_gps_map_osd_t osd_classic = {
884        .widget     = NULL,
885    
886      .draw       = osd_draw,      .draw       = osd_draw,
887      .check      = osd_check,      .check      = osd_check,
888      .render     = osd_render,      .render     = osd_render,
889      .free       = osd_free,      .free       = osd_free,
890        .busy       = osd_busy,
891    
892      .cb         = NULL,      .cb         = NULL,
893      .data       = NULL,      .data       = NULL,

Legend:
Removed from v.86  
changed lines
  Added in v.88