Initialize Tizen 2.3
[apps/home/mobileprint.git] / mobileprint / smsc / lib / smsc_smart.c
1 /*
2 *  Mobileprint
3 *
4 * Copyright 2013  Samsung Electronics Co., Ltd
5
6 * Licensed under the Flora License, Version 1.1 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
9
10 * http://floralicense.org/license/
11
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 *
18 */
19
20 #include <Evas.h>
21
22 #include "smsc_debug.h"
23 #include "smsc_widget.h"
24
25 #include "smsc_smart.h"
26
27
28 #define _evas_smart_smsc_type "Evas_Smart_Smsc"
29
30
31 #define _evas_smart_smsc_type           "Evas_Smart_Smsc"
32 #define EVT_CHILDREN_NUMBER_CHANGED     "children,changed"
33
34
35 static const Evas_Smart_Cb_Description _smart_callbacks[] =
36 {
37    {EVT_CHILDREN_NUMBER_CHANGED, "i"},
38    {NULL, NULL}
39 };
40
41
42 struct _Evas_Smart_Smsc_Data {
43         Evas_Object_Smart_Clipped_Data base;
44         struct smsc_widget widget;
45         Evas_Object *screen_reader_rectangle;
46
47         int is_ready;
48         struct size_px widget_size;
49
50         int is_process_file;
51         char **fnames;
52         int files_count;
53         char *ppd;
54         struct paper_size_pts paper_size;
55         enum page_orientation orientation;
56         int n_up;
57         struct page_scale scale;
58         int is_grayscale;
59 };
60
61
62 typedef struct _Evas_Smart_Smsc_Data Evas_Smart_Smsc_Data;
63
64
65 #define EVAS_SMART_SMSC_DATA_GET(o, ptr) \
66         Evas_Smart_Smsc_Data *ptr = evas_object_smart_data_get(o)
67
68 #define EVAS_SMART_SMSC_DATA_GET_OR_RETURN(o, ptr)              \
69         EVAS_SMART_SMSC_DATA_GET(o, ptr);                       \
70         if (!ptr) {                                             \
71                 SMSC_DEBUG("No widget data for object %p (%s)!", \
72                                 o, evas_object_type_get(o));    \
73                 abort();                                        \
74                 return;                                         \
75         }
76
77 #define EVAS_SMART_SMSC_DATA_GET_OR_RETURN_VAL(o, ptr, val)     \
78         EVAS_SMART_SMSC_DATA_GET(o, ptr);                       \
79         if (!ptr) {                                             \
80                 SMSC_DEBUG("No widget data for object %p (%s)!", \
81                                 o, evas_object_type_get(o));    \
82                 abort();                                        \
83                 return val;                                     \
84         }
85
86 EVAS_SMART_SUBCLASS_NEW(_evas_smart_smsc_type, _evas_smart_smsc,
87                 Evas_Smart_Class, Evas_Smart_Class,
88                 evas_object_smart_clipped_class_get, _smart_callbacks);
89
90
91 static void _evas_smart_smsc_smart_add(Evas_Object *o)
92 {
93         SMSC_TRACE_BEGIN;
94         EVAS_SMART_DATA_ALLOC(o, Evas_Smart_Smsc_Data);
95
96         init_smsc_widget(&(priv->widget), o);
97         priv->is_ready = 0;
98         memset(&(priv->widget_size), 0, sizeof(priv->widget_size));
99
100         priv->is_process_file = 0;
101         priv->fnames = NULL;
102         priv->files_count = 0;
103         priv->ppd = NULL;
104         memset(&(priv->paper_size), 0, sizeof(priv->paper_size));
105         priv->orientation = PAGE_ORIENTATION_PORTRAIT;
106         priv->n_up = 1;
107         memset(&(priv->scale), 0, sizeof(priv->scale));
108         priv->is_grayscale = 0;
109         priv->screen_reader_rectangle = NULL;
110
111         _evas_smart_smsc_parent_sc->add(o);
112         SMSC_TRACE_END;
113 }
114
115
116 static void _evas_smart_smsc_smart_del(Evas_Object *o)
117 {
118         //EVAS_SMART_SMSC_DATA_GET(o, priv);
119
120         /* remove childrens */
121         /* TODO: destroy smsc_widget */
122
123         _evas_smart_smsc_parent_sc->del(o);
124 }
125
126
127 static void _evas_smart_smsc_smart_show(Evas_Object *o)
128 {
129         EVAS_SMART_SMSC_DATA_GET(o, priv);
130         /* show smsc_widget */
131         show_smsc_widget(&(priv->widget));
132         _evas_smart_smsc_parent_sc->show(o);
133 }
134
135
136 static void _evas_smart_smsc_smart_hide(Evas_Object *o)
137 {
138         EVAS_SMART_SMSC_DATA_GET(o, priv);
139         /* hide childrens */
140         /* TODO: save hide state for smsc_widget */
141         hide_smsc_widget(&(priv->widget));
142         _evas_smart_smsc_parent_sc->hide(o);
143 }
144
145
146 static void _evas_smart_smsc_smart_move(Evas_Object *o,
147                 Evas_Coord x, Evas_Coord y)
148 {
149         /* TODO: correct move event usage (provide picture moving animation) */
150         SMSC_TRACE_BEGIN;
151         EVAS_SMART_SMSC_DATA_GET_OR_RETURN(o, priv);
152         priv->widget.off_x = x;
153         priv->widget.off_y = y;
154         move_smsc_widget_pages(&(priv->widget));
155         evas_object_move(priv->widget.loading_animation, x, y);
156         SMSC_TRACE_END;
157 }
158
159
160 static void _evas_smart_smsc_smart_resize(Evas_Object *o,
161                 Evas_Coord w, Evas_Coord h)
162 {
163         SMSC_TRACE_BEGIN;
164         Evas_Coord ow, oh;
165         evas_object_geometry_get(o, NULL, NULL, &ow, &oh);
166         if ((ow == w) && (oh == h)) {
167                 SMSC_TRACE_END;
168                 return;
169         }
170
171         evas_object_smart_changed(o);
172         SMSC_TRACE_END;
173 }
174
175
176 void evas_smart_smsc_free_process_file_args(Evas_Smart_Smsc_Data *priv)
177 {
178         int i;
179         SMSC_RET_IF(NULL == priv, "priv is NULL");
180         if (priv->fnames != NULL)
181                 for (i = 0; i < priv->files_count; ++i)
182                         SMSC_IF_FREE_MEM(priv->fnames[i]);
183         SMSC_IF_FREE_MEM(priv->fnames);
184         priv->files_count = 0;
185         SMSC_IF_FREE_MEM(priv->ppd);
186         SMSC_IF_FREE_MEM(priv->paper_size.name);
187
188         priv->is_process_file = 0;
189 }
190
191
192 static void _evas_smart_smsc_smart_calculate(Evas_Object *o)
193 {
194         SMSC_TRACE_BEGIN;
195         Evas_Coord x, y, w, h;
196
197         EVAS_SMART_SMSC_DATA_GET_OR_RETURN(o, priv);
198         evas_object_geometry_get(o, &x, &y, &w, &h);
199         SMSC_DEBUG("Geometry: (%d, %d) : (%d, %d)",
200                         x, y, w, h);
201
202         /* change children sizes */
203
204         priv->widget_size.x = w;
205         priv->widget_size.y = h;
206         priv->is_ready = 1;
207
208         /* set widget offset */
209         priv->widget.off_x = x;
210         priv->widget.off_y = y;
211
212         /* resize rectangle for accessibility support */
213         evas_object_move(priv->screen_reader_rectangle, x, y);
214         evas_object_resize(priv->screen_reader_rectangle, w, h);
215
216         clear_smsc_widget(&(priv->widget));
217
218         /* request to preview_engine for recalculation */
219         if (priv->is_process_file)
220                 process_preview_engine_file(&(priv->widget.engine),
221                                 priv->fnames, priv->files_count,
222                                 priv->ppd, &(priv->paper_size),
223                                 &(priv->widget_size), priv->orientation,
224                                 priv->n_up, &(priv->scale), priv->is_grayscale);
225
226         SMSC_TRACE_END;
227 }
228
229
230 /* set smart interface */
231 static void _evas_smart_smsc_smart_set_user(Evas_Smart_Class *sc)
232 {
233         SMSC_TRACE_BEGIN;
234         sc->add = _evas_smart_smsc_smart_add;
235         sc->del = _evas_smart_smsc_smart_del;
236         sc->show = _evas_smart_smsc_smart_show;
237         sc->hide = _evas_smart_smsc_smart_hide;
238         sc->move = _evas_smart_smsc_smart_move;
239
240         sc->resize = _evas_smart_smsc_smart_resize;
241         sc->calculate = _evas_smart_smsc_smart_calculate;
242         SMSC_TRACE_END;
243 }
244
245
246 Evas_Object *evas_smart_smsc_add(Evas *evas)
247 {
248         Evas_Object *res;
249         SMSC_TRACE_BEGIN;
250         res = evas_object_smart_add(evas, _evas_smart_smsc_smart_class_new());
251         SMSC_TRACE_END;
252         return res;
253 }
254
255
256 int evas_smart_smsc_set_file(Evas_Object *o, char **const fnames,
257                 int files_count, const char *ppd,
258                 const struct paper_size_pts *paper_size,
259                 enum page_orientation orientation, int n_up,
260                 const struct page_scale *scale, int is_grayscale)
261 {
262         int res = 0;
263         int i;
264         SMSC_TRACE_BEGIN;
265         SMSC_RETV_IF(NULL == o || NULL == fnames || files_count <= 0
266                         || NULL == fnames[0] || NULL == ppd
267                         || NULL == paper_size || NULL == scale,
268                         -1, "Argument error");
269         EVAS_SMART_SMSC_DATA_GET_OR_RETURN_VAL(o, priv, -1);
270
271         /* save configuration for future usage */
272         evas_smart_smsc_free_process_file_args(priv);
273
274         priv->fnames = malloc(sizeof(char*) * (files_count + 1));
275         SMSC_RETV_IF(NULL == priv->fnames, -1, "Out of memory");
276         memset(priv->fnames, 0, sizeof(char*) * (files_count + 1));
277         for (i = 0; i < files_count; ++i) {
278                 priv->fnames[i] = strdup(fnames[i]);
279                 if (NULL == priv->fnames[i]) {
280                         evas_smart_smsc_free_process_file_args(priv);
281                         SMSC_RETV_IF(1, -1, "Out of memory");
282                 }
283         }
284         priv->files_count = files_count;
285         priv->ppd = strdup(ppd);
286         priv->paper_size = *paper_size;
287         priv->paper_size.name = strdup(paper_size->name);
288         priv->orientation = orientation;
289         priv->n_up = n_up;
290         priv->scale = *scale;
291         priv->is_grayscale = is_grayscale;
292
293         priv->is_process_file = 1;
294
295         if (NULL == priv->ppd || NULL == priv->paper_size.name) {
296                 evas_smart_smsc_free_process_file_args(priv);
297                 SMSC_RETV_IF(1, -1, "Out of memory");
298         }
299
300         /* request preview_engine for recalculation */
301         if (priv->is_ready) {
302                 clear_smsc_widget(&(priv->widget));
303                 res = process_preview_engine_file(&(priv->widget.engine),
304                                 priv->fnames, priv->files_count, priv->ppd,
305                                 &(priv->paper_size), &(priv->widget_size),
306                                 priv->orientation, priv->n_up, &(priv->scale),
307                                 priv->is_grayscale);
308         }
309
310         SMSC_TRACE_END;
311         return res;
312 }
313
314 //needed to get events MOUSE_IN for correct Screen Reader work
315 void smsc_mouse_in_cb(void *data, Evas *evas,
316                 Evas_Object *obj, void *event_info)
317 {
318         SMSC_TRACE_BEGIN;
319         SMSC_TRACE_END;
320 }
321
322 int evas_smart_smsc_set_layout(Evas_Object *o, Evas_Object *layout)
323 {
324         EVAS_SMART_SMSC_DATA_GET_OR_RETURN_VAL(o, priv, -1);
325         smsc_widget_set_layout(&(priv->widget), layout);
326         evas_object_event_callback_add(priv->screen_reader_rectangle, EVAS_CALLBACK_MOUSE_IN,
327                         smsc_mouse_in_cb, &(priv->widget));
328         return 0;
329 }
330
331 /* transparent rectangle to support Screen Reader */
332 int init_smsc_accessability_support(Evas_Object *o)
333 {
334         SMSC_TRACE_BEGIN;
335         SMSC_RETV_IF(NULL == o, -1, "Invalid arguments");
336         EVAS_SMART_SMSC_DATA_GET_OR_RETURN_VAL(o, priv, -1);
337         struct smsc_widget *widget = &(priv->widget);
338
339         SMSC_RETV_IF(NULL == widget || NULL == widget->parent || NULL == widget->canvas, -1,
340                         "Can't get widget of object.");
341         if (NULL == priv->screen_reader_rectangle)
342         {
343                 priv->screen_reader_rectangle = evas_object_rectangle_add(widget->canvas);
344                 SMSC_RETV_IF(NULL == priv->screen_reader_rectangle, -1,
345                         "Failed to add rectangle to smart object widget canvas");
346         }
347
348         evas_object_color_set(priv->screen_reader_rectangle, 0, 0, 0, 0);
349         evas_object_smart_member_add(priv->screen_reader_rectangle, widget->parent);
350         evas_object_move(priv->screen_reader_rectangle,
351                                                 priv->widget.off_x, priv->widget.off_y);
352         evas_object_resize(priv->screen_reader_rectangle,
353                                                 priv->widget_size.x,
354                                                 priv->widget_size.y);
355         evas_object_raise(priv->screen_reader_rectangle);
356         evas_object_show(priv->screen_reader_rectangle);
357
358         SMSC_TRACE_END;
359         return 0;
360 }
361
362 /* rectangle for screen reader creating and registering in access */
363 int set_main_view_accessability_info(Evas_Object *o,
364                                                                         Evas_Object *layout,
365                                                                         const char *access_info,
366                                                                         const char *access_type,
367                                                                         const char *access_context_info)
368 {
369         SMSC_TRACE_BEGIN;
370         EVAS_SMART_SMSC_DATA_GET_OR_RETURN_VAL(o, priv, -1);
371
372         Evas_Object *ao;
373         ao = elm_access_object_get(priv->screen_reader_rectangle);
374         if (NULL == ao) {
375                 ao = elm_access_object_register(priv->screen_reader_rectangle, layout);
376                 SMSC_RETV_IF(NULL == ao, -1, "ERROR: Failed to register smsc in access!");
377         }
378         SMSC_DEBUG("Setting main view accessibility info for screen reader: %s", access_info);
379         elm_access_info_set(ao, ELM_ACCESS_INFO, access_info);
380         elm_access_info_set(ao, ELM_ACCESS_TYPE, access_type);
381         elm_access_info_set(ao, ELM_ACCESS_CONTEXT_INFO, access_context_info);
382         SMSC_TRACE_END;
383         return 0;
384 }
385
386
387 /**
388  * @brief       Calculate current page number based on current page offset
389  * @param[in]   o       Smooth scrolling widget
390  * @return      <0      Error (argument error or not initialized)
391  *              >=0     Current page number starting from 0
392  */
393 int evas_smart_smsc_calculate_page_number(Evas_Object *o)
394 {
395         EVAS_SMART_SMSC_DATA_GET_OR_RETURN_VAL(o, priv, -1);
396         return get_smsc_position_cur_page(&(priv->widget.position));
397 }
398
399
400 /**
401  * @brief       Get pages count
402  * @param[in]   o       Smooth scrolling widget
403  * return       <=0     Error (argument error or not initialized)
404  *              >0      Pages count
405  */
406 int evas_smart_smsc_get_pages_count(Evas_Object *o)
407 {
408         EVAS_SMART_SMSC_DATA_GET_OR_RETURN_VAL(o, priv, -1);
409         SMSC_RETV_IF(!priv->widget.position.is_configured,
410                         -1, "Not initialized");
411         return priv->widget.position.pages_count;
412 }