Fix:Core:Fixed win32 build
[navit-package] / navit / cursor.c
1 /**
2  * Navit, a modular navigation system.
3  * Copyright (C) 2005-2008 Navit Team
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License
7  * version 2 as published by the Free Software Foundation.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the
16  * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17  * Boston, MA  02110-1301, USA.
18  */
19
20 #include <stdio.h>
21 #include <stdlib.h>
22 #include <string.h>
23 #include <unistd.h>
24 #include <fcntl.h>
25 #include <math.h>
26 #include <glib.h>
27 #include "debug.h"
28 #include "coord.h"
29 #include "transform.h"
30 #include "projection.h"
31 #include "point.h"
32 #include "graphics.h"
33 #include "vehicle.h"
34 #include "navit.h"
35 #include "callback.h"
36 #include "color.h"
37 #include "cursor.h"
38 #include "compass.h"
39 #include "item.h"
40 #include "layout.h"
41 #include "event.h"
42 /* #include "track.h" */
43
44
45 struct cursor {
46         int w,h;
47         struct graphics *gra;
48         struct callback *animate_callback;
49         struct event_timeout *animate_timer;    
50         struct point cursor_pnt;
51         struct graphics_gc *bg;
52         struct attr **attrs;
53         struct transformation *trans;
54         int sequence;
55         int angle;
56         int speed;
57 };
58
59
60
61 static void
62 cursor_draw_do(struct cursor *this_, int lazy)
63 {
64         struct point p;
65         int speed=this_->speed;
66         int angle=this_->angle;
67
68         if (!this_->attrs || !this_->gra)
69                 return;
70         if (!this_->gra)
71                 return;
72         transform_set_yaw(this_->trans, -this_->angle);
73         graphics_draw_mode(this_->gra, draw_mode_begin);
74         p.x=0;
75         p.y=0;
76         graphics_draw_rectangle(this_->gra, this_->bg, &p, this_->w, this_->h);
77         for (;;) {
78                 struct attr **attr=this_->attrs;
79                 int sequence=this_->sequence;
80                 int match=0;
81                 while (*attr) {
82                         if ((*attr)->type == attr_itemgra) {
83                                 struct itemgra *itm=(*attr)->u.itemgra;
84                                 dbg(1,"speed %d-%d %d\n", itm->speed_range.min, itm->speed_range.max, speed);
85                                 if (speed >= itm->speed_range.min && speed <= itm->speed_range.max &&  
86                                     angle >= itm->angle_range.min && angle <= itm->angle_range.max &&  
87                                     sequence >= itm->sequence_range.min && sequence <= itm->sequence_range.max) {
88                                         graphics_draw_itemgra(this_->gra, itm, this_->trans);
89                                         match=1;
90                                 }
91                         }
92                         attr++;
93                 }
94                 if (match) {
95                         break;
96                 } else {
97                         if (this_->sequence) 
98                                 this_->sequence=0;
99                         else
100                                 break;
101                 }
102         }
103         graphics_draw_drag(this_->gra, &this_->cursor_pnt);
104         graphics_draw_mode(this_->gra, lazy ? draw_mode_end_lazy : draw_mode_end);
105 }
106
107 void
108 cursor_draw(struct cursor *this_, struct graphics *gra, struct point *pnt, int lazy, int angle, int speed)
109 {
110         if (angle < 0)
111                 angle+=360;
112         dbg(1,"enter this=%p gra=%p pnt=%p lazy=%d dir=%d speed=%d\n", this_, gra, pnt, lazy, angle, speed);
113         dbg(1,"point %d,%d\n", pnt->x, pnt->y);
114         this_->cursor_pnt=*pnt;
115         this_->cursor_pnt.x-=this_->w/2;
116         this_->cursor_pnt.y-=this_->h/2;
117         this_->angle=angle;
118         this_->speed=speed;
119         if (!this_->gra) {
120                 struct color c;
121                 this_->gra=graphics_overlay_new(gra, &this_->cursor_pnt, this_->w, this_->h, 65535, 0);
122                 if (this_->gra) {
123                         this_->bg=graphics_gc_new(this_->gra);
124                         c.r=0; c.g=0; c.b=0; c.a=0;
125                         graphics_gc_set_foreground(this_->bg, &c);
126                         graphics_background_gc(this_->gra, this_->bg);
127                 }
128         }
129         cursor_draw_do(this_, lazy);
130 }
131
132 static void
133 cursor_animate(struct cursor * this)
134 {
135         this->sequence++;
136         cursor_draw_do(this, 0);
137 }
138
139 int
140 cursor_add_attr(struct cursor *this_, struct attr *attr)
141 {
142         int ret=1;
143         switch (attr->type) {
144         case attr_itemgra:
145                 break;
146         default:
147                 ret=0;
148         }
149         if (ret)
150                 this_->attrs=attr_generic_add_attr(this_->attrs, attr);
151         return ret;
152 }
153
154 struct cursor *
155 cursor_new(struct attr *parent, struct attr **attrs)
156 {
157         struct cursor *this=g_new0(struct cursor,1);
158         struct attr *w,*h, *interval;
159         struct pcoord center;
160         struct point scenter;
161         w=attr_search(attrs, NULL, attr_w);
162         h=attr_search(attrs, NULL, attr_h);
163         if (! w || ! h)
164                 return NULL;
165
166         this->w=w->u.num;
167         this->h=h->u.num;
168         this->trans=transform_new();
169         center.pro=projection_screen;
170         center.x=0;
171         center.y=0;
172         transform_setup(this->trans, &center, 16, 0);
173         scenter.x=this->w/2;
174         scenter.y=this->h/2;
175         transform_set_screen_center(this->trans, &scenter);
176         interval=attr_search(attrs, NULL, attr_interval);
177         if (interval) {
178                 this->animate_callback=callback_new_1(callback_cast(cursor_animate), this);
179                 this->animate_timer=event_add_timeout(interval->u.num, 1, this->animate_callback);
180         }
181         dbg(2,"ret=%p\n", this);
182         return this;
183 }
184
185 void
186 cursor_destroy(struct cursor *this_)
187 {
188         if (this_->animate_callback) {
189                 callback_destroy(this_->animate_callback);
190                 event_remove_timeout(this_->animate_timer);
191         }
192         transform_destroy(this_->trans);
193         g_free(this_);
194 }