elm: Fixed wrong vim formatting.
[framework/uifw/elementary.git] / src / lib / elm_route.c
1 #include <Elementary.h>
2 #include "elm_priv.h"
3
4 /**
5  * @defgroup Route MapRoute
6  *
7  * For displaying a route on the map widget
8  *
9  */
10
11 typedef struct _Widget_Data Widget_Data;
12 typedef struct Segment Segment;
13
14 struct _Widget_Data
15 {
16    Evas_Object *obj;
17 #ifdef ELM_EMAP
18    EMap_Route *emap;
19 #endif
20
21    double lon_min, lon_max;
22    double lat_min, lat_max;
23
24    Eina_List *segments; //list of *Segment
25
26    Eina_Bool must_calc_segments :1;
27 };
28
29 struct Segment
30 {
31    Evas_Object *obj;
32
33 #ifdef ELM_EMAP
34    EMap_Route_Node *node_start;
35    EMap_Route_Node *node_end;
36 #endif
37
38    double start_x, start_y;
39    double end_x, end_y;
40
41    Eina_Bool must_calc :1;
42 };
43
44 static const char *widtype = NULL;
45 static void _del_hook(Evas_Object *obj);
46 static void _mirrored_set(Evas_Object *obj, Eina_Bool rtl);
47 static void _theme_hook(Evas_Object *obj);
48 static void _sizing_eval(Evas_Object *obj);
49 static void _clear_route(Evas_Object *obj);
50 static void _update_lon_lat_min_max(Evas_Object *obj, double lon, double lat);
51
52 static void
53 _del_hook(Evas_Object *obj)
54 {
55    Evas_Object *segment;
56    Widget_Data *wd = elm_widget_data_get(obj);
57    if (!wd) return;
58
59    _clear_route(obj);
60
61    free(wd);
62 }
63
64 static void
65 _resize_cb(void *data __UNUSED__ , Evas *e __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__)
66 {
67    _sizing_eval(obj);
68 }
69
70 static void
71 _mirrored_set(Evas_Object *obj, Eina_Bool rtl)
72 {
73    Widget_Data *wd = elm_widget_data_get(obj);
74    if (!wd) return;
75 }
76
77 static void
78 _theme_hook(Evas_Object *obj)
79 {
80    Widget_Data *wd = elm_widget_data_get(obj);
81    if (!wd) return;
82   //TODO
83    _sizing_eval(obj);
84 }
85
86 static void
87 _sizing_eval(Evas_Object *obj)
88 {
89    Eina_List *l;
90    Segment *segment;
91    Evas_Coord x, y, w, h;
92    Evas_Coord start_x, start_y, end_x, end_y;
93
94    Widget_Data *wd = elm_widget_data_get(obj);
95    evas_object_geometry_get(obj, &x, &y, &w, &h);
96
97    EINA_LIST_FOREACH(wd->segments, l, segment)
98    {
99       if(wd->must_calc_segments || segment->must_calc)
100       {
101
102 #ifdef ELM_EMAP
103          segment->start_x = (emap_route_node_lon_get(segment->node_start)- wd->lon_min) / (float)(wd->lon_max - wd->lon_min);
104          segment->start_y = 1 - (emap_route_node_lat_get(segment->node_start) - wd->lat_min) / (float)(wd->lat_max - wd->lat_min);
105          segment->end_x = (emap_route_node_lon_get(segment->node_end) - wd->lon_min) / (float)(wd->lon_max - wd->lon_min);
106          segment->end_y = 1 - (emap_route_node_lat_get(segment->node_end) - wd->lat_min) / (float)(wd->lat_max - wd->lat_min);
107 #endif
108          segment->must_calc = EINA_FALSE;
109       }
110
111       start_x = x+(int)(segment->start_x*w);
112       start_y = y+(int)(segment->start_y*h);
113       end_x = x+(int)(segment->end_x*w);
114       end_y = y+(int)(segment->end_y*h);
115       evas_object_line_xy_set(segment->obj, start_x, start_y, end_x, end_y);
116    }
117
118    wd->must_calc_segments = EINA_FALSE;
119 }
120
121 static void
122 _clear_route(Evas_Object *obj)
123 {
124    Segment *segment;
125    Widget_Data *wd = elm_widget_data_get(obj);
126    if (!wd) return;
127
128 #ifdef ELM_EMAP
129    wd->lon_min = EMAP_LON_MAX;
130    wd->lon_max = EMAP_LON_MIN;
131    wd->lat_min = EMAP_LAT_MAX;
132    wd->lat_max = EMAP_LAT_MIN;
133 #endif
134
135    EINA_LIST_FREE(wd->segments, segment)
136    {
137       evas_object_del(segment->obj);
138       free(segment);
139    }
140 }
141
142 static void
143 _update_lon_lat_min_max(Evas_Object *obj, double lon, double lat)
144 {
145    Widget_Data *wd = elm_widget_data_get(obj);
146
147    if(wd->lon_min > lon)
148    {
149       wd->lon_min = lon;
150       wd->must_calc_segments = EINA_TRUE;
151    }
152    if(wd->lat_min > lat)
153    {
154       wd->lat_min = lat;
155       wd->must_calc_segments = EINA_TRUE;
156    }
157
158    if(wd->lon_max < lon)
159    {
160       wd->lon_max = lon;
161       wd->must_calc_segments = EINA_TRUE;
162    }
163    if(wd->lat_max < lat)
164    {
165       wd->lat_max = lat;
166       wd->must_calc_segments = EINA_TRUE;
167    }
168 }
169
170 /**
171  * Add a new route to the parent
172  *
173  * @param parent The parent object
174  * @return The new object or NULL if it cannot be created
175  *
176  * @ingroup Route
177  */
178 EAPI Evas_Object *
179 elm_route_add(Evas_Object *parent)
180 {
181    Evas_Object *obj;
182    Evas *e;
183    Widget_Data *wd;
184    Evas_Object *icon;
185
186    ELM_WIDGET_STANDARD_SETUP(wd, Widget_Data, parent, e, obj, NULL);
187
188    ELM_SET_WIDTYPE(widtype, "map_route");
189    elm_widget_type_set(obj, "map_route");
190    elm_widget_sub_object_add(parent, obj);
191    elm_widget_data_set(obj, wd);
192    elm_widget_del_hook_set(obj, _del_hook);
193    elm_widget_theme_hook_set(obj, _theme_hook);
194    elm_widget_can_focus_set(obj, EINA_FALSE);
195
196    evas_object_event_callback_add(obj, EVAS_CALLBACK_MOVE,
197                                   _resize_cb, obj);
198    evas_object_event_callback_add(obj, EVAS_CALLBACK_RESIZE,
199                                   _resize_cb, obj);
200
201 #ifdef ELM_EMAP
202    wd->lon_min = EMAP_LON_MAX;
203    wd->lon_max = EMAP_LON_MIN;
204    wd->lat_min = EMAP_LAT_MAX;
205    wd->lat_max = EMAP_LAT_MIN;
206 #endif
207
208    _mirrored_set(obj, elm_widget_mirrored_get(obj));
209    _sizing_eval(obj);
210    return obj;
211 }
212
213 #ifdef ELM_EMAP
214 /**
215  * Set the emap object which describes the route
216  *
217  * @param obj The photo object
218  * @param emap the route
219  *
220  * @return (1 = success, 0 = error)
221  *
222  * @ingroup Route
223  */
224 EAPI Eina_Bool
225 elm_route_emap_set(Evas_Object *obj, EMap_Route *emap)
226 {
227    EMap_Route_Node *node, *node_prev = NULL;
228    Evas_Object *o;
229    Eina_List *l;
230
231    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
232    Widget_Data *wd = elm_widget_data_get(obj);
233
234    if (!wd) return EINA_FALSE;
235    wd->emap = emap;
236
237    _clear_route(obj);
238
239    EINA_LIST_FOREACH(emap_route_nodes_get(wd->emap), l, node)
240    {
241       if(node_prev)
242       {
243          Segment *segment = calloc(1, sizeof(Segment));
244          segment->node_start = node_prev;
245          segment->node_end = node;
246
247          o = evas_object_line_add(evas_object_evas_get(obj));
248          segment->obj = o;
249          evas_object_smart_member_add(o, obj);
250          evas_object_show(o);
251
252          segment->must_calc = EINA_TRUE;
253
254          _update_lon_lat_min_max(obj, emap_route_node_lon_get(node_prev), emap_route_node_lat_get(node_prev));
255          _update_lon_lat_min_max(obj, emap_route_node_lon_get(node), emap_route_node_lat_get(node));
256
257          wd->segments = eina_list_append(wd->segments, segment);
258       }
259       node_prev = node;
260    }
261
262    _sizing_eval(obj);
263 }
264 #endif
265
266 EAPI double
267 elm_route_lon_min_get(Evas_Object *obj)
268 {
269    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
270    Widget_Data *wd = elm_widget_data_get(obj);
271    return wd->lon_min;
272 }
273
274 EAPI double
275 elm_route_lat_min_get(Evas_Object *obj)
276 {
277    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
278    Widget_Data *wd = elm_widget_data_get(obj);
279    return wd->lat_min;
280 }
281
282 EAPI double
283 elm_route_lon_max_get(Evas_Object *obj)
284 {
285    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
286    Widget_Data *wd = elm_widget_data_get(obj);
287    return wd->lon_max;
288 }
289
290 EAPI double
291 elm_route_lat_max_get(Evas_Object *obj)
292 {
293    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
294    Widget_Data *wd = elm_widget_data_get(obj);
295    return wd->lat_max;
296 }
297
298 /* vim:set ts=8 sw=3 sts=3 expandtab cino=>5n-3f0^-2{2(0W1st0 :*/