tizen 2.4 release
[framework/uifw/elementary.git] / src / lib / elm_route.c
1 #ifdef HAVE_CONFIG_H
2 # include "elementary_config.h"
3 #endif
4
5 #include <Elementary.h>
6
7 #include "elm_priv.h"
8 #include "elm_widget_route.h"
9
10 #define MY_CLASS ELM_ROUTE_CLASS
11
12 #define MY_CLASS_NAME "Elm_Route"
13 #define MY_CLASS_NAME_LEGACY "elm_route"
14
15 static void
16 _clear_route(Evas_Object *obj)
17 {
18    Segment *segment;
19
20    ELM_ROUTE_DATA_GET(obj, sd);
21
22 #ifdef ELM_EMAP
23    sd->lon_min = EMAP_LON_MAX;
24    sd->lon_max = EMAP_LON_MIN;
25    sd->lat_min = EMAP_LAT_MAX;
26    sd->lat_max = EMAP_LAT_MIN;
27 #endif
28
29    EINA_LIST_FREE(sd->segments, segment)
30      {
31         evas_object_del(segment->obj);
32         free(segment);
33      }
34 }
35
36 static void
37 _sizing_eval(Evas_Object *obj)
38 {
39    Eina_List *l;
40    Segment *segment;
41    Evas_Coord x, y, w, h;
42    Evas_Coord start_x, start_y, end_x, end_y;
43
44    ELM_ROUTE_DATA_GET(obj, sd);
45
46    evas_object_geometry_get(obj, &x, &y, &w, &h);
47
48    EINA_LIST_FOREACH(sd->segments, l, segment)
49      {
50         if (sd->must_calc_segments || segment->must_calc)
51           {
52 #ifdef ELM_EMAP
53              segment->start_x =
54                (emap_route_node_lon_get(segment->node_start) - sd->lon_min)
55                / (float)(sd->lon_max - sd->lon_min);
56              segment->start_y =
57                1 - (emap_route_node_lat_get(segment->node_start)
58                     - sd->lat_min) / (float)(sd->lat_max - sd->lat_min);
59              segment->end_x =
60                (emap_route_node_lon_get(segment->node_end) - sd->lon_min)
61                / (float)(sd->lon_max - sd->lon_min);
62              segment->end_y =
63                1 - (emap_route_node_lat_get(segment->node_end)
64                     - sd->lat_min) / (float)(sd->lat_max - sd->lat_min);
65 #endif
66              segment->must_calc = EINA_FALSE;
67           }
68
69         start_x = x + (int)(segment->start_x * w);
70         start_y = y + (int)(segment->start_y * h);
71         end_x = x + (int)(segment->end_x * w);
72         end_y = y + (int)(segment->end_y * h);
73
74         evas_object_line_xy_set(segment->obj, start_x, start_y, end_x, end_y);
75      }
76
77    sd->must_calc_segments = EINA_FALSE;
78 }
79
80 static void
81 _move_resize_cb(void *data EINA_UNUSED,
82                 Evas *e EINA_UNUSED,
83                 Evas_Object *obj,
84                 void *event_info EINA_UNUSED)
85 {
86    _sizing_eval(obj);
87 }
88
89 EOLIAN static Eina_Bool
90 _elm_route_elm_widget_theme_apply(Eo *obj, Elm_Route_Data *sd EINA_UNUSED)
91 {
92    Eina_Bool int_ret = EINA_FALSE;
93    eo_do_super(obj, MY_CLASS, int_ret = elm_obj_widget_theme_apply());
94    if (!int_ret) return EINA_FALSE;
95
96    //TODO
97
98    _sizing_eval(obj);
99
100    return EINA_TRUE;
101 }
102
103 #ifdef ELM_EMAP
104 static void
105 _update_lon_lat_min_max(Evas_Object *obj,
106                         double lon,
107                         double lat)
108 {
109    ELM_ROUTE_DATA_GET(obj, sd);
110
111    if (sd->lon_min > lon)
112      {
113         sd->lon_min = lon;
114         sd->must_calc_segments = EINA_TRUE;
115      }
116    if (sd->lat_min > lat)
117      {
118         sd->lat_min = lat;
119         sd->must_calc_segments = EINA_TRUE;
120      }
121
122    if (sd->lon_max < lon)
123      {
124         sd->lon_max = lon;
125         sd->must_calc_segments = EINA_TRUE;
126      }
127    if (sd->lat_max < lat)
128      {
129         sd->lat_max = lat;
130         sd->must_calc_segments = EINA_TRUE;
131      }
132 }
133
134 #endif
135
136 EOLIAN static void
137 _elm_route_evas_object_smart_add(Eo *obj, Elm_Route_Data *priv)
138 {
139
140    eo_do_super(obj, MY_CLASS, evas_obj_smart_add());
141    elm_widget_sub_object_parent_add(obj);
142    elm_widget_can_focus_set(obj, EINA_FALSE);
143
144    evas_object_event_callback_add
145      (obj, EVAS_CALLBACK_MOVE, _move_resize_cb, obj);
146    evas_object_event_callback_add
147      (obj, EVAS_CALLBACK_RESIZE, _move_resize_cb, obj);
148
149 #ifdef ELM_EMAP
150    priv->lon_min = EMAP_LON_MAX;
151    priv->lon_max = EMAP_LON_MIN;
152    priv->lat_min = EMAP_LAT_MAX;
153    priv->lat_max = EMAP_LAT_MIN;
154 #else
155    (void)priv;
156 #endif
157
158    _sizing_eval(obj);
159 }
160
161 EOLIAN static void
162 _elm_route_evas_object_smart_del(Eo *obj, Elm_Route_Data *_pd EINA_UNUSED)
163 {
164    _clear_route(obj);
165
166    eo_do_super(obj, MY_CLASS, evas_obj_smart_del());
167 }
168
169 /**
170  * Add a new route to the parent
171  *
172  * @param parent The parent object
173  * @return The new object or NULL if it cannot be created
174  *
175  * @ingroup Route
176  */
177 EAPI Evas_Object *
178 elm_route_add(Evas_Object *parent)
179 {
180    EINA_SAFETY_ON_NULL_RETURN_VAL(parent, NULL);
181    Evas_Object *obj = eo_add(MY_CLASS, parent);
182    return obj;
183 }
184
185 EOLIAN static void
186 _elm_route_eo_base_constructor(Eo *obj, Elm_Route_Data *_pd EINA_UNUSED)
187 {
188    eo_do_super(obj, MY_CLASS, eo_constructor());
189    eo_do(obj,
190          evas_obj_type_set(MY_CLASS_NAME_LEGACY));
191 }
192
193 EOLIAN static void
194 _elm_route_emap_set(Eo *obj, Elm_Route_Data *sd, void *_emap)
195 {
196 #ifdef ELM_EMAP
197    EMap_Route *emap = _emap;
198
199    EMap_Route_Node *node, *node_prev = NULL;
200    Evas_Object *o;
201    Eina_List *l;
202
203    sd->emap = emap;
204
205    _clear_route(obj);
206
207    EINA_LIST_FOREACH(emap_route_nodes_get(sd->emap), l, node)
208      {
209         if (node_prev)
210           {
211              Segment *segment = calloc(1, sizeof(Segment));
212
213              segment->node_start = node_prev;
214              segment->node_end = node;
215
216              o = evas_object_line_add(evas_object_evas_get(obj));
217              segment->obj = o;
218              evas_object_smart_member_add(o, obj);
219
220              segment->must_calc = EINA_TRUE;
221
222              _update_lon_lat_min_max
223                (obj, emap_route_node_lon_get(node_prev),
224                emap_route_node_lat_get(node_prev));
225              _update_lon_lat_min_max
226                (obj, emap_route_node_lon_get(node),
227                emap_route_node_lat_get(node));
228
229              sd->segments = eina_list_append(sd->segments, segment);
230           }
231
232         node_prev = node;
233      }
234
235    _sizing_eval(obj);
236 #else
237    (void)obj;
238    (void)sd;
239    (void)_emap;
240 #endif
241 }
242
243 EOLIAN static void
244 _elm_route_longitude_min_max_get(Eo *obj EINA_UNUSED, Elm_Route_Data *sd, double *min, double *max)
245 {
246    if (min) *min = sd->lon_min;
247    if (max) *max = sd->lon_max;
248 }
249
250 EOLIAN static void
251 _elm_route_latitude_min_max_get(Eo *obj EINA_UNUSED, Elm_Route_Data *sd, double *min, double *max)
252 {
253    if (min) *min = sd->lat_min;
254    if (max) *max = sd->lat_max;
255 }
256
257 EOLIAN static void
258 _elm_route_class_constructor(Eo_Class *klass)
259 {
260    evas_smart_legacy_type_register(MY_CLASS_NAME_LEGACY, klass);
261 }
262
263 #include "elm_route.eo.c"