2e71df44807686cfeef22e5d546f64b517489956
[apps/native/gear-racing-controller.git] / src / view / view_racing.c
1 /*
2 * Copyright (c) 2018 Samsung Electronics Co., Ltd.
3 *
4 * Licensed under the Flora License, Version 1.1 (the License);
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://floralicense.org/license/
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an AS IS BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include "view/view_base.h"
18 #include "view/view_racing.h"
19 #include "view_manager/view_manager.h"
20 #include "controller/controller_racing.h"
21 #include "log.h"
22 #include "math_helper.h"
23
24 #define CAM_AZIMUTH_STEP 0.01
25
26 typedef enum _e_camera_button_action {
27         CAMERA_BUTTON_RIGHT_UP,
28         CAMERA_BUTTON_RIGHT_DOWN,
29         CAMERA_BUTTON_LEFT_UP,
30         CAMERA_BUTTON_LEFT_DOWN,
31 } e_camera_button_action;
32
33 typedef struct _s_view_racing {
34         s_view_base view_base;
35         Evas_Object *velocity;
36         Evas_Object *direction;
37         Evas_Object *camera_azimuth_indicator;
38         Evas_Object *camera_elevation_indicator;
39
40         float velocity_angle;
41         float direction_angle;
42
43         float dir_min_angle;
44         float dir_max_angle;
45         float vel_min_angle;
46         float vel_max_angle;
47
48         bool stop_longpress;
49
50         Ecore_Animator *button_value_animator;
51         bool buttons_pressed[2];
52         float button_value;
53
54         float button_value_min;
55         float button_value_max;
56 } s_view_racing;
57
58 static s_view_racing s_info = {
59                 {0,},
60                 .dir_min_angle = -90,
61                 .dir_max_angle = 90,
62                 .vel_min_angle = -38,
63                 .vel_max_angle = 180 + 38,
64 };
65
66 static Evas_Object *_create_image(Evas_Object* parent,
67                 int pos_X, int pos_Y, int width, int height,
68                 float angle,
69                 char *file_name,
70                 e_horizontal_align horizontal_align, e_vertical_align vertical_align)
71 {
72         char img_path[PATH_MAX];
73         view_base_get_resource(file_name, img_path);
74
75         Evas_Object *image = elm_image_add(parent);
76
77         if (!image) {
78                 dlog_print(DLOG_ERROR, LOG_TAG, "this->image == NULL");
79                 return NULL;
80         }
81
82         if (!elm_image_file_set(image, img_path, NULL)) {
83                 dlog_print(DLOG_ERROR, LOG_TAG, "elm_image_file_set() failed. File: %s", img_path);
84                 return NULL;
85         }
86
87         evas_object_resize(image, width, height);
88         view_base_set_position(image, pos_X, pos_Y, horizontal_align, vertical_align);
89         view_base_set_angle(image, angle, 180, 180);
90
91         return image;
92 }
93
94 static void _view_destroyed_cb(void *data, Evas *e, Evas_Object *obj, void *event_info)
95 {
96         evas_object_del(s_info.velocity);
97         evas_object_del(s_info.direction);
98 }
99
100
101 static void _layout_back_cb(void *data, Evas_Object *obj, void *event_info)
102 {
103         elm_win_lower(view_manager_get_win());
104 }
105
106 static void _controller_cb(void *data)
107 {
108         s_controller_data *controller_data = (s_controller_data *)data;
109
110         float angle = math_helper_range_map(controller_data->direction, -1, 1, s_info.dir_min_angle, s_info.dir_max_angle);
111         view_base_set_angle(s_info.direction, angle, 180.0, 180.0);
112
113 //      _D("VIEW VALUES: %f %f DIR: %f", controller_data->direction, controller_data->throttle, angle);
114
115         angle = math_helper_range_map(fabsf(controller_data->throttle), 0, 1, s_info.vel_min_angle, s_info.vel_max_angle);
116         view_base_set_angle(s_info.velocity, angle, 180.0, 180.0);
117
118         angle = math_helper_range_map(controller_data->cam_elevation, 0, 1, 0, 90);
119         view_base_set_angle(s_info.camera_elevation_indicator, 90 - angle, 180.0, 180.0);
120
121         if (controller_data->throttle < 0) {
122                 evas_object_color_set(s_info.velocity, 0, 255, 255, 255);
123         } else {
124                 evas_object_color_set(s_info.velocity, 255, 255, 255, 255);
125         }
126 }
127
128 static void _racing_screen_clicked_cb(void *data, Evas_Object *obj, const char *emission, const char *source)
129 {
130         evas_object_hide(s_info.velocity);
131
132         controller_racing_set_stop(true);
133 }
134
135 static void _stop_longpress_completed(void *data, Evas_Object *obj, const char *emission, const char *source)
136 {
137         ASSERT_FUNCTION_START;
138
139         s_info.stop_longpress = true;
140         controller_racing_next();
141
142
143         ASSERT_FUNCTION_END;
144 }
145
146 static void _stop_logpress_up(void *data, Evas_Object *obj, const char *emission, const char *source)
147 {
148         ASSERT_FUNCTION_START;
149
150         if (!s_info.stop_longpress) {
151                 evas_object_show(s_info.velocity);
152         }
153
154         s_info.stop_longpress = false;
155
156         controller_racing_set_stop(false);
157         ASSERT_FUNCTION_END;
158 }
159
160 static Eina_Bool _button_value_animator_cb(void *data)
161 {
162         float prev = s_info.button_value;
163
164         if (s_info.buttons_pressed[0] && !s_info.buttons_pressed[1]) {
165                 s_info.button_value -= CAM_AZIMUTH_STEP;
166         } else if (!s_info.buttons_pressed[0] && s_info.buttons_pressed[1]) {
167                 s_info.button_value += CAM_AZIMUTH_STEP;
168         }
169
170         if (prev * s_info.button_value < 0) {
171                 s_info.button_value = 0;
172         }
173
174         if (s_info.button_value < s_info.button_value_min) {
175                 s_info.button_value = s_info.button_value_min;
176         } else if (s_info.button_value > s_info.button_value_max) {
177                 s_info.button_value = s_info.button_value_max;
178         }
179
180         controller_racing_set_button_value(s_info.button_value);
181
182         float angle = math_helper_range_map(s_info.button_value, s_info.button_value_min, s_info.button_value_max, -90.0f, 90.0f);
183         view_base_set_angle(s_info.camera_azimuth_indicator, angle, 180.0, 180.0);
184         _D("[CAM] AZIMUTH: % f", s_info.button_value);
185
186         return ECORE_CALLBACK_RENEW;
187 }
188
189 static void _camera_button_cb(void *data, Evas_Object *obj, const char *emission, const char *source)
190 {
191         e_camera_button_action camera_button = (e_camera_button_action)data;
192
193         switch (camera_button) {
194                 case CAMERA_BUTTON_RIGHT_UP:
195                         s_info.buttons_pressed[1] = false;
196                         break;
197                 case CAMERA_BUTTON_RIGHT_DOWN:
198                         s_info.buttons_pressed[1] = true;
199                         break;
200                 case CAMERA_BUTTON_LEFT_UP:
201                         s_info.buttons_pressed[0] = false;
202                         break;
203                 case CAMERA_BUTTON_LEFT_DOWN:
204                         s_info.buttons_pressed[0] = true;
205                         break;
206                 default:
207                         break;
208         }
209
210         if ((s_info.buttons_pressed[0] || s_info.buttons_pressed[1]) && !s_info.button_value_animator) {
211                 s_info.button_value_animator = ecore_animator_add(_button_value_animator_cb, NULL);
212         } else if (s_info.button_value_animator) {
213                 ecore_animator_del(s_info.button_value_animator);
214                 s_info.button_value_animator= NULL;
215         }
216
217         _D("Camera button action: %d", camera_button);
218 }
219
220 static void _view_racing_create_gui(Evas_Object *parent)
221 {
222         s_info.view_base.view = view_base_create_layout(parent, "edje/racing.edj", GRP_MAIN);
223         eext_object_event_callback_add(s_info.view_base.view, EEXT_CALLBACK_BACK, _layout_back_cb, NULL);
224
225         s_info.velocity_angle = 45;
226         s_info.velocity = _create_image(parent, 44, 180, 160, 50,
227                         s_info.velocity_angle,
228                         "images/vel.png", HORIZONTAL_ALIGN_LEFT, VERTICAL_ALIGN_CENTER);
229
230         s_info.direction_angle = 30;
231         s_info.direction = _create_image(parent, 180, -5, 38, 38,
232                         s_info.direction_angle,
233                         "images/circle.png", HORIZONTAL_ALIGN_CENTER, VERTICAL_ALIGN_TOP);
234
235         s_info.camera_azimuth_indicator = _create_image(parent, 180, -5, 17, 17,
236                         0.0f,
237                         "images/circle.png", HORIZONTAL_ALIGN_CENTER, VERTICAL_ALIGN_TOP);
238         evas_object_color_set(s_info.camera_azimuth_indicator, 0, 255, 255, 255);
239
240         s_info.camera_elevation_indicator = _create_image(parent, 180, -5, 17, 17,
241                         90.0f,
242                         "images/circle.png", HORIZONTAL_ALIGN_CENTER, VERTICAL_ALIGN_TOP);
243         evas_object_color_set(s_info.camera_elevation_indicator, 255, 0, 0, 255);
244
245
246
247         evas_object_event_callback_add(s_info.view_base.view, EVAS_CALLBACK_DEL, _view_destroyed_cb, NULL);
248         elm_layout_signal_callback_add(s_info.view_base.view, "bg_clicked", "", _racing_screen_clicked_cb, NULL);
249
250         elm_layout_signal_callback_add(s_info.view_base.view, "stop_pressed", "", _stop_longpress_completed, NULL);
251         elm_layout_signal_callback_add(s_info.view_base.view, "stop_released", "", _stop_logpress_up, NULL);
252
253         elm_layout_signal_callback_add(s_info.view_base.view, "cam_right_down", "", _camera_button_cb, (void *)CAMERA_BUTTON_RIGHT_DOWN);
254         elm_layout_signal_callback_add(s_info.view_base.view, "cam_right_up", "", _camera_button_cb, (void *)CAMERA_BUTTON_RIGHT_UP);
255
256         elm_layout_signal_callback_add(s_info.view_base.view, "cam_left_down", "", _camera_button_cb, (void *)CAMERA_BUTTON_LEFT_DOWN);
257         elm_layout_signal_callback_add(s_info.view_base.view, "cam_left_up", "", _camera_button_cb, (void *)CAMERA_BUTTON_LEFT_UP);
258
259         controller_racing_set_stop(false);
260 }
261
262 static void _show_cb(void)
263 {
264         ASSERT_FUNCTION_START;
265
266         s_info.stop_longpress = false;
267         evas_object_show(s_info.velocity);
268         evas_object_show(s_info.direction);
269
270         evas_object_show(s_info.camera_azimuth_indicator);
271         evas_object_show(s_info.camera_elevation_indicator);
272
273         controller_racing_init(_controller_cb);
274
275         ASSERT_FUNCTION_END;
276 }
277
278 static void _hide_cb(void)
279 {
280         ASSERT_FUNCTION_START;
281
282         evas_object_hide(s_info.velocity);
283         evas_object_hide(s_info.direction);
284
285         evas_object_hide(s_info.camera_azimuth_indicator);
286         evas_object_hide(s_info.camera_elevation_indicator);
287         controller_racing_destroy();
288
289         ASSERT_FUNCTION_END;
290 }
291
292 void view_racing_set_button_params(float min, float max)
293 {
294         s_info.button_value_min = min;
295         s_info.button_value_max = max;
296 }
297
298 s_view_base *view_racing_init(Evas_Object *parent)
299 {
300         s_info.view_base.show_cb = _show_cb;
301         s_info.view_base.hide_cb = _hide_cb;
302
303         _view_racing_create_gui(parent);
304
305         return &s_info.view_base;
306 }