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