Add BUILD_EXAMPLE_NAME option explain for README.md
[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/devel-api/visuals/image-visual-properties-devel.h>
20 #include <dali-toolkit/public-api/image-loader/image-url.h>
21 #include <dali-toolkit/public-api/image-loader/image.h>
22 #include <dali/dali.h>
23 #include <dali/public-api/adaptor-framework/encoded-image-buffer.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(), sizeof(uint8_t), size, 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   void UpdateImageUrl()
123   {
124     mImageBuffer = ConvertFileToEncodedImageBuffer(IMAGE_PATH[mImageIndex]);
125     mImageUrl    = Image::GenerateUrl(mImageBuffer);
126   }
127   void UpdateImageViews()
128   {
129     for(int i = 0; i < static_cast<int>(NUMBER_OF_IMAGES_ROW); i++)
130     {
131       for(int j = 0; j < static_cast<int>(NUMBER_OF_IMAGES_COLUMN); j++)
132       {
133         int viewId = i * NUMBER_OF_IMAGES_COLUMN + j;
134         // Remove old image and set null
135         if(mImageViews[viewId])
136         {
137           mImageViews[viewId].Unparent();
138           mImageViews[viewId] = ImageView(); // Set null image view
139         }
140
141         bool needToCreate = true;
142
143         // If current state don't wanna create current view, just skip
144         unsigned int currentViewState = 1u << ((i + j) & 1);
145         if(mState & currentViewState)
146         {
147           needToCreate = false;
148         }
149
150         if(needToCreate)
151         {
152           mImageViews[viewId] = CreateImageView(i, j);
153           mContentLayer.Add(mImageViews[viewId]);
154         }
155       }
156     }
157   }
158   ImageView CreateImageView(int offset_y, int offset_x)
159   {
160     ImageView view = ImageView::New();
161     view.SetProperty(Actor::Property::SIZE, IMAGE_VIEW_SIZE);
162     view.SetProperty(Actor::Property::POSITION, Vector2(IMAGE_VIEW_SIZE.x * offset_x, IMAGE_VIEW_SIZE.y * offset_y + mToolBar.GetNaturalSize().y));
163     view.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
164
165     Property::Map imagePropertyMap;
166     imagePropertyMap.Insert(Visual::Property::TYPE, Visual::IMAGE);
167     imagePropertyMap.Insert(ImageVisual::Property::URL, mImageUrl.GetUrl());
168
169     view.SetProperty(ImageView::Property::IMAGE, imagePropertyMap);
170
171     return view;
172   }
173
174   bool OnTick()
175   {
176     mState = (mState + 1) % 4;
177     UpdateImageViews();
178     return true; // Keep tick always
179   }
180
181   bool OnTouch(Actor actor, const TouchEvent& touch)
182   {
183     if(touch.GetState(0) == PointState::UP)
184     {
185       // Change resource
186       mImageIndex = (mImageIndex + 1) % NUMBER_OF_RESOURCES;
187       // Change resource's url
188       UpdateImageUrl();
189       // Update image views
190       UpdateImageViews();
191     }
192     return true;
193   }
194
195   /**
196    * Main key event handler
197    */
198   void OnKeyEvent(const KeyEvent& event)
199   {
200     if(event.GetState() == KeyEvent::DOWN)
201     {
202       if(IsKey(event, DALI_KEY_ESCAPE) || IsKey(event, DALI_KEY_BACK))
203       {
204         if(mTimer.IsRunning())
205         {
206           mTimer.Stop();
207           mTimer.TickSignal().Disconnect(this, &ImageViewEncodedImageBufferApp::OnTick);
208         }
209         mApplication.Quit();
210       }
211     }
212   }
213
214 private:
215   Application& mApplication;
216
217   Toolkit::Control mView;         ///< The View instance.
218   Toolkit::ToolBar mToolBar;      ///< The View's Toolbar.
219   Layer            mContentLayer; ///< Content layer
220
221   Toolkit::ImageView mImageViews[NUMBER_OF_IMAGES];
222
223   unsigned int       mImageIndex{0u};
224   EncodedImageBuffer mImageBuffer;
225   ImageUrl           mImageUrl;
226
227   // Automatic unparent and create ticker.
228   Timer        mTimer;
229   unsigned int mState{0u}; ///< 0 : draw all images, 1 : draw half, 2 : draw another half, 3 : don't draw images.
230 };
231
232 int DALI_EXPORT_API main(int argc, char** argv)
233 {
234   Application                    application = Application::New(&argc, &argv, DEMO_THEME_PATH);
235   ImageViewEncodedImageBufferApp test(application);
236   application.MainLoop();
237   return 0;
238 }