Ticket #648: osd_core.c.odometer.diff

File osd_core.c.odometer.diff, 6.5 KB (added by tegzed, 11 years ago)

Patch to add odometer osd

  • osd_core.c

     
    163163}
    164164
    165165
     166
     167struct odometer {
     168        struct osd_item osd_item;
     169        int width;
     170        struct graphics_gc *orange;
     171        struct graphics_gc *white;
     172        struct callback *click_cb;
     173        char *text;                 //text of label attribute for this osd
     174
     175        int bActive;                //counting or not
     176        double sum_dist;            //sum of distance ofprevious intervals in meters
     177        int sum_time;               //sum of time of previous intervals in seconds (needed for avg spd calculation)
     178        time_t last_click_time;     //time of last click (for double click handling)
     179        time_t last_start_time;     //time of last start of counting
     180        struct coord last_coord;
     181};
     182
     183char* str_replace(char*output, char*input, char*pattern, char*replacement)
     184{
     185  if (!output || !input || !pattern || !replacement) {
     186    return NULL;
     187  }
     188  if(!strcmp(pattern,"")) {
     189    return input;
     190  }
     191
     192  char*pos  = &input[0];
     193  char*pos2 = &input[0];
     194  output[0] = 0;
     195  while ( (pos2=strstr(pos,pattern)) ) {
     196    strncat(output,pos,pos2-pos);
     197    strcat(output,replacement);
     198    pos = pos2 + strlen(pattern);
     199  }
     200  strcat(output,pos);
     201}
     202
     203static void
     204osd_odometer_draw(struct odometer *this, struct navit *nav,
     205                 struct vehicle *v)
     206{
     207  struct coord curr_coord;
     208
     209  char *dist_buffer=0;
     210  char *spd_buffer=0;
     211  struct point p, bbox[4];
     212  struct attr position_attr,vehicle_attr;
     213  enum projection pro;
     214  struct vehicle* curr_vehicle = v;
     215  double spd = 0;
     216
     217  if(nav) {
     218    navit_get_attr(nav, attr_vehicle, &vehicle_attr, NULL);
     219  }
     220  if (vehicle_attr.u.vehicle) {
     221    curr_vehicle = vehicle_attr.u.vehicle;
     222  }
     223
     224  if(0==curr_vehicle)
     225    return;
     226
     227  osd_std_draw(&this->osd_item);
     228  if(this->bActive) {
     229    vehicle_get_attr(curr_vehicle, attr_position_coord_geo,&position_attr, NULL);
     230    pro = projection_mg;//position_attr.u.pcoord->pro;
     231    transform_from_geo(pro, position_attr.u.coord_geo, &curr_coord);
     232
     233    if (this->last_coord.x != -1 ) {
     234        //we have valid previous position
     235        double dCurrDist = 0;
     236        dCurrDist = transform_distance(pro, &curr_coord, &this->last_coord);
     237        this->sum_dist += dCurrDist;
     238        int time_all = time(0)-this->last_click_time+this->sum_time;
     239        spd = 3.6*(double)this->sum_dist/(double)time_all;
     240    }
     241    this->last_coord = curr_coord;
     242  }
     243
     244  char buffer [64+1]="";
     245  char buffer2[64+1]="";
     246  dist_buffer = format_distance(this->sum_dist,"");
     247  spd_buffer = format_speed(spd,"");
     248
     249  buffer [0] = 0;
     250  buffer2[0] = 0;
     251  if(this->text) {
     252    str_replace(buffer2,this->text,"${avg_spd}",spd_buffer);
     253    str_replace(buffer,buffer2,"${distance}",dist_buffer);
     254  }
     255
     256  graphics_get_text_bbox(this->osd_item.gr, this->osd_item.font, buffer, 0x10000, 0, bbox, 0);
     257  p.x=(this->osd_item.w-bbox[2].x)/2;
     258  p.y = this->osd_item.h-this->osd_item.h/10;
     259  struct graphics_gc *curr_color = this->bActive?this->white:this->orange;
     260  graphics_draw_text(this->osd_item.gr, curr_color, NULL, this->osd_item.font, buffer, &p, 0x10000, 0);
     261  g_free(dist_buffer);
     262  g_free(spd_buffer);
     263  graphics_draw_mode(this->osd_item.gr, draw_mode_end);
     264}
     265
     266
     267
     268static void
     269osd_odometer_click(struct odometer *this, struct navit *nav, int pressed, int button, struct point *p)
     270{
     271  struct point bp = this->osd_item.p;
     272  osd_wrap_point(&bp, nav);
     273  if ((p->x < bp.x || p->y < bp.y || p->x > bp.x + this->osd_item.w || p->y > bp.y + this->osd_item.h) && !this->osd_item.pressed)
     274    return;
     275  navit_ignore_button(nav);
     276  if (pressed) { //single click handling
     277    if(this->bActive) { //being stopped
     278      this->last_coord.x = -1;
     279      this->last_coord.y = -1;
     280      this->sum_time += time(0)-this->last_click_time;
     281    }
     282
     283  this->bActive ^= 1;  //toggle active flag
     284
     285  if (this->last_click_time == time(0)) { //double click handling
     286    this->bActive = 0;
     287    this->sum_dist = 0;
     288    this->sum_time = 0;
     289    this->last_start_time = 0;
     290    this->last_coord.x = -1;
     291    this->last_coord.y = -1;
     292  }
     293
     294  this->last_click_time = time(0);
     295
     296  osd_odometer_draw(this, nav,NULL);
     297  }
     298}
     299
     300
     301static void
     302osd_odometer_init(struct odometer *this, struct navit *nav)
     303{
     304        struct color c;
     305
     306        osd_set_std_graphic(nav, &this->osd_item, (struct osd_priv *)this);
     307
     308        this->orange = graphics_gc_new(this->osd_item.gr);
     309        c.r = 0xFFFF;
     310        c.g = 0xA5A5;
     311        c.b = 0x0000;
     312        c.a = 65535;
     313        graphics_gc_set_foreground(this->orange, &c);
     314        graphics_gc_set_linewidth(this->orange, this->width);
     315
     316        this->white = graphics_gc_new(this->osd_item.gr);
     317        c.r = 65535;
     318        c.g = 65535;
     319        c.b = 65535;
     320        c.a = 65535;
     321        graphics_gc_set_foreground(this->white, &c);
     322        graphics_gc_set_linewidth(this->white, this->width);
     323
     324        graphics_gc_set_linewidth(this->osd_item.graphic_fg_white, this->width);
     325
     326    this->last_coord.x = -1;
     327    this->last_coord.y = -1;
     328    this->sum_dist = 0.0;
     329
     330        navit_add_callback(nav, callback_new_attr_1(callback_cast(osd_odometer_draw), attr_position_coord_geo, this));
     331
     332        navit_add_callback(nav, this->click_cb = callback_new_attr_1(callback_cast (osd_odometer_click), attr_button, this));
     333
     334        osd_odometer_draw(this, nav, NULL);
     335}
     336
     337static struct osd_priv *
     338osd_odometer_new(struct navit *nav, struct osd_methods *meth,
     339                struct attr **attrs)
     340{
     341        struct odometer *this = g_new0(struct odometer, 1);
     342        struct attr *attr;
     343        this->osd_item.p.x = 120;
     344        this->osd_item.p.y = 20;
     345        this->osd_item.w = 60;
     346        this->osd_item.h = 80;
     347        this->osd_item.navit = nav;
     348        this->osd_item.font_size = 200;
     349        this->osd_item.meth.draw = osd_draw_cast(osd_odometer_draw);
     350
     351        this->bActive = 0; //do not count on init
     352        this->sum_dist = 0;
     353        this->last_click_time = time(0);
     354        this->last_coord.x = -1;
     355        this->last_coord.y = -1;
     356
     357
     358        attr = attr_search(attrs, NULL, attr_label);
     359        //FIXME find some way to free text!!!!
     360        if (attr) {
     361                this->text = g_strdup(attr->u.str);
     362        }
     363        else
     364                this->text = NULL;
     365
     366
     367
     368        osd_set_std_attr(attrs, &this->osd_item, 2);
     369        attr = attr_search(attrs, NULL, attr_width);
     370        this->width=attr ? attr->u.num : 2;
     371        navit_add_callback(nav, callback_new_attr_1(callback_cast(osd_odometer_init), attr_graphics_ready, this));
     372        return (struct osd_priv *) this;
     373}
     374
     375
     376
     377
    166378struct stopwatch {
    167379        struct osd_item osd_item;
    168380        int width;
     
    18532065        plugin_register_osd_type("scale", osd_scale_new);
    18542066                plugin_register_osd_type("image", osd_image_new);
    18552067                plugin_register_osd_type("stopwatch", osd_stopwatch_new);
     2068        plugin_register_osd_type("odometer", osd_odometer_new);
    18562069}