}
static void
+autozoom_action(GtkWidget *w, struct gui_priv *gui, void *dummy)
+{
+ struct attr autozoom_attr;
+
+ autozoom_attr.type = attr_autozoom_active;
+ if (! gtk_toggle_action_get_active(GTK_TOGGLE_ACTION(w))) {
+ autozoom_attr.u.num = 0;
+ } else {
+ autozoom_attr.u.num = 1;
+ }
+
+ navit_set_attr(gui->nav, &autozoom_attr);
+}
+
+static void
cursor_action(GtkWidget *w, struct gui_priv *gui, void *dummy)
{
struct attr attr;
{ "TrackingAction", NULL ,_n("Lock on Road"), NULL, NULL, G_CALLBACK(tracking_action),TRUE },
{ "OrientationAction", "orientation_icon", _n("Northing"), NULL, NULL, G_CALLBACK(orient_north_action),FALSE },
{ "RoadbookAction", GTK_STOCK_JUSTIFY_FILL, _n("Roadbook"), NULL, NULL, G_CALLBACK(roadbook_action), FALSE },
+ { "AutozoomAction", GTK_STOCK_ZOOM_FIT, _n("Autozoom"), NULL, NULL, G_CALLBACK(autozoom_action), FALSE },
#ifdef GTK_STOCK_FULLSCREEN
{ "FullscreenAction",GTK_STOCK_FULLSCREEN, _n("Fullscreen"), NULL, NULL, G_CALLBACK(window_fullscreen_action), FALSE }
#else
<menuitem name=\"Tracking\" action=\"TrackingAction\"/>\
<menuitem name=\"Orientation\" action=\"OrientationAction\"/>\
<menuitem name=\"Roadbook\" action=\"RoadbookAction\"/>\
+ <menuitem name=\"Autozoom\" action=\"AutozoomAction\"/>\
<menuitem name=\"Fullscreen\" action=\"FullscreenAction\"/>\
<menuitem name=\"Quit\" action=\"QuitAction\" />\
<placeholder name=\"RouteMenuAdditions\" />\
<toolitem name=\"Destination\" action=\"DestinationAction\"/>\
<!-- <toolitem name=\"Info\" action=\"InfoAction\"/> -->\
<toolitem name=\"Roadbook\" action=\"RoadbookAction\"/>\
+ <toolitem name=\"Autozoom\" action=\"AutozoomAction\"/>\
<toolitem name=\"Quit\" action=\"QuitAction\"/>\
<separator/>\
</placeholder>\
}
toggle_action = GTK_TOGGLE_ACTION(gtk_action_group_get_action(this->base_group, "RoadbookAction"));
gtk_toggle_action_set_active(toggle_action, 0);
+
+ if (navit_get_attr(this->nav, attr_autozoom_active, &attr, NULL)) {
+ toggle_action = GTK_TOGGLE_ACTION(gtk_action_group_get_action(this->base_group, "AutozoomAction"));
+ gtk_toggle_action_set_active(toggle_action, attr.u.num);
+ }
+
}
static struct menu_priv *
int button_pressed,moved,popped,zoomed;
int center_timeout;
int autozoom_secs;
+ int autozoom_min;
+ int autozoom_active;
struct event_timeout *button_timeout, *motion_timeout;
struct callback *motion_timeout_callback;
int ignore_button;
* zoom level according to the current speed.
*
* @param this_ The navit struct
+ * @param center The "immovable" point - i.e. the vehicles position if we're centering on the vehicle
* @param speed The vehicles speed in meters per second
+ * @param dir The direction into which the vehicle moves
*/
static void
navit_autozoom(struct navit *this_, struct coord *center, int speed, int draw)
{
struct coord c;
struct point pc;
- int distance;
+ int distance,w,h;
+ double new_scale;
long scale;
- double factor;
- if (this_->autozoom_secs <= 0) {
+ if (! this_->autozoom_active) {
return;
}
distance = speed * this_->autozoom_secs;
- if (route_get_path_set(this_->route)) {
- c = route_get_coord_dist(this_->route, distance);
+ transform_get_size(this_->trans, &w, &h);
+ transform(this_->trans, transform_get_projection(this_->trans), center, &pc, 1, 0, 0, NULL);
+ scale = transform_get_scale(this_->trans);
+
+ /* We make shure that the point we want to see is within a certain range
+ * around the vehicle. The radius of this circle is the size of the
+ * screen. This doesn't necessarily mean the point is visible because of
+ * perspective etc. Quite rough, but should be enough. */
+
+ if (w > h) {
+ new_scale = (double)distance / h * 16;
} else {
- return;
+ new_scale = (double)distance / w * 16;
}
- transform(this_->trans, transform_get_projection(this_->trans), center, &pc, 1, 0, 0, NULL);
- factor = transform_get_autozoom_factor(this_->trans, &pc, &c);
+ if (abs(new_scale - scale) < 2) {
+ return; // Smoothing
+ }
- if ((factor < 1.1) && (factor > 0.9)) {
- return;
+ if (new_scale >= this_->autozoom_min) {
+ navit_scale(this_, (long)new_scale, &pc, 0);
+ } else {
+ if (scale != this_->autozoom_min) {
+ navit_scale(this_, this_->autozoom_min, &pc, 0);
+ }
}
-
- scale = transform_get_scale(this_->trans);
- scale = (scale * factor);
-
- navit_scale(this_, scale, &pc, draw);
}
/**
this_->center_timeout = 10;
this_->use_mousewheel = 1;
- this_->autozoom_secs = 0;
+ this_->autozoom_secs = 10;
+ this_->autozoom_min = 7;
+ this_->autozoom_active = 0;
- this_->trans=transform_new();
+ this_->trans = transform_new();
transform_from_geo(pro, &g, &co);
center.x=co.x;
center.y=co.y;
center.pro = pro;
+
transform_setup(this_->trans, ¢er, zoom, (this_->orientation != -1) ? this_->orientation : 0);
for (;*attrs; attrs++) {
navit_set_attr_do(this_, *attrs, 1);
attr_updated=(this_->autozoom_secs != attr->u.num);
this_->autozoom_secs = attr->u.num;
break;
+ case attr_autozoom_active:
+ attr_updated=(this_->autozoom_active != attr->u.num);
+ this_->autozoom_active = attr->u.num;
+ break;
case attr_center:
transform_from_geo(transform_get_projection(this_->trans), attr->u.coord_geo, &co);
dbg(0,"0x%x,0x%x\n",co.x,co.y);
case attr_zoom:
attr->u.num=transform_get_scale(this_->trans);
break;
+ case attr_autozoom_active:
+ attr->u.num=this_->autozoom_active;
+ break;
default:
return 0;
}
case attr_vehicle:
ret=navit_add_vehicle(this_, attr->u.vehicle);
break;
+ case attr_autozoom_min:
+ this_->autozoom_min = attr->u.num;
+ break;
default:
return 0;
}
pnt2=*pnt;
else {
pro=transform_get_projection(this_->trans);
- transform(this_->trans, pro, &nv->coord, &pnt2, 1, 0);
+ transform(this_->trans, pro, &nv->coord, &pnt2, 1);
}
#if 1
cursor_draw(nv->cursor, &pnt2, nv->dir-transform_get_angle(this_->trans, 0), nv->speed > 2, pnt == NULL);
navit_set_center_cursor(this_);
else
navit_vehicle_draw(this_, nv, pnt);
+
if (nv->follow_curr > 1)
nv->follow_curr--;
else
return transform_distance_sq(&l, ref);
}
-double
-transform_get_autozoom_factor(struct transformation *this_, struct point *center, struct coord *c)
-{
- struct point p;
- struct map_selection *ms=this_->screen_sel;
- double fx=0,fy=0,nfx,nfy;
-
- transform(this_, transform_get_projection(this_), c, &p, 1, 0, 0, NULL);
-
- while (ms) {
- struct point_rect *r=&ms->u.p_rect;
- if (p.x > center->x) {
- nfx = (double)(p.x - center->x) / (r->rl.x - center->x);
- } else {
- nfx = (double)(p.x - center->x) / (r->lu.x - center->x);
- }
-
- if (p.y < center->y) {
- nfy = (double)(p.y - center->y) / (double)(r->lu.y - center->y) ;
- } else {
- nfy = (double)(p.y - center->y) / (double)(r->rl.y - center->y);
- }
-
- if ((nfx < fx) || (fx == 0)) {
- fx = nfx;
- }
- if ((nfy < fy) || (fy == 0)) {
- fy = nfy;
- }
-
- ms=ms->next;
- }
-
- return (fy < fx) ? fx : fy;
-}
-
int
transform_distance_polyline_sq(struct coord *c, int count, struct coord *ref, struct coord *lpnt, int *pos)
{