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