example: upgrade rive viewer for loading rive files in examples/resource directory.
authorTaehyub Kim <taehyub.kim@samsung.com>
Fri, 12 Mar 2021 08:48:47 +0000 (17:48 +0900)
committerHermet Park <hermetpark@gmail.com>
Fri, 12 Mar 2021 09:52:15 +0000 (18:52 +0900)
example/resource/heart.riv [new file with mode: 0644]
example/resource/juice063.riv [new file with mode: 0644]
example/resource/knight063.riv [new file with mode: 0644]
example/resource/marty_v6.riv [new file with mode: 0644]
example/resource/notification_icon_3.riv [new file with mode: 0644]
example/resource/poison_loader.riv [new file with mode: 0644]
example/resource/shapes.riv [moved from example/shapes.riv with 100% similarity]
example/rive_viewer.cpp
meson.build

diff --git a/example/resource/heart.riv b/example/resource/heart.riv
new file mode 100644 (file)
index 0000000..7a1c858
Binary files /dev/null and b/example/resource/heart.riv differ
diff --git a/example/resource/juice063.riv b/example/resource/juice063.riv
new file mode 100644 (file)
index 0000000..c212ddc
Binary files /dev/null and b/example/resource/juice063.riv differ
diff --git a/example/resource/knight063.riv b/example/resource/knight063.riv
new file mode 100644 (file)
index 0000000..1db14b2
Binary files /dev/null and b/example/resource/knight063.riv differ
diff --git a/example/resource/marty_v6.riv b/example/resource/marty_v6.riv
new file mode 100644 (file)
index 0000000..a324304
Binary files /dev/null and b/example/resource/marty_v6.riv differ
diff --git a/example/resource/notification_icon_3.riv b/example/resource/notification_icon_3.riv
new file mode 100644 (file)
index 0000000..eff4c79
Binary files /dev/null and b/example/resource/notification_icon_3.riv differ
diff --git a/example/resource/poison_loader.riv b/example/resource/poison_loader.riv
new file mode 100644 (file)
index 0000000..cd76f0d
Binary files /dev/null and b/example/resource/poison_loader.riv differ
index 5cae43f..76eb22b 100644 (file)
@@ -1,4 +1,6 @@
 #include <thread>
+#include <dirent.h>
+#include <algorithm>
 #include <Elementary.h>
 #include <rive_tizen.hpp>
 
 
 using namespace std;
 
-#define WIDTH 700
+#define WIDTH 1000
 #define HEIGHT 700
+#define LIST_HEIGHT 200
 
 static unique_ptr<tvg::SwCanvas> canvas;
 static tvg::Canvas *renderCanvas;
-static rive::File* file = nullptr;
+static rive::File* currentFile = nullptr;
 static rive::Artboard* artboard = nullptr;
 static rive::LinearAnimationInstance* animationInstance = nullptr;
 static Ecore_Animator *animator = nullptr;
 static Eo* view = nullptr;
+static vector<std::string> rivefiles;
 static double lastTime;
 
 static void deleteWindow(void *data, Evas_Object *obj, void *ev)
 {
-   elm_exit();
+    elm_exit();
 }
 
 static void drawToCanvas(void* data, Eo* obj)
@@ -34,43 +38,19 @@ static void drawToCanvas(void* data, Eo* obj)
     }
 }
 
-Eina_Bool animationLoop(void *data)
+static bool isRiveFile(const char *filename)
 {
-    double currentTime = ecore_time_get();
-    float elapsed = currentTime - lastTime;
-    static float animationTime = 0;
-    lastTime = currentTime;
-
-    if (artboard != nullptr)
-    {
-       if (animationInstance != nullptr)
-       {
-          animationInstance->advance(elapsed);
-          animationInstance->apply(artboard);
-       }
-       artboard->advance(elapsed);
-
-       rive::TvgRenderer renderer(renderCanvas);
-       renderer.save();
-       artboard->draw(&renderer);
-       renderer.restore();
-    }
-
-    evas_object_image_pixels_dirty_set(view, EINA_TRUE);
-    evas_object_image_data_update_add(view, 0, 0, WIDTH, HEIGHT);
-
-    return ECORE_CALLBACK_RENEW;
+    const char *dot = strrchr(filename, '.');
+    if(!dot || dot == filename) return false;
+    return !strcmp(dot + 1, "riv");
 }
 
-static void runExample(uint32_t* buffer)
+static void loadRiveFile(const char* filename)
 {
-    //Create a Canvas
-    canvas = tvg::SwCanvas::gen();
-    canvas->target(buffer, WIDTH, WIDTH, HEIGHT, tvg::SwCanvas::ARGB8888);
-    renderCanvas = canvas.get();
+    // Clear Canvas Buffer
+    renderCanvas->clear();
 
     // Load Rive File
-    const char* filename = "../../example/shapes.riv";
     FILE* fp = fopen(filename, "r");
 
     fseek(fp, 0, SEEK_END);
@@ -86,6 +66,7 @@ static void runExample(uint32_t* buffer)
     }
 
     auto reader = rive::BinaryReader(bytes, length);
+    rive::File* file = nullptr;
     auto result = rive::File::import(reader, &file);
     if (result != rive::ImportResult::success)
     {
@@ -98,6 +79,7 @@ static void runExample(uint32_t* buffer)
     artboard->advance(0.0f);
 
     delete animationInstance;
+    delete currentFile;
 
     auto animation = artboard->firstAnimation<rive::LinearAnimation>();
     if (animation != nullptr)
@@ -109,37 +91,123 @@ static void runExample(uint32_t* buffer)
        animationInstance = nullptr;
     }
 
+    currentFile = file;
+    delete[] bytes;
+}
+
+static void fileClickedCb (void *data, Evas_Object *obj, void *event_info)
+{
+    Elm_Object_Item *item = elm_list_selected_item_get(obj);
+    int index = 0;
+    for (Elm_Object_Item *iter = item; iter != NULL; iter = elm_list_item_prev(iter))
+       index++;
+    if (rivefiles.size() > 0)
+      loadRiveFile(rivefiles[index-1].c_str());
+}
+
+static std::vector<std::string> riveFiles(const std::string &dirName)
+{
+    DIR *d;
+    struct dirent *dir;
+    std::vector<std::string> result;
+    d = opendir(dirName.c_str());
+    if (d) {
+      while ((dir = readdir(d)) != NULL) {
+        if (isRiveFile(dir->d_name))
+          result.push_back(dirName + dir->d_name);
+      }
+      closedir(d);
+    }
+
+    std::sort(result.begin(), result.end(), [](auto & a, auto &b){return a < b;});
+
+    return result;
+}
+
+Eina_Bool animationLoop(void *data)
+{
+    double currentTime = ecore_time_get();
+    float elapsed = currentTime - lastTime;
+    static float animationTime = 0;
+    lastTime = currentTime;
+
+    if (artboard != nullptr)
+    {
+       if (animationInstance != nullptr)
+       {
+          animationInstance->advance(elapsed);
+          animationInstance->apply(artboard);
+       }
+       artboard->advance(elapsed);
+
+       rive::TvgRenderer renderer(renderCanvas);
+       renderer.save();
+       artboard->draw(&renderer);
+       renderer.restore();
+    }
+
+    evas_object_image_pixels_dirty_set(view, EINA_TRUE);
+    evas_object_image_data_update_add(view, 0, 0, WIDTH, HEIGHT);
+
+    return ECORE_CALLBACK_RENEW;
+}
+
+static void runExample(uint32_t* buffer)
+{
+    //Create a Canvas
+    canvas = tvg::SwCanvas::gen();
+    canvas->target(buffer, WIDTH, WIDTH, HEIGHT, tvg::SwCanvas::ARGB8888);
+    renderCanvas = canvas.get();
+
     lastTime = ecore_time_get();
     ecore_animator_frametime_set(1. / 60);
     animator = ecore_animator_add(animationLoop, nullptr);
-
-    delete[] bytes;
 }
 
-
 static void cleanExample()
 {
-    delete file;
     delete animationInstance;
 }
 
-
 static void setupScreen(uint32_t* buffer)
 {
     Eo* win = elm_win_util_standard_add(NULL, "Rive Viewer");
     evas_object_smart_callback_add(win, "delete,request", deleteWindow, 0);
 
-    view = evas_object_image_filled_add(evas_object_evas_get(win));
+    Eo* box = elm_box_add(win);
+    evas_object_size_hint_weight_set(box, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+    elm_win_resize_object_add(win, box);
+    evas_object_show(box);
+
+    view = evas_object_image_filled_add(evas_object_evas_get(box));
     evas_object_image_size_set(view, WIDTH, HEIGHT);
     evas_object_image_data_set(view, buffer);
     evas_object_image_pixels_get_callback_set(view, drawToCanvas, nullptr);
     evas_object_image_pixels_dirty_set(view, EINA_TRUE);
     evas_object_image_data_update_add(view, 0, 0, WIDTH, HEIGHT);
-    evas_object_size_hint_weight_set(view, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+    evas_object_size_hint_weight_set(view, EVAS_HINT_EXPAND, 0.0);
+    evas_object_size_hint_min_set(view, WIDTH, HEIGHT);
     evas_object_show(view);
 
-    elm_win_resize_object_add(win, view);
-    evas_object_resize(win, WIDTH, HEIGHT);
+    elm_box_pack_end(box, view);
+
+    Eo *fileList = elm_list_add(box);
+    evas_object_size_hint_weight_set(fileList, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+    evas_object_size_hint_align_set(fileList, EVAS_HINT_FILL, EVAS_HINT_FILL);
+
+    // Search Rive Files in Resource Dir
+    rivefiles = riveFiles(RIVE_FILE_DIR);
+    for (int i = 0; i < rivefiles.size(); i++)
+    {
+       const char *ptr = strrchr(rivefiles[i].c_str(), '/');
+       Elm_Object_Item *item = elm_list_item_append(fileList, ptr + 1, NULL, NULL, fileClickedCb, NULL);
+    }
+    elm_list_go(fileList);
+
+    elm_box_pack_end(box, fileList);
+    evas_object_show(fileList);
+
+    evas_object_resize(win, WIDTH, HEIGHT + LIST_HEIGHT);
     evas_object_show(win);
 }
 
index 94c5329..952f3d0 100644 (file)
@@ -4,6 +4,8 @@ project('rive_tizen',
         version : '0.1.0',
         license : 'MIT')
 
+add_project_arguments('-DRIVE_FILE_DIR="@0@/example/resource/"'.format(meson.current_source_dir()), language : 'cpp')
+
 thorvg_dep = dependency('thorvg', required : true)
 
 run_command('script/install.sh')