animator(void *data , double pos)
{
LottieView *view = static_cast<LottieView *>(data);
- view->seek(pos);
- if (pos == 1.0) {
+ float nextPos = pos + view->mStartPos;
+ if (nextPos > 1.0) nextPos = 1.0;
+
+ view->seek(nextPos);
+ if (nextPos == 1.0) {
+ view->mAnimator = NULL;
view->finished();
return EINA_FALSE;
}
evas_object_vg_root_node_set(mVg, root);
}
+static void mImageDelCb(void *data, Evas *evas, Evas_Object *obj, void *)
+{
+ LottieView *lottie = (LottieView *)data;
+
+ if (lottie->mImage != obj) return;
+
+ lottie->mImage = NULL;
+ lottie->stop();
+}
+
+static void mVgDelCb(void *data, Evas *evas, Evas_Object *obj, void *)
+{
+ LottieView *lottie = (LottieView *)data;
+ if (lottie->mVg != obj) return;
+
+ lottie->mVg = NULL;
+ lottie->stop();
+}
+
+void LottieView::initializeBufferObject(Evas *evas)
+{
+ if (mRenderMode) {
+ mImage = evas_object_image_filled_add(evas);
+ evas_object_image_colorspace_set(mImage, EVAS_COLORSPACE_ARGB8888);
+ evas_object_image_alpha_set(mImage, EINA_TRUE);
+ evas_object_event_callback_add(mImage, EVAS_CALLBACK_DEL, mImageDelCb, this);
+ } else {
+ mVg = evas_object_vg_add(evas);
+ evas_object_event_callback_add(mVg, EVAS_CALLBACK_DEL, mVgDelCb, this);
+ }
+}
+
LottieView::LottieView(Evas *evas, bool renderMode, bool asyncRender):mVg(nullptr), mImage(nullptr)
{
mPalying = false;
mRenderMode = renderMode;
mAsyncRender = asyncRender;
- if (mRenderMode) {
- mImage = evas_object_image_filled_add(evas);
- evas_object_image_colorspace_set(mImage, EVAS_COLORSPACE_ARGB8888);
- evas_object_image_alpha_set(mImage, EINA_TRUE);
- } else {
- mVg = evas_object_vg_add(evas);
- }
+ initializeBufferObject(evas);
}
LottieView::~LottieView()
delete mPlayer;
}
+Evas_Object *LottieView::getImage() {
+ if (mRenderMode) {
+ return mImage;
+ } else {
+ return mVg;
+ }
+}
+
void LottieView::show()
{
if (mRenderMode) {
if (mPalying && mReverse)
pos = 1.0 - pos;
+ mPos = pos;
+
if (mRenderMode) {
LOTBuffer buf;
evas_object_image_size_get(mImage, &buf.width, &buf.height);
if (mAsyncRender) {
if (mRenderTask.valid()) return;
mDirty = true;
- mPendingPos = pos;
buf.buffer = (uint32_t *)evas_object_image_data_get(mImage, EINA_TRUE);
buf.bytesPerLine = evas_object_image_stride_get(mImage);
- mRenderTask = mPlayer->render(mPendingPos, buf);
+ mRenderTask = mPlayer->render(mPos, buf);
mBuffer = buf;
// to force a redraw
evas_object_image_data_update_add(mImage, 0 , 0, buf.width, buf.height);
}
}
+float LottieView::getPos()
+{
+ return mPos;
+}
+
void LottieView::render()
{
if (!mDirty) return;
}
mBuffer.buffer = nullptr;
} else {
- const std::vector<LOTNode *> &renderList = mPlayer->renderList(mPendingPos);
+ const std::vector<LOTNode *> &renderList = mPlayer->renderList(mPos);
update(renderList);
}
}
void LottieView::play()
{
+ mStartPos = mPos;
+ if (mAnimator) ecore_animator_del(mAnimator);
mAnimator = ecore_animator_timeline_add(mPlayer->playTime()/mSpeed, animator, this);
mReverse = false;
mCurCount = mRepeatCount;
void LottieView::stop()
{
mPalying = false;
+ if (mAnimator) {
+ ecore_animator_del(mAnimator);
+ mAnimator = NULL;
+ }
}
void LottieView::restart()
mReverse = !mReverse;
else
mReverse = false;
+
+ mStartPos = 0;
+ if (mAnimator) ecore_animator_del(mAnimator);
mAnimator = ecore_animator_timeline_add(mPlayer->playTime()/mSpeed, animator, this);
}
}
#include "lottieview.h"
#include<iostream>
#include <stdio.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <dirent.h>
+#include <error.h>
using namespace std;
struct _AppInfo {
LottieView *view;
Evas_Object *layout;
+ Evas_Object *slider;
+ Evas_Object *button;
+ Ecore_Evas *ee;
+ Eina_Bool autoPlaying;
};
+typedef struct _ItemData ItemData;
+struct _ItemData {
+ int index;
+};
+
+Eina_List *jsonFiles;
+bool renderMode = true;
+
+static void
+_layout_del_cb(void *data, Evas *, Evas_Object *, void *)
+{
+ AppInfo *info = (AppInfo *)data;
+ if (info->view) delete info->view;
+ info->view = NULL;
+
+ ecore_evas_data_set(info->ee, "AppInfo", NULL);
+
+ free(info);
+}
+
+static void
+_update_frame_info(AppInfo *info, double pos)
+{
+ int frameNo = pos * info->view->getTotalFrame();
+ char buf[64];
+
+ sprintf(buf, "%d / %ld", frameNo, info->view->getTotalFrame());
+ elm_object_part_text_set(info->layout, "text", buf);
+}
+
+static void
+_toggle_start_button(AppInfo *info)
+{
+ if (!info->autoPlaying)
+ {
+ info->autoPlaying = EINA_TRUE;
+ info->view->play();
+ elm_object_text_set(info->button, "Stop");
+ }
+ else
+ {
+ info->autoPlaying = EINA_FALSE;
+ info->view->stop();
+ elm_object_text_set(info->button, "Start");
+ }
+}
+
static void
-_win_del_cb(void *data, Evas_Object *obj, void *event_info EINA_UNUSED)
+_ee_pre_render_cb(Ecore_Evas *ee)
{
- LottieView *view = (LottieView *)data;
- delete view;
+ AppInfo *info = (AppInfo *)ecore_evas_data_get(ee, "AppInfo");
+
+ if (info && info->autoPlaying && info->view)
+ {
+ float pos = info->view->getPos();
+ _update_frame_info(info, pos);
+ elm_slider_value_set(info->slider, (double)pos);
+ info->view->render();
+
+ if (pos >= 1.0)
+ _toggle_start_button(info);
+ }
}
static void
double val = elm_slider_value_get(obj);
AppInfo *info = (AppInfo *)data;
- int frameNo = val * info->view->getTotalFrame();
- char buf[64];
+ _update_frame_info(info, val);
- sprintf(buf, "%d / %ld", frameNo, info->view->getTotalFrame());
+ if (!info->autoPlaying)
+ {
+ info->view->seek(val);
+ info->view->render();
+ }
+}
- elm_object_part_text_set(info->layout, "text", buf);
+static void
+_button_clicked_cb(void *data, Evas_Object *obj, void *event_info)
+{
+ AppInfo *info = (AppInfo *)data;
- info->view->seek(val);
- info->view->render();
+ _toggle_start_button(info);
}
-EAPI_MAIN int
-elm_main(int argc EINA_UNUSED, char **argv EINA_UNUSED)
+Evas_Object *
+create_layout(Evas_Object *parent, char *file)
{
- Evas_Object *win, *layout, *slider, *image;
- bool renderMode = true;
+ Evas_Object *layout, *slider, *image, *button;
+ Evas *e;
+ Ecore_Evas *ee;
char buf[64];
- AppInfo appInfo;
-
- if (argc > 1) {
- if (!strcmp(argv[1], "--disable-render"))
- renderMode = false;
- }
-
- elm_policy_set(ELM_POLICY_QUIT, ELM_POLICY_QUIT_LAST_WINDOW_CLOSED);
- win = elm_win_util_standard_add("lottie", "LottieViewer");
- elm_win_autodel_set(win, EINA_TRUE);
- evas_object_resize(win, 500, 700);
- evas_object_show(win);
+ AppInfo *info = (AppInfo *)calloc(sizeof(AppInfo), 1);
- layout = elm_layout_add(win);
+ //LAYOUT
+ layout = elm_layout_add(parent);
evas_object_show(layout);
evas_object_size_hint_weight_set(layout, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
edjPath +="layout.edj";
elm_layout_file_set(layout, edjPath.c_str(), "layout");
- elm_win_resize_object_add(win, layout);
+ //LOTTIEVIEW
+ LottieView *view = new LottieView(evas_object_evas_get(layout), renderMode);
std::string filePath = DEMO_DIR;
- filePath +="insta_camera.json";
+ filePath +=file;
- LottieView *view = new LottieView(evas_object_evas_get(win), renderMode);
view->setFilePath(filePath.c_str());
view->setSize(500, 500);
- evas_object_smart_callback_add(win, "delete,request", _win_del_cb, (void *)view);
-
+ //IMAGE from LOTTIEVIEW
image = view->getImage();
evas_object_show(image);
evas_object_size_hint_min_set(image, 500, 500);
elm_object_part_content_set(layout, "lottie", image);
- appInfo.view = view;
- appInfo.layout = layout;
-
+ //SLIDER
slider = elm_slider_add(layout);
- evas_object_show(slider);
elm_object_part_content_set(layout, "slider", slider);
- evas_object_smart_callback_add(slider, "changed", _slider_cb, (void *)&appInfo);
+ evas_object_smart_callback_add(slider, "changed", _slider_cb, (void *)info);
+
+ button = elm_button_add(layout);
+ elm_object_text_set(button, "Start");
+ elm_object_part_content_set(layout, "button", button);
+ evas_object_smart_callback_add(button, "clicked", _button_clicked_cb, (void *)info);
+
+ e = evas_object_evas_get(layout);
+ ee = ecore_evas_ecore_evas_get(e);
+ ecore_evas_data_set(ee, "AppInfo", info);
+ ecore_evas_callback_pre_render_set(ee, _ee_pre_render_cb);
+
+ info->view = view;
+ info->layout = layout;
+ info->slider = slider;
+ info->button = button;
+ info->ee = ee;
+ evas_object_event_callback_add(layout, EVAS_CALLBACK_DEL, _layout_del_cb, (void *)info);
sprintf(buf, "%d / %ld", 0, view->getTotalFrame());
elm_object_part_text_set(layout, "text", buf);
view->seek(0.0);
view->render();
+ return layout;
+}
+
+static void
+_gl_selected_cb(void *data, Evas_Object *obj, void *event_info)
+{
+ Evas_Object *nf = (Evas_Object *)data;
+ Elm_Object_Item *it = (Elm_Object_Item *)event_info;
+ elm_genlist_item_selected_set(it, EINA_FALSE);
+
+ Evas_Object *layout = create_layout(nf, (char *)eina_list_nth(jsonFiles, (elm_genlist_item_index_get(it) - 1)));
+ elm_naviframe_item_push(nf, NULL, NULL, NULL, layout, NULL);
+}
+
+static char *
+_gl_text_get(void *data, Evas_Object *obj, const char *part)
+{
+ ItemData *id = (ItemData *) data;
+ char *str = (char *)eina_list_nth(jsonFiles, id->index);
+ return strdup(str);
+}
+
+static void
+_gl_del(void *data, Evas_Object *obj)
+{
+}
+
+EAPI_MAIN int
+elm_main(int argc EINA_UNUSED, char **argv EINA_UNUSED)
+{
+ Evas_Object *win, *nf, *genlist;
+ Elm_Genlist_Item_Class *itc = elm_genlist_item_class_new();
+ ItemData *itemData;
+ DIR *dir;
+ struct dirent *ent;
+ int i, fileCount = 0;
+
+ if (argc > 1) {
+ if (!strcmp(argv[1], "--disable-render"))
+ renderMode = false;
+ }
+
+ //WIN
+ elm_policy_set(ELM_POLICY_QUIT, ELM_POLICY_QUIT_LAST_WINDOW_CLOSED);
+ win = elm_win_util_standard_add("lottie", "LottieViewer");
+ elm_win_autodel_set(win, EINA_TRUE);
+ evas_object_resize(win, 500, 700);
+ evas_object_show(win);
+
+ //NAVIFRAME
+ nf = elm_naviframe_add(win);
+ evas_object_size_hint_weight_set(nf, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+ elm_win_resize_object_add(win, nf);
+ evas_object_show(nf);
+
+ //GENLIST
+ genlist = elm_genlist_add(nf);
+ elm_genlist_mode_set(genlist, ELM_LIST_COMPRESS);
+ evas_object_smart_callback_add(genlist, "selected", _gl_selected_cb, nf);
+
+ itc->item_style = "default";
+ itc->func.text_get = _gl_text_get;
+ itc->func.del = _gl_del;
+
+ std::string rscPath = DEMO_DIR;
+
+ dir = opendir(rscPath.c_str());
+ while ((ent = readdir(dir)) != NULL) {
+ if (!strncmp(ent->d_name + (strlen(ent->d_name) - 4), "json", 4)) {
+ jsonFiles = eina_list_append(jsonFiles, strdup(ent->d_name));
+ fileCount++;
+ }
+ }
+ closedir(dir);
+
+ for (i = 0; i < fileCount; i++) {
+ itemData = (ItemData *)calloc(sizeof(ItemData), 1);
+ itemData->index = i;
+ elm_genlist_item_append(genlist, itc, (void *)itemData, NULL, ELM_GENLIST_ITEM_NONE, NULL, NULL);
+ }
+
+ elm_naviframe_item_push(nf, "Lottie Viewer", NULL, NULL, genlist, NULL);
+
elm_run();
return 0;