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