Apply the Listener
[profile/tv/apps/native/videoplayer.git] / src / control.cpp
1 /*
2  * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  * Licensed under the Apache License, Version 2.0 (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://www.apache.org/licenses/LICENSE-2.0
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 <Elementary.h>
18 #include <Eina.h>
19 #include <dbg.h>
20 #include <InputHandler.h>
21 #include "define.h"
22 #include "i18n.h"
23 #include "control.h"
24
25 #define MAX_CONTROL_BTNS 7
26
27 struct control_data;
28
29 class CControlHandler :
30         public CListenerMgr,
31         public IMouseMoveListener,
32         public IMouseClickedListener {
33
34 private:
35         control_data *m;
36
37 public:
38         CControlHandler(control_data *dt) :
39                 IMouseMoveListener(this),
40                 IMouseClickedListener(this) {
41                 m = dt;
42         }
43         virtual void OnMouseMove(int id, Evas *e, Evas_Object *obj,
44                         Evas_Event_Mouse_Move *ev);
45         virtual void OnMouseClicked(int id, Evas_Object *obj);
46         int GetEventTypes(void);
47 };
48
49 struct _event_cb {
50         void (*func)(void *data, const char *ev);
51         void *data;
52 };
53
54 struct control_data {
55         Evas_Object *base;
56         Evas_Object *focused;
57         Evas_Object *btn[MAX_CONTROL_BTNS];
58         int btns;
59         struct _event_cb cb;
60         CControlHandler *handler;
61 };
62
63 static void _event_callback(void *dt, Evas_Object *obj,
64                 const char *emission, const char *source)
65 {
66         struct control_data *data;
67
68         if (!dt)
69                 return;
70
71         data = (control_data *)dt;
72
73         data->cb.func(data->cb.data, source);
74 }
75
76 static void _set_focus_directions(Evas_Object **btn, int count)
77 {
78         Evas_Object *obj;
79         int i;
80
81         for (i = 0; i < count; i++) {
82                 if (i == count - 1)
83                         obj = btn[0];
84                 else
85                         obj = btn[i + 1];
86
87                 elm_object_focus_next_object_set(btn[i], obj, ELM_FOCUS_RIGHT);
88
89                 if (i == 0)
90                         obj = btn[count - 1];
91                 else
92                         obj = btn[i - 1];
93
94                 elm_object_focus_next_object_set(btn[i], obj, ELM_FOCUS_LEFT);
95         }
96 }
97
98 static inline Evas_Object *_add_button(Evas_Object *base, const char *style)
99 {
100         Evas_Object *btn;
101
102         btn = elm_button_add(base);
103         if (!btn)
104                 return NULL;
105
106         elm_object_style_set(btn, style);
107         evas_object_show(btn);
108
109         return btn;
110 }
111
112 static int _add_controls(struct control_data *data,
113                 const char **btns, int count)
114 {
115         int i, j;
116         char buf[32];
117         CControlHandler *handler;
118
119         handler = data->handler;
120
121         for (i = 0; i < count; i++) {
122                 snprintf(buf, sizeof(buf), "video_btn_%s", btns[i]);
123                 data->btn[i] = _add_button(data->base, buf);
124                 if (!data->btn[i]) {
125                         for (j = 0; j < i; j++)
126                                 data->btn[j] = NULL;
127                         return -1;
128                 }
129
130                 snprintf(buf, sizeof(buf), "part_btn%d", i);
131                 elm_object_part_content_set(data->base,
132                                 buf, data->btn[i]);
133
134                 /* FIXME: disable setting button temporary */
135                 if (i == count - 1) {
136                         elm_object_focus_allow_set(data->btn[i], EINA_FALSE);
137                         break;
138                 }
139
140                 handler->Connect(data->btn[i], -1, handler->GetEventTypes());
141
142                 elm_object_signal_callback_add(data->btn[i],
143                                 SIG_BTN_ANI_FIN, btns[i],
144                                 _event_callback, data);
145
146                 elm_object_focus_next_object_set(data->btn[i],
147                                 data->btn[i], ELM_FOCUS_DOWN);
148
149                 data->btns++;
150         }
151
152         return 0;
153 }
154
155 Eina_Bool control_add_bar(struct control_data *data,
156                 Evas_Object *base, const char **btns, int count)
157 {
158         int r;
159
160         if (!data || !base || !btns)
161                 return EINA_FALSE;
162
163         data->base = base;
164         data->btns = 0;
165
166         r = _add_controls(data, btns, count);
167         if (r < 0)
168                 return EINA_FALSE;
169
170         _set_focus_directions(data->btn, data->btns);
171
172         return EINA_TRUE;
173 }
174
175 void control_handler_init(struct control_data *data,
176                 void (*func)(void *, const char *), void *param)
177 {
178         if (!data || !func)
179                 return;
180
181         data->cb.func = func;
182         data->cb.data = param;
183 }
184
185 void control_focus_set(struct control_data *data, int id, Eina_Bool foc)
186 {
187         if (!data)
188                 return;
189
190         elm_object_focus_set(data->btn[id], foc);
191 }
192
193 void control_signal_emit(struct control_data *data, int id,
194                 const char *emission, const char *source)
195 {
196         if (!data)
197                 return;
198
199         elm_object_signal_emit(data->btn[id], emission, source);
200 }
201
202 void control_hide(struct control_data *data)
203 {
204         int i;
205
206         for (i = 0; i < data->btns; i++) {
207                 evas_object_freeze_events_set(data->btn[i], EINA_TRUE);
208                 elm_object_focus_allow_set(data->btn[i], EINA_FALSE);
209         }
210 }
211
212 void control_show(struct control_data *data)
213 {
214         int i;
215
216         for (i = 0; i < data->btns; i++) {
217                 evas_object_freeze_events_set(data->btn[i], EINA_FALSE);
218                 elm_object_focus_allow_set(data->btn[i], EINA_TRUE);
219         }
220 }
221
222 void control_fini(struct control_data *data)
223 {
224         if (!data)
225                 return;
226
227         delete data->handler;
228         free(data);
229 }
230
231 struct control_data *control_init(void)
232 {
233         struct control_data *data;
234
235         data = (control_data *)calloc(1, sizeof(*data));
236         if (!data) {
237                 _ERR("allocation fail");
238                 return NULL;
239         }
240
241         data->handler = new CControlHandler(data);
242
243         return data;
244 }
245
246 void CControlHandler::OnMouseMove(int id, Evas *e, Evas_Object *obj,
247                         Evas_Event_Mouse_Move *ev)
248 {
249         if (!obj)
250                 return;
251
252         if (!elm_object_focus_get(obj))
253                 elm_object_focus_set(obj, EINA_TRUE);
254 }
255
256 void CControlHandler::OnMouseClicked(int id, Evas_Object *obj)
257 {
258         elm_object_signal_emit(obj, SIG_BTN_ANI_START, "");
259 }
260
261 int CControlHandler::GetEventTypes(void)
262 {
263         return TYPE_MOUSE_MOVE | TYPE_CLICKED;
264 }