2 * Copyright (c) 2023 Samsung Electronics Co., Ltd.
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
18 #include <dali-toolkit/dali-toolkit.h>
19 #include <dali-toolkit/devel-api/controls/control-devel.h>
20 #include <dali-toolkit/devel-api/visuals/animated-vector-image-visual-actions-devel.h>
21 #include <dali-toolkit/devel-api/visuals/image-visual-properties-devel.h>
22 #include <dali-toolkit/public-api/image-loader/image-url.h>
23 #include <dali-toolkit/public-api/image-loader/image.h>
24 #include <dali/dali.h>
25 #include <dali/public-api/adaptor-framework/encoded-image-buffer.h>
28 #include "shared/view.h"
31 using namespace Dali::Toolkit;
35 const char* BACKGROUND_IMAGE(DEMO_IMAGE_DIR "background-gradient.jpg");
36 const char* TOOLBAR_IMAGE(DEMO_IMAGE_DIR "top-bar.png");
37 const char* APPLICATION_TITLE("Image view with encoded image buffer");
39 const char* IMAGE_PATH[] = {
40 DEMO_IMAGE_DIR "gallery-small-23.jpg",
41 DEMO_IMAGE_DIR "woodEffect.jpg",
42 DEMO_IMAGE_DIR "wood.png", // 32bits image
43 // DEMO_IMAGE_DIR "heartsframe.9.png", ///< Not implemented yet.
44 DEMO_IMAGE_DIR "dog-anim.webp",
45 DEMO_IMAGE_DIR "World.svg", // svg image
46 DEMO_IMAGE_DIR "insta_camera.json" // lottie image
49 const unsigned int NUMBER_OF_RESOURCES = sizeof(IMAGE_PATH) / sizeof(char*);
51 const unsigned int VECTOR_IMAGE_INDEX = NUMBER_OF_RESOURCES - 2u;
52 const unsigned int ANIMATED_VECTOR_IMAGE_INDEX = NUMBER_OF_RESOURCES - 1u;
54 const unsigned int NUMBER_OF_IMAGES_ROW = 3;
55 const unsigned int NUMBER_OF_IMAGES_COLUMN = 2;
56 const unsigned int NUMBER_OF_IMAGES = NUMBER_OF_IMAGES_ROW * NUMBER_OF_IMAGES_COLUMN;
58 constexpr Vector2 IMAGE_VIEW_SIZE(200.0f, 200.0f);
60 const unsigned int TIMER_INTERVAL = 1000; // ms
62 EncodedImageBuffer ConvertFileToEncodedImageBuffer(const char* url)
64 EncodedImageBuffer buffer;
66 fp = fopen(url, "rb");
69 fseek(fp, 0, SEEK_END);
70 size_t size = ftell(fp);
71 Dali::Vector<uint8_t> data;
73 fseek(fp, 0, SEEK_SET);
74 size_t realSize = fread(data.Begin(), sizeof(uint8_t), size, fp);
76 data.Resize(realSize);
77 buffer = EncodedImageBuffer::New(data);
84 class ImageViewEncodedImageBufferApp : public ConnectionTracker
87 ImageViewEncodedImageBufferApp(Application& application)
88 : mApplication(application)
90 // Connect to the Application's Init signal
91 mApplication.InitSignal().Connect(this, &ImageViewEncodedImageBufferApp::Create);
94 ~ImageViewEncodedImageBufferApp()
99 void Create(Application& application)
101 // The Init signal is received once (only) during the Application lifetime
103 ImageUrl backgroundImageUrl = Image::GenerateUrl(ConvertFileToEncodedImageBuffer(BACKGROUND_IMAGE));
104 ImageUrl toolbarImageUrl = Image::GenerateUrl(ConvertFileToEncodedImageBuffer(TOOLBAR_IMAGE));
106 // Creates a default view with a default tool bar.
107 // The view is added to the window.
108 mContentLayer = DemoHelper::CreateView(application,
111 backgroundImageUrl.GetUrl(),
112 toolbarImageUrl.GetUrl(),
121 // Create automatic unparent and create ticker.
122 mTimer = Timer::New(TIMER_INTERVAL);
123 mTimer.TickSignal().Connect(this, &ImageViewEncodedImageBufferApp::OnTick);
126 application.GetWindow().GetRootLayer().TouchedSignal().Connect(this, &ImageViewEncodedImageBufferApp::OnTouch);
128 application.GetWindow().KeyEventSignal().Connect(this, &ImageViewEncodedImageBufferApp::OnKeyEvent);
132 void UpdateImageUrl()
134 if(mImageIndex < NUMBER_OF_RESOURCES)
136 mImageBuffer = ConvertFileToEncodedImageBuffer(IMAGE_PATH[mImageIndex]);
139 if(mImageIndex == VECTOR_IMAGE_INDEX)
141 mImageBuffer.SetImageType(EncodedImageBuffer::ImageType::VECTOR_IMAGE);
143 else if(mImageIndex == ANIMATED_VECTOR_IMAGE_INDEX)
145 mImageBuffer.SetImageType(EncodedImageBuffer::ImageType::ANIMATED_VECTOR_IMAGE);
148 mImageUrl = Image::GenerateUrl(mImageBuffer);
151 void UpdateImageViews()
153 for(int i = 0; i < static_cast<int>(NUMBER_OF_IMAGES_ROW); i++)
155 for(int j = 0; j < static_cast<int>(NUMBER_OF_IMAGES_COLUMN); j++)
157 int viewId = i * NUMBER_OF_IMAGES_COLUMN + j;
158 // Remove old image and set null
159 if(mImageViews[viewId])
161 mImageViews[viewId].Unparent();
162 mImageViews[viewId] = ImageView(); // Set null image view
165 bool needToCreate = true;
167 // If current state don't wanna create current view, just skip
168 unsigned int currentViewState = 1u << ((i + j) & 1);
169 if(mState & currentViewState)
171 needToCreate = false;
176 mImageViews[viewId] = CreateImageView(i, j);
177 mContentLayer.Add(mImageViews[viewId]);
182 ImageView CreateImageView(int offset_y, int offset_x)
184 ImageView view = ImageView::New();
185 view.SetProperty(Actor::Property::SIZE, IMAGE_VIEW_SIZE);
186 view.SetProperty(Actor::Property::POSITION, Vector2(IMAGE_VIEW_SIZE.x * offset_x, IMAGE_VIEW_SIZE.y * offset_y + mToolBar.GetNaturalSize().y));
187 view.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
189 Property::Map imagePropertyMap;
190 imagePropertyMap.Insert(Visual::Property::TYPE, Visual::IMAGE);
191 imagePropertyMap.Insert(ImageVisual::Property::URL, mImageUrl.GetUrl());
193 view.SetProperty(ImageView::Property::IMAGE, imagePropertyMap);
195 if(mImageIndex == ANIMATED_VECTOR_IMAGE_INDEX)
197 DevelControl::DoAction(view, ImageView::Property::IMAGE, DevelAnimatedVectorImageVisual::Action::PLAY, Property::Value());
205 mState = (mState + 1) % 4;
207 return true; // Keep tick always
210 bool OnTouch(Actor actor, const TouchEvent& touch)
212 if(touch.GetState(0) == PointState::UP)
215 mImageIndex = (mImageIndex + 1) % NUMBER_OF_RESOURCES;
216 // Change resource's url
218 // Update image views
225 * Main key event handler
227 void OnKeyEvent(const KeyEvent& event)
229 if(event.GetState() == KeyEvent::DOWN)
231 if(IsKey(event, DALI_KEY_ESCAPE) || IsKey(event, DALI_KEY_BACK))
233 if(mTimer.IsRunning())
236 mTimer.TickSignal().Disconnect(this, &ImageViewEncodedImageBufferApp::OnTick);
244 Application& mApplication;
246 Toolkit::Control mView; ///< The View instance.
247 Toolkit::ToolBar mToolBar; ///< The View's Toolbar.
248 Layer mContentLayer; ///< Content layer
250 Toolkit::ImageView mImageViews[NUMBER_OF_IMAGES];
252 unsigned int mImageIndex{0u};
253 EncodedImageBuffer mImageBuffer;
256 // Automatic unparent and create ticker.
258 unsigned int mState{0u}; ///< 0 : draw all images, 1 : draw half, 2 : draw another half, 3 : don't draw images.
261 int DALI_EXPORT_API main(int argc, char** argv)
263 Application application = Application::New(&argc, &argv, DEMO_THEME_PATH);
264 ImageViewEncodedImageBufferApp test(application);
265 application.MainLoop();