Add Sample with Encoded Image Buffer
[platform/core/uifw/dali-demo.git] / examples / image-view-encoded-image-buffer / image-view-encoded-image-buffer-example.cpp
1 /*
2  * Copyright (c) 2021 Samsung Electronics Co., Ltd.
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
18 #include <dali-toolkit/dali-toolkit.h>
19 #include <dali-toolkit/public-api/image-loader/image.h>
20 #include <dali/public-api/adaptor-framework/encoded-image-buffer.h>
21 #include <dali-toolkit/public-api/image-loader/image-url.h>
22 #include <dali-toolkit/devel-api/visuals/image-visual-properties-devel.h>
23 #include <dali/dali.h>
24 #include <string>
25 #include "shared/view.h"
26
27 using namespace Dali;
28 using namespace Dali::Toolkit;
29
30 namespace
31 {
32 const char* BACKGROUND_IMAGE(DEMO_IMAGE_DIR "background-gradient.jpg");
33 const char* TOOLBAR_IMAGE(DEMO_IMAGE_DIR "top-bar.png");
34 const char* APPLICATION_TITLE("Image view with encoded image buffer");
35
36 const char* IMAGE_PATH[] = {
37   DEMO_IMAGE_DIR "gallery-small-23.jpg",
38   DEMO_IMAGE_DIR "woodEffect.jpg",
39   DEMO_IMAGE_DIR "wood.png", // 32bits image
40 };
41
42 const unsigned int NUMBER_OF_RESOURCES = sizeof(IMAGE_PATH) / sizeof(char*);
43
44 const unsigned int NUMBER_OF_IMAGES_ROW    = 3;
45 const unsigned int NUMBER_OF_IMAGES_COLUMN = 2;
46 const unsigned int NUMBER_OF_IMAGES        = NUMBER_OF_IMAGES_ROW * NUMBER_OF_IMAGES_COLUMN;
47
48 constexpr Vector2 IMAGE_VIEW_SIZE(200.0f, 200.0f);
49
50 const unsigned int TIMER_INTERVAL = 1000; // ms
51
52 EncodedImageBuffer ConvertFileToEncodedImageBuffer(const char* url)
53 {
54   EncodedImageBuffer buffer;
55   FILE *fp;
56   fp = fopen(url, "rb");
57   if(fp != NULL)
58   {
59     fseek(fp, 0, SEEK_END);
60     size_t size = ftell(fp);
61     Dali::Vector<uint8_t> data;
62     data.Resize(size);
63     fseek(fp, 0, SEEK_SET);
64     size_t realSize = fread(data.Begin(), size, sizeof(uint8_t), fp);
65     fclose(fp);
66     data.Resize(realSize);
67     buffer = EncodedImageBuffer::New(data);
68   }
69   return buffer;
70 }
71
72 } // namespace
73
74 class ImageViewEncodedImageBufferApp : public ConnectionTracker
75 {
76 public:
77   ImageViewEncodedImageBufferApp(Application& application)
78   : mApplication(application)
79   {
80     // Connect to the Application's Init signal
81     mApplication.InitSignal().Connect(this, &ImageViewEncodedImageBufferApp::Create);
82   }
83
84   ~ImageViewEncodedImageBufferApp()
85   {
86     // Nothing to do here
87   }
88
89   void Create(Application& application)
90   {
91     // The Init signal is received once (only) during the Application lifetime
92
93     ImageUrl backgroundImageUrl = Image::GenerateUrl(ConvertFileToEncodedImageBuffer(BACKGROUND_IMAGE));
94     ImageUrl toolbarImageUrl    = Image::GenerateUrl(ConvertFileToEncodedImageBuffer(TOOLBAR_IMAGE));
95
96     // Creates a default view with a default tool bar.
97     // The view is added to the window.
98     mContentLayer = DemoHelper::CreateView(application,
99                                            mView,
100                                            mToolBar,
101                                            backgroundImageUrl.GetUrl(),
102                                            toolbarImageUrl.GetUrl(),
103                                            APPLICATION_TITLE);
104
105     // Initialize
106     mState = 0;
107     mImageIndex = 0;
108     UpdateImageUrl();
109     UpdateImageViews();
110
111     // Create automatic unparent and create ticker.
112     mTimer = Timer::New(TIMER_INTERVAL);
113     mTimer.TickSignal().Connect(this, &ImageViewEncodedImageBufferApp::OnTick);
114     mTimer.Start();
115
116     application.GetWindow().GetRootLayer().TouchedSignal().Connect(this, &ImageViewEncodedImageBufferApp::OnTouch);
117
118     application.GetWindow().KeyEventSignal().Connect(this, &ImageViewEncodedImageBufferApp::OnKeyEvent);
119   }
120
121 private:
122
123   void UpdateImageUrl()
124   {
125     mImageBuffer = ConvertFileToEncodedImageBuffer(IMAGE_PATH[mImageIndex]);
126     mImageUrl    = Image::GenerateUrl(mImageBuffer);
127   }
128   void UpdateImageViews()
129   {
130     for(int i = 0; i < static_cast<int>(NUMBER_OF_IMAGES_ROW); i++)
131     {
132       for(int j = 0; j < static_cast<int>(NUMBER_OF_IMAGES_COLUMN); j++)
133       {
134         int viewId = i * NUMBER_OF_IMAGES_COLUMN + j;
135         // Remove old image and set null
136         if(mImageViews[viewId])
137         {
138           mImageViews[viewId].Unparent();
139           mImageViews[viewId] = ImageView(); // Set null image view
140         }
141
142         bool needToCreate = true;
143
144         // If current state don't wanna create current view, just skip
145         unsigned int  currentViewState = 1u << ((i + j) & 1);
146         if(mState & currentViewState)
147         {
148           needToCreate = false;
149         }
150
151         if(needToCreate)
152         {
153           mImageViews[viewId] = CreateImageView(i, j);
154           mContentLayer.Add(mImageViews[viewId]);
155         }
156       }
157     }
158   }
159   ImageView CreateImageView(int offset_y, int offset_x)
160   {
161     ImageView view = ImageView::New();
162     view.SetProperty(Actor::Property::SIZE, IMAGE_VIEW_SIZE);
163     view.SetProperty(Actor::Property::POSITION, Vector2(IMAGE_VIEW_SIZE.x * offset_x, IMAGE_VIEW_SIZE.y * offset_y + mToolBar.GetNaturalSize().y));
164     view.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
165
166     Property::Map imagePropertyMap;
167     imagePropertyMap.Insert(Visual::Property::TYPE, Visual::IMAGE);
168     imagePropertyMap.Insert(ImageVisual::Property::URL, mImageUrl.GetUrl());
169
170     view.SetProperty(ImageView::Property::IMAGE, imagePropertyMap);
171
172     return view;
173   }
174
175   bool OnTick()
176   {
177     mState = (mState + 1) % 4;
178     UpdateImageViews();
179     return true; // Keep tick always
180   }
181
182   bool OnTouch(Actor actor, const TouchEvent& touch)
183   {
184     if(touch.GetState(0) == PointState::UP)
185     {
186       // Change resource
187       mImageIndex = (mImageIndex + 1) % NUMBER_OF_RESOURCES;
188       // Change resource's url
189       UpdateImageUrl();
190       // Update image views
191       UpdateImageViews();
192     }
193     return true;
194   }
195
196   /**
197    * Main key event handler
198    */
199   void OnKeyEvent(const KeyEvent& event)
200   {
201     if(event.GetState() == KeyEvent::DOWN)
202     {
203       if(IsKey(event, DALI_KEY_ESCAPE) || IsKey(event, DALI_KEY_BACK))
204       {
205         if(mTimer.IsRunning())
206         {
207           mTimer.Stop();
208           mTimer.TickSignal().Disconnect(this, &ImageViewEncodedImageBufferApp::OnTick);
209         }
210         mApplication.Quit();
211       }
212     }
213   }
214
215 private:
216   Application& mApplication;
217
218   Toolkit::Control   mView;         ///< The View instance.
219   Toolkit::ToolBar   mToolBar;      ///< The View's Toolbar.
220   Layer              mContentLayer; ///< Content layer
221
222   Toolkit::ImageView mImageViews[NUMBER_OF_IMAGES];
223
224   unsigned int       mImageIndex;
225   EncodedImageBuffer mImageBuffer;
226   ImageUrl           mImageUrl;
227
228   // Automatic unparent and create ticker.
229   Timer              mTimer;
230   unsigned int       mState; ///< 0 : draw all images, 1 : draw half, 2 : draw another half, 3 : don't draw images.
231 };
232
233 int DALI_EXPORT_API main(int argc, char** argv)
234 {
235   Application                    application = Application::New(&argc, &argv, DEMO_THEME_PATH);
236   ImageViewEncodedImageBufferApp test(application);
237   application.MainLoop();
238   return 0;
239 }