updated licenses info
[platform/core/uifw/lottie-player.git] / example / lottieviewer.cpp
1 /*
2  * Copyright (c) 2018 Samsung Electronics Co., Ltd. All rights reserved.
3  *
4  * Licensed under the LGPL License, Version 2.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  *     https://www.gnu.org/licenses/
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 "lottieview.h"
19 #include<iostream>
20 #include <stdio.h>
21 #include <stdlib.h>
22 #include <sys/types.h>
23 #include <dirent.h>
24 #include <error.h>
25 #include <algorithm>
26
27 using namespace std;
28
29 typedef struct _AppInfo AppInfo;
30 struct _AppInfo {
31    LottieView *view;
32    Evas_Object *layout;
33    Evas_Object *slider;
34    Evas_Object *button;
35    Ecore_Evas *ee;
36    Eina_Bool autoPlaying;
37 };
38
39 typedef struct _ItemData ItemData;
40 struct _ItemData {
41    int index;
42 };
43
44
45 std::vector<std::string> jsonFiles;
46 bool renderMode = true;
47
48 static void
49 _layout_del_cb(void *data, Evas *, Evas_Object *, void *)
50 {
51    AppInfo *info = (AppInfo *)data;
52    if (info->view) delete info->view;
53    info->view = NULL;
54
55    ecore_evas_data_set(info->ee, "AppInfo", NULL);
56
57    free(info);
58 }
59
60 static void
61 _update_frame_info(AppInfo *info, double pos)
62 {
63    int frameNo = pos * info->view->getTotalFrame();
64    char buf[64];
65
66    sprintf(buf, "%d / %ld", frameNo, info->view->getTotalFrame());
67    elm_object_part_text_set(info->layout, "text", buf);
68 }
69
70 static void
71 _toggle_start_button(AppInfo *info)
72 {
73    if (!info->autoPlaying)
74      {
75         info->autoPlaying = EINA_TRUE;
76         info->view->play();
77         elm_object_text_set(info->button, "Stop");
78      }
79    else
80      {
81         info->autoPlaying = EINA_FALSE;
82         info->view->stop();
83         elm_object_text_set(info->button, "Start");
84      }
85 }
86
87 static void
88 _ee_pre_render_cb(Ecore_Evas *ee)
89 {
90     AppInfo *info = (AppInfo *)ecore_evas_data_get(ee, "AppInfo");
91
92     if (info && info->autoPlaying && info->view)
93       {
94          float pos = info->view->getPos();
95          _update_frame_info(info, pos);
96          elm_slider_value_set(info->slider, (double)pos);
97          info->view->render();
98
99          if (pos >= 1.0)
100            _toggle_start_button(info);
101       }
102 }
103
104 static void
105 _slider_cb(void *data, Evas_Object *obj, void *event_info EINA_UNUSED)
106 {
107    double val = elm_slider_value_get(obj);
108    AppInfo *info = (AppInfo *)data;
109
110    _update_frame_info(info, val);
111
112    if (!info->autoPlaying)
113      {
114         info->view->seek(val);
115         info->view->render();
116      }
117 }
118
119 static void
120 _button_clicked_cb(void *data, Evas_Object *obj, void *event_info)
121 {
122    AppInfo *info = (AppInfo *)data;
123
124    _toggle_start_button(info);
125 }
126
127 Evas_Object *
128 create_layout(Evas_Object *parent, const char *file)
129 {
130    Evas_Object *layout, *slider, *image, *button;
131    Evas *e;
132    Ecore_Evas *ee;
133    char buf[64];
134    AppInfo *info = (AppInfo *)calloc(sizeof(AppInfo), 1);
135
136    //LAYOUT
137    layout = elm_layout_add(parent);
138    evas_object_show(layout);
139    evas_object_size_hint_weight_set(layout, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
140
141    std::string edjPath = DEMO_DIR;
142    edjPath +="layout.edj";
143
144    elm_layout_file_set(layout, edjPath.c_str(), "layout");
145
146    //LOTTIEVIEW
147    LottieView *view = new LottieView(evas_object_evas_get(layout), renderMode);
148    std::string filePath = DEMO_DIR;
149    filePath +=file;
150
151    view->setFilePath(filePath.c_str());
152    view->setSize(500, 500);
153
154    //IMAGE from LOTTIEVIEW
155    image = view->getImage();
156    evas_object_show(image);
157    evas_object_size_hint_min_set(image, 500, 500);
158    elm_object_part_content_set(layout, "lottie", image);
159
160    //SLIDER
161    slider = elm_slider_add(layout);
162    elm_object_part_content_set(layout, "slider", slider);
163    evas_object_smart_callback_add(slider, "changed", _slider_cb, (void *)info);
164
165    button = elm_button_add(layout);
166    elm_object_text_set(button, "Start");
167    elm_object_part_content_set(layout, "button", button);
168    evas_object_smart_callback_add(button, "clicked", _button_clicked_cb, (void *)info);
169
170    e = evas_object_evas_get(layout);
171    ee = ecore_evas_ecore_evas_get(e);
172    ecore_evas_data_set(ee, "AppInfo", info);
173    ecore_evas_callback_pre_render_set(ee, _ee_pre_render_cb);
174
175    info->view = view;
176    info->layout = layout;
177    info->slider = slider;
178    info->button = button;
179    info->ee = ee;
180    evas_object_event_callback_add(layout, EVAS_CALLBACK_DEL, _layout_del_cb, (void *)info);
181
182    sprintf(buf, "%d / %ld", 0, view->getTotalFrame());
183    elm_object_part_text_set(layout, "text", buf);
184
185    view->seek(0.0);
186    view->render();
187
188    return layout;
189 }
190
191 static void
192 _gl_selected_cb(void *data, Evas_Object *obj, void *event_info)
193 {
194    Evas_Object *nf = (Evas_Object *)data;
195    Elm_Object_Item *it = (Elm_Object_Item *)event_info;
196    elm_genlist_item_selected_set(it, EINA_FALSE);
197
198    Evas_Object *layout = create_layout(nf, jsonFiles[elm_genlist_item_index_get(it) - 1].c_str());
199    elm_naviframe_item_push(nf, NULL, NULL, NULL, layout, NULL);
200 }
201
202 static char *
203 _gl_text_get(void *data, Evas_Object *obj, const char *part)
204 {
205    ItemData *id = (ItemData *) data;
206    return strdup(jsonFiles[id->index].c_str());
207 }
208
209 static void
210 _gl_del(void *data, Evas_Object *obj)
211 {
212 }
213
214 EAPI_MAIN int
215 elm_main(int argc EINA_UNUSED, char **argv EINA_UNUSED)
216 {
217    Evas_Object *win, *nf, *genlist;
218    Elm_Genlist_Item_Class *itc = elm_genlist_item_class_new();
219    ItemData *itemData;
220    DIR *dir;
221    struct dirent *ent;
222
223    if (argc > 1) {
224       if (!strcmp(argv[1], "--disable-render"))
225          renderMode = false;
226    }
227
228    //WIN        
229    elm_policy_set(ELM_POLICY_QUIT, ELM_POLICY_QUIT_LAST_WINDOW_CLOSED);
230    win = elm_win_util_standard_add("lottie", "LottieViewer");
231    elm_win_autodel_set(win, EINA_TRUE);
232    evas_object_resize(win, 500, 700);
233    evas_object_show(win);
234
235    //NAVIFRAME
236    nf = elm_naviframe_add(win);
237    evas_object_size_hint_weight_set(nf, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
238    elm_win_resize_object_add(win, nf);
239    evas_object_show(nf);
240
241    //GENLIST
242    genlist = elm_genlist_add(nf);
243    elm_genlist_mode_set(genlist, ELM_LIST_COMPRESS);
244    evas_object_smart_callback_add(genlist, "selected", _gl_selected_cb, nf);
245
246    itc->item_style = "default";
247    itc->func.text_get = _gl_text_get;
248    itc->func.del = _gl_del;
249
250    std::string rscPath = DEMO_DIR;
251
252    dir = opendir(rscPath.c_str());
253    while ((ent = readdir(dir)) != NULL) {
254       if (!strncmp(ent->d_name + (strlen(ent->d_name) - 4), "json", 4)) {
255          jsonFiles.push_back(ent->d_name);
256       }
257    }
258    closedir(dir);
259
260    std::sort(jsonFiles.begin(), jsonFiles.end(), [](auto & a, auto &b){return a < b;});
261
262    for (uint i = 0; i < jsonFiles.size(); i++) {
263       itemData = (ItemData *)calloc(sizeof(ItemData), 1);
264       itemData->index = i;
265       elm_genlist_item_append(genlist, itc, (void *)itemData, NULL, ELM_GENLIST_ITEM_NONE, NULL, NULL);
266    }
267
268    elm_naviframe_item_push(nf, "Lottie Viewer", NULL, NULL, genlist, NULL);
269
270    elm_run();
271
272    return 0;
273 }
274 ELM_MAIN()