[dali_2.3.23] Merge branch 'devel/master'
[platform/core/uifw/dali-demo.git] / examples / image-view-url / image-view-url-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/image-loader/texture-manager.h>
20
21 #include "generated/image-view-url-frag.h"
22 #include "shared/view.h"
23
24 using namespace Dali;
25
26 namespace
27 {
28 const char* BIG_TEST_IMAGE(DEMO_IMAGE_DIR "book-landscape-cover.jpg");
29
30 const char* const APPLICATION_TITLE("Image View URL");
31 const char* const TOOLBAR_IMAGE(DEMO_IMAGE_DIR "top-bar.png");
32 const char* const BUTTON_ICON(DEMO_IMAGE_DIR "icon-change.png");
33 const char* const BUTTON_ICON_SELECTED(DEMO_IMAGE_DIR "icon-change-selected.png");
34
35 const char* DELTA_UNIFORM_NAME = "uDelta";
36
37 const Vector2 TARGET_SIZE(800.f, 800.f);
38 } // namespace
39
40 class ImageViewUrlApp : public ConnectionTracker
41 {
42 public:
43   ImageViewUrlApp(Application& application, std::string url)
44   : mApplication(application),
45     mUrl(url),
46     mDeltaPropertyIndex(Property::INVALID_INDEX)
47   {
48     // Connect to the Application's Init signal
49     mApplication.InitSignal().Connect(this, &ImageViewUrlApp::Create);
50   }
51
52   ~ImageViewUrlApp() = default;
53
54 private:
55   // The Init signal is received once (only) during the Application lifetime
56   void Create(Application& application)
57   {
58     // Get a handle to the window
59     Window window = application.GetWindow();
60     window.KeyEventSignal().Connect(this, &ImageViewUrlApp::OnKeyEvent);
61
62     Toolkit::ToolBar toolBar;
63     Toolkit::Control background;
64     // Creates a default view with a default tool bar.
65     mContent = DemoHelper::CreateView(application,
66                                       background,
67                                       toolBar,
68                                       "",
69                                       TOOLBAR_IMAGE,
70                                       APPLICATION_TITLE);
71
72     // Add a button to switch the scene. (right of toolbar)
73     Toolkit::PushButton switchButton = Toolkit::PushButton::New();
74     switchButton.SetProperty(Toolkit::Button::Property::UNSELECTED_BACKGROUND_VISUAL, BUTTON_ICON);
75     switchButton.SetProperty(Toolkit::Button::Property::SELECTED_BACKGROUND_VISUAL, BUTTON_ICON_SELECTED);
76     switchButton.ClickedSignal().Connect(this, &ImageViewUrlApp::OnButtonClicked);
77     toolBar.AddControl(switchButton,
78                        DemoHelper::DEFAULT_VIEW_STYLE.mToolBarButtonPercentage,
79                        Toolkit::Alignment::HORIZONTAL_RIGHT,
80                        DemoHelper::DEFAULT_MODE_SWITCH_PADDING);
81
82     std::string url = mUrl;
83     if(url.empty())
84     {
85       url = BIG_TEST_IMAGE;
86     }
87
88     CreateRenderTask(url);
89     CreateScene();
90   }
91
92   void CreateRenderTask(const std::string& url)
93   {
94     auto rootActor = mApplication.GetWindow().GetRootLayer();
95
96     auto cameraActor = CameraActor::New(TARGET_SIZE);
97     cameraActor.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER);
98     cameraActor.SetInvertYAxis(true);
99     rootActor.Add(cameraActor);
100
101     {
102       // create actor to render input with applied shader
103       mActorForInput = Toolkit::ImageView::New(url);
104       mActorForInput.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER);
105       mActorForInput.SetProperty(Actor::Property::SIZE, TARGET_SIZE);
106       Property::Map customShader;
107       customShader[Toolkit::Visual::Shader::Property::FRAGMENT_SHADER] = Dali::Shader::GetFragmentShaderPrefix() + SHADER_IMAGE_VIEW_URL_FRAG.data();
108       Property::Map visualMap;
109       visualMap.Insert(Toolkit::Visual::Property::SHADER, customShader);
110       mActorForInput.SetProperty(Toolkit::ImageView::Property::IMAGE, visualMap);
111
112       mDeltaPropertyIndex = mActorForInput.RegisterProperty(DELTA_UNIFORM_NAME, 0.f);
113
114       rootActor.Add(mActorForInput);
115
116       RenderTaskList taskList = mApplication.GetWindow().GetRenderTaskList();
117
118       // perform a horizontal blur targeting the internal buffer
119       auto renderTask = taskList.CreateTask();
120       renderTask.SetRefreshRate(RenderTask::REFRESH_ALWAYS);
121       renderTask.SetSourceActor(mActorForInput);
122       renderTask.SetExclusive(true);
123       renderTask.SetInputEnabled(false);
124       renderTask.SetClearColor(Vector4(1., 0., 0., 1.));
125       renderTask.SetClearEnabled(true);
126       renderTask.SetCameraActor(cameraActor);
127
128       mOutputTexture   = Texture::New(TextureType::TEXTURE_2D,
129                                     Pixel::RGB888,
130                                     unsigned(TARGET_SIZE.width),
131                                     unsigned(TARGET_SIZE.height));
132       auto framebuffer = FrameBuffer::New(TARGET_SIZE.width, TARGET_SIZE.height, FrameBuffer::Attachment::NONE);
133       framebuffer.AttachColorTexture(mOutputTexture);
134
135       renderTask.SetFrameBuffer(framebuffer);
136     }
137     {
138       // animate the shader uniform
139       mAnimation = Animation::New(10.f);
140
141       mActorForInput.SetProperty(mDeltaPropertyIndex, 0.f);
142       mAnimation.AnimateTo(Property(mActorForInput, mDeltaPropertyIndex), Math::PI * 2.f);
143       mAnimation.SetLooping(true);
144       mAnimation.Play();
145     }
146   }
147
148   void CreateScene()
149   {
150     auto url   = Dali::Toolkit::TextureManager::AddTexture(mOutputTexture);
151     mImageView = Toolkit::ImageView::New(url);
152
153     mImageView.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER);
154     mImageView.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::CENTER);
155     mContent.Add(mImageView);
156   }
157
158   bool OnButtonClicked(Toolkit::Button button)
159   {
160     if(mAnimation.GetState() == Animation::State::PLAYING)
161     {
162       mAnimation.Pause();
163     }
164     else
165     {
166       mAnimation.Play();
167     }
168     return true;
169   }
170
171   void OnKeyEvent(const KeyEvent& event)
172   {
173     if(event.GetState() == KeyEvent::DOWN)
174     {
175       if(IsKey(event, Dali::DALI_KEY_ESCAPE) || IsKey(event, Dali::DALI_KEY_BACK))
176       {
177         mApplication.Quit();
178       }
179     }
180   }
181
182 private:
183   Application&       mApplication;
184   std::string        mUrl;
185   Layer              mContent;
186   Toolkit::ImageView mImageView;
187   Animation          mAnimation;
188   Actor              mActorForInput;
189   Property::Index    mDeltaPropertyIndex;
190   Texture            mOutputTexture;
191 };
192
193 int DALI_EXPORT_API main(int argc, char** argv)
194 {
195   Application application = Application::New(&argc, &argv);
196
197   std::string url;
198   if(argc > 1)
199   {
200     url = argv[1];
201   }
202
203   ImageViewUrlApp test(application, url);
204   application.MainLoop();
205   return 0;
206 }