You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
spOSMroute/draw/draw_gui.c

354 lines
11 KiB

/*
* draw_gui.c
* Copyright (C) Steffen Pohle 2011 <steffen@gulpe.de>
*
* main.c is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* main.c is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <sys/time.h>
#include <math.h>
#include "osmroute.h"
#include "draw.h"
#include "map.h"
#include "gps.h"
#include "system.h"
#include "gui.h"
#include "routing.h"
#include "favorites.h"
#include "vector.h"
#include "memoryleak.h"
/*
* mouse variables
*/
iPoint mousepos;
int mousebtn;
time_t mousebtnpresstime;
iPoint mousebtnpresspos = {0.0, 0.0};
struct map_pos mousebtnpressgpos = {0, 0};
int mousebtnpresslongtime = 0;
unsigned long long int mouse_over_way_id = 0;
unsigned short int mouse_over_way_sid = 0;
char mouse_over_way_name[MAP_W_NAMELEN] = "\0";
/*****************************************************************
* draw mouse move
* if btn == -1 mean no button pressed or selected
*/
void draw_mousemove (int x, int y, int btn) {
float lon, lat, lonold, latold;
mousepos.x = x;
mousepos.y = y;
if (mousebtn) {
latold = -map_km2lat(((float)(mousebtnpresspos.y-gfx_screensize.y/2)) * view_scale);
lonold = map_km2lon(((float)(mousebtnpresspos.x-gfx_screensize.x/2)) * view_scale, view_lat + latold);
lat = -map_km2lat(((float)(y-gfx_screensize.y/2)) * view_scale);
lon = map_km2lon(((float)(x-gfx_screensize.x/2)) * view_scale, view_lat + lat);
lat = lat - latold;
lon = lon - lonold;
view_lat = mousebtnpressgpos.lat - lat;
view_lon = mousebtnpressgpos.lon - lon;
draw_del_flag (DRAW_GPSFOLLOW);
}
draw ();
};
void draw_mousebtndown (int x, int y, int btn) {
mousebtnpresstime = time (NULL);
mousebtnpresspos.x = x;
mousebtnpresspos.y = y;
mousebtnpressgpos.lon = view_lon;
mousebtnpressgpos.lat = view_lat;
mousebtn = btn;
mousebtnpresslongtime = 0;
draw ();
};
void draw_mousebtnup (int x, int y, int btn)
{
time_t t = time(NULL);
float lon, lat;
int dx, dy;
if (!mousebtn) return; /* button is no longer pressed */
mousebtn = 0;
/* check for debugging routeing problems */
if (route && y > gfx_screensize.y-32 && y < gfx_screensize.y && x > 0 && x < 100 ) {
view_lon = route->closest_lon;
view_lat = route->closest_lat;
draw_del_flag (DRAW_GPSFOLLOW);
}
else {
lat = -map_km2lat(((float)(y-gfx_screensize.y/2)) * view_scale);
lon = map_km2lon(((float)(x-gfx_screensize.x/2)) * view_scale, view_lat + lat);
dx = abs (mousebtnpresspos.x-x)*100/gfx_screensize.x;
dy = abs (mousebtnpresspos.y-y)*100/gfx_screensize.y;
/* short time button pressing */
d_printf ("released mouse button..");
if (t - mousebtnpresstime <= 1) {
if (dx < 10 && dy < 10) {
if (select_enabled) {
select_enabled = 0;
}
else {
select_enabled = 1;
select_pos.lat = view_lat + lat;
select_pos.lon = view_lon + lon;
}
}
}
else if (mousebtnpresslongtime && dx < 10 && dy < 10) {
/* long time button pressed */
wnd_mapcontext_show ();
}
}
draw ();
};
void draw_mouseloop () {
time_t t = time(NULL);
if (mousebtn && t - mousebtnpresstime > 1) {
mousebtnpresslongtime = 1;
d_printf ("draw_mouseloop: long press..");
draw ();
}
return;
};
void draw_gui () {
struct line_style tmplinestyle;
struct line_style ls;
iPoint p1, p2, center = {gfx_screensize.x/2, gfx_screensize.y/2};
struct map_pos pos;
int n, n1;
float lon, lat;
char text[64];
struct map_hash *mh = NULL;
struct map_way *mw = NULL;
draw_gui_route ();
draw_gui_favorites ();
draw_gui_gps ();
/*
* read current way where the mouse is over at
*/
draw_screen2geo (mousepos.x, mousepos.y, &lon, &lat);
if (app.status == APPSTATUS_nothing) mh = map_hash_get (lon, lat, MHLOAD_RELOAD);
else mh = map_hash_get (lon, lat, MHLOAD_NONE);
pos.lon = lon;
pos.lat = lat;
map_way_findclosest (&pos, NULL, 0, NULL, 0, &mouse_over_way_id, &mouse_over_way_sid);
/*
* our mouse cursor
*/
tmplinestyle.width = 2.0;
if (mousebtnpresslongtime && mousebtn)
tmplinestyle.c = tmplinestyle.borderc = color[COLOR_red][2];
else
tmplinestyle.c = tmplinestyle.borderc = color[COLOR_white][3];
draw_line (NULL, mousepos.x-5, mousepos.y-5, mousepos.x+5, mousepos.y+5, tmplinestyle);
draw_line (NULL, mousepos.x+5, mousepos.y-5, mousepos.x-5, mousepos.y+5, tmplinestyle);
/*
* draw selected position
*/
if (select_enabled) {
p1 = draw_geo2screen (view_lon, view_lat, select_pos.lon, select_pos.lat);
p1.x += center.x;
p1.y += center.y;
tmplinestyle.c = tmplinestyle.borderc = color[COLOR_bluegray][3];
draw_line (NULL, p1.x, p1.y-5, p1.x, p1.y+5, tmplinestyle);
draw_line (NULL, p1.x-5, p1.y, p1.x+5, p1.y, tmplinestyle);
draw_screen2geo (mousepos.x, mousepos.y, &pos.lon, &pos.lat);
lon = map_getdistance (select_pos, pos);
sprintf (text, _("Select Distance:%g"), lon);
gfx_draw_text (NULL, 0, gfx_screensize.y-32, text, &color[COLOR_white][3]);
}
/*
* statusline
*/
if (app.status != APPSTATUS_nothing) {
struct line_style ls;
ls.width = 1.0;
ls.c = ls.borderc = color[COLOR_white][3];
p1.x = gfx_screensize.x/2-101;
p2.x = gfx_screensize.x/2+101;
p1.y = gfx_screensize.y-32;
p2.y = gfx_screensize.y-10;
draw_polygonstart ();
draw_polygonadd (p1.x, p1.y);
draw_polygonadd (p2.x, p1.y);
draw_polygonadd (p2.x, p2.y);
draw_polygonadd (p1.x, p2.y);
draw_polygonfinish (NULL, ls, &color[COLOR_white][0], 1);
p1.x = gfx_screensize.x/2-(float)(100.0*app.statusline_progress);
p2.x = gfx_screensize.x/2+(float)(100.0*app.statusline_progress);
p1.y = gfx_screensize.y-31;
p2.y = gfx_screensize.y-11;
draw_polygonstart ();
draw_polygonadd (p1.x, p1.y);
draw_polygonadd (p2.x, p1.y);
draw_polygonadd (p2.x, p2.y);
draw_polygonadd (p1.x, p2.y);
draw_polygonfinish (NULL, ls, &color[COLOR_blue][3], 0);
gfx_draw_text (NULL, gfx_screensize.x/2-98, p1.y + 2, app.statusline_text, &color[COLOR_white][3]);
}
/*
* draw additional debugging informations
*/
if (view_flags & DRAW_DEBUG) {
struct memoryleak_info mi;
struct map_hash *mh1;
struct map_way *mw1;
iPoint p1, p2;
fPoint nd;
/* draw vorner markings */
ls.width = 1.0;
ls.c = ls.borderc = color[COLOR_pink][2];
p1.x = gfx_screensize.x;
p1.y = gfx_screensize.y;
gfx_draw_line (NULL, 1, 1, 6, 6, ls);
gfx_draw_line (NULL, 1, p1.y-1, 6, p1.y-6, ls);
gfx_draw_line (NULL, p1.x-1, p1.y-1, p1.x-6, p1.y-6, ls);
gfx_draw_line (NULL, p1.x-1, 1, p1.x-6, 6, ls);
/* draw scale */
sprintf (text, "Scale:%g m/px", view_scale * 1000.0);
gfx_draw_text (NULL, 80, 40, text, &color[COLOR_white][3]);
/* memory information */
ml_get_stats (&mi);
sprintf (text, "mem: %d kB [%d]", (int)(mi.size/1024), (int)mi.blocks);
gfx_draw_text (NULL, 80, 56, text, &color[COLOR_white][3]);
/* draw the way */
mw = map_way_find (mh, mouse_over_way_id, mouse_over_way_sid);
if (mw && draw_type[mw->type]) {
/* go through all the nodes */
tmplinestyle.width = 3;
tmplinestyle.c = color[COLOR_pink][2];
for (n = 0; n < mw->p_cnt; n++) {
p2 = p1;
nd.x = map_lon2km (view_lon - mw->p[n].lon, mw->p[n].lat);
nd.y = map_lat2km (view_lat - mw->p[n].lat);
p1.x = center.x - (nd.x / view_scale);
p1.y = center.y + (nd.y / view_scale);
if (n > 0) {
tmplinestyle.width = 3;
tmplinestyle.c = color[COLOR_pink][3];
draw_lineway (NULL, p1.x, p1.y, p2.x, p2.y, tmplinestyle);
}
if (n == 0) {
tmplinestyle.c = color[COLOR_greengray][3];
tmplinestyle.width = 0;
draw_lineway (NULL, p1.x, p1.y-10, p1.x, p1.y+10, tmplinestyle);
draw_lineway (NULL, p1.x+10, p1.y, p1.x-10, p1.y, tmplinestyle);
}
else {
tmplinestyle.c = color[COLOR_green][3];
tmplinestyle.width = 0;
draw_lineway (NULL, p1.x, p1.y-5, p1.x, p1.y+5, tmplinestyle);
draw_lineway (NULL, p1.x+5, p1.y, p1.x-5, p1.y, tmplinestyle);
}
}
/* draw the waynodes and connected way */
for (n = 0; n < mw->n_cnt; n++) if (mw->n[n].pnr < mw->p_cnt) {
p1 = draw_geo2screen (view_lon, view_lat, mw->n[n].d.lon, mw->n[n].d.lat);
p2 = draw_geo2screen (view_lon, view_lat, mw->p[mw->n[n].pnr].lon, mw->p[mw->n[n].pnr].lat);
p1.x += center.x;
p1.y += center.y;
p2.x += center.x;
p2.y += center.y;
tmplinestyle.width = 0;
tmplinestyle.c = color[COLOR_red][3];
draw_lineway (NULL, p1.x, p1.y, p2.x, p2.y, tmplinestyle);
tmplinestyle.width = 0;
tmplinestyle.c = color[COLOR_red][2];
draw_lineway (NULL, p2.x-5, p2.y-5, p2.x+5, p2.y+5, tmplinestyle);
draw_lineway (NULL, p2.x+5, p2.y-5, p2.x-5, p2.y+5, tmplinestyle);
mh1 = map_hash_get (mw->n[n].d.lon, mw->n[n].d.lat, MHLOAD_RELOAD);
mw1 = map_way_find (mh1, mw->n[n].d_id, mw->n[n].d_subid);
if (mw1) {
/* go through all the nodes */
tmplinestyle.width = 3;
tmplinestyle.c = color[COLOR_pink][3];
for (n1 = 0; n1 < mw1->p_cnt; n1++) {
p2 = p1;
nd.x = map_lon2km (view_lon - mw1->p[n1].lon, mw1->p[n1].lat);
nd.y = map_lat2km (view_lat - mw1->p[n1].lat);
p1.x = center.x - (nd.x / view_scale);
p1.y = center.y + (nd.y / view_scale);
if (n1 > 0) {
tmplinestyle.width = 3;
tmplinestyle.c = color[COLOR_pink][1];
draw_lineway (NULL, p1.x, p1.y, p2.x, p2.y, tmplinestyle);
}
}
}
else
d_printf ("can not find way. %g:%g id:%lld subid:%d", mw->n[n].d.lon, mw->n[n].d.lat, mw->n[n].d_id, mw->n[n].d_subid);
}
/* 6displaying informations */
sprintf (text, "name:%s flags:%d type:%d", mw->name, mw->flags, mw->type);
gfx_draw_text (NULL, mousepos.x, mousepos.y-24, text, &color[COLOR_white][3]);
sprintf (text, "len:%g ref:%s", map_way_getlenght (mw, -1, -1), mw->ref);
gfx_draw_text (NULL, mousepos.x, mousepos.y-12, text, &color[COLOR_white][3]);
sprintf (text, "ipos:%d,%d pcnt:%d ncnt:%d", mh->pos.ilon, mh->pos.ilat, mw->p_cnt, mw->n_cnt);
gfx_draw_text (NULL, mousepos.x, mousepos.y-48, text, &color[COLOR_white][3]);
sprintf (text, "pos:%g,%g ipos:%d,%d", mw->p[0].lon, mw->p[0].lat, map_geo2igeo (mw->p[0].lon), map_geo2igeo (mw->p[0].lat));
gfx_draw_text (NULL, mousepos.x, mousepos.y-36, text, &color[COLOR_white][3]);
}
/* highlight way under cursor */
if (mouse_over_way_id != 0) {
sprintf (text, "id:%lld:%d", mouse_over_way_id, mouse_over_way_sid);
gfx_draw_text (NULL, mousepos.x, mousepos.y, text, &color[COLOR_white][3]);
}
}
gui_draw ();
};