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