05483dcbf0d6b3a697417289e46aff1165b15761
[platform/core/uifw/dali-demo.git] / examples / atlas / atlas-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/dali.h>
19 #include <dali/devel-api/images/atlas.h>
20 #include <dali-toolkit/devel-api/controls/buttons/button-devel.h>
21
22 #include "shared/view.h"
23 #include <iostream>
24 #include <cstdio>
25
26 using namespace Dali;
27
28 class AtlasController;
29
30 namespace
31 {
32 const char * const BACKGROUND_IMAGE( DEMO_IMAGE_DIR "background-gradient.jpg" );
33 const char * const TOOLBAR_IMAGE( DEMO_IMAGE_DIR "top-bar.png" );
34 const char * const LOSE_CONTEXT_IMAGE( DEMO_IMAGE_DIR "icon-cluster-wobble.png" );
35 const char * const LOSE_CONTEXT_IMAGE_SELECTED( DEMO_IMAGE_DIR "icon-cluster-wobble-selected.png" );
36
37 Application gApplication;
38 AtlasController* gAtlasController(NULL);
39 }
40
41 class AtlasController : public ConnectionTracker
42 {
43 public:
44
45   AtlasController( Application& application )
46   : mApplication( application )
47   {
48     // Connect to the Application's Init signal
49     mApplication.InitSignal().Connect( this, &AtlasController::Create );
50   }
51
52   ~AtlasController()
53   {
54     // Nothing to do here;
55   }
56
57   void Create( Application& application )
58   {
59     // Get a handle to the stage
60     Stage stage = Stage::GetCurrent();
61     stage.SetBackgroundColor(Color::YELLOW);
62
63     // Respond to a click anywhere on the stage
64     stage.KeyEventSignal().Connect(this, &AtlasController::OnKeyEvent);
65
66     mApplication.GetWindow().ShowIndicator( Dali::Window::INVISIBLE );
67
68     mContentLayer = DemoHelper::CreateView( mApplication,
69         mView,
70         mToolBar,
71         BACKGROUND_IMAGE,
72         TOOLBAR_IMAGE,
73         "Atlas" );
74
75     mLoseContextButton = Toolkit::PushButton::New();
76     mLoseContextButton.SetProperty( Toolkit::DevelButton::Property::UNSELECTED_BACKGROUND_VISUAL, LOSE_CONTEXT_IMAGE );
77     mLoseContextButton.SetProperty( Toolkit::DevelButton::Property::SELECTED_BACKGROUND_VISUAL, LOSE_CONTEXT_IMAGE_SELECTED );
78     mLoseContextButton.ClickedSignal().Connect( this, &AtlasController::OnLoseContextButtonClicked );
79     mToolBar.AddControl( mLoseContextButton, DemoHelper::DEFAULT_VIEW_STYLE.mToolBarButtonPercentage, Toolkit::Alignment::HorizontalRight, DemoHelper::DEFAULT_MODE_SWITCH_PADDING );
80
81     mAtlas = Atlas::New( 400,700, Pixel::RGBA8888);
82     mAtlas.Clear(Vector4(0.f,0.5f,0.5f,0.25f));
83     mAtlas.Upload( DEMO_IMAGE_DIR "icon-change.png", 50, 30 );
84     mAtlas.Upload( DEMO_IMAGE_DIR "icon-cluster-carousel.png", 100, 30 );
85     mAtlas.Upload( DEMO_IMAGE_DIR "icon-effects-on.png", 150, 30 );
86     mAtlas.Upload( DEMO_IMAGE_DIR "icon-effect-cross.png", 100, 80 );
87     mAtlas.Upload( DEMO_IMAGE_DIR "icon-effect-fold.png", 150, 80 );
88     mAtlas.Upload( DEMO_IMAGE_DIR "icon-effect-wave.png", 200, 80 );
89     mAtlas.Upload( DEMO_IMAGE_DIR "icon-item-view-layout-depth.png", 150, 130 );
90     mAtlas.Upload( DEMO_IMAGE_DIR "icon-item-view-layout-grid.png", 200, 130 );
91     mAtlas.Upload( DEMO_IMAGE_DIR "icon-item-view-layout-spiral.png", 250, 130 );
92
93     UploadBufferImages();
94     UploadPixelData();
95
96     mAtlas.Upload( DEMO_IMAGE_DIR "gallery-small-1.jpg", 4, 304 );
97     mAtlas.Upload( DEMO_IMAGE_DIR "gallery-small-2.jpg", 136, 304 );
98     mAtlas.Upload( DEMO_IMAGE_DIR "gallery-small-3.jpg", 268, 304 );
99     mAtlas.Upload( DEMO_IMAGE_DIR "gallery-small-4.jpg", 4, 436 );
100     mAtlas.Upload( DEMO_IMAGE_DIR "gallery-small-5.jpg", 136, 436 );
101     mAtlas.Upload( DEMO_IMAGE_DIR "gallery-small-6.jpg", 268, 436 );
102     mAtlas.Upload( DEMO_IMAGE_DIR "gallery-small-7.jpg", 4, 568 );
103     mAtlas.Upload( DEMO_IMAGE_DIR "gallery-small-7.jpg", 136, 568 );
104     mAtlas.Upload( DEMO_IMAGE_DIR "gallery-small-7.jpg", 268, 568 );
105
106
107     Toolkit::ImageView imageView = Toolkit::ImageView::New( mAtlas );
108
109     imageView.SetParentOrigin(ParentOrigin::CENTER);
110     mContentLayer.Add( imageView );
111
112     mPanGestureDetector = PanGestureDetector::New();
113     mPanGestureDetector.DetectedSignal().Connect( this, &AtlasController::OnPanGesture );
114     mPanGestureDetector.Attach( imageView );
115
116     stage.ContextLostSignal().Connect( this, &AtlasController::OnContextLost );
117     stage.ContextRegainedSignal().Connect( this, &AtlasController::OnContextRegained );
118   }
119
120   void UploadBufferImages()
121   {
122     mAtlas.Upload( CreateBufferImage( Vector4(1.f, 1.f, 1.f, 0.5f  ), 80, 90 ), 0, 210 );
123     mAtlas.Upload( CreateBufferImage( Vector4(1.f, 1.f, 0.75f, 0.5f  ), 80, 80 ), 40, 210 );
124     mAtlas.Upload( CreateBufferImage( Vector4(1.f, 1.f, 0.5f, 0.5f  ), 80, 70 ), 80, 210 );
125     mAtlas.Upload( CreateBufferImage( Vector4(1.f, 1.f, 0.25f, 0.5f  ), 80, 60 ), 120, 210 );
126     mAtlas.Upload( CreateBufferImage( Vector4(1.f, 1.f, 0.f, 0.5f  ), 80, 50 ), 160, 210 );
127     mAtlas.Upload( CreateBufferImage( Vector4(0.75f, 0.75f, 0.f, 0.5f  ), 80, 40 ), 200, 210 );
128     mAtlas.Upload( CreateBufferImage( Vector4(0.5f, 0.5f, 0.f, 0.5f  ), 80, 30 ), 240, 210 );
129     mAtlas.Upload( CreateBufferImage( Vector4(0.25f, 0.25f, 0.f, 0.5f  ), 80, 20 ), 280, 210 );
130     mAtlas.Upload( CreateBufferImage( Vector4(0.1f, 0.1f, 0.f, 0.5f  ), 80, 10 ), 320, 210 );
131   }
132
133   void UploadPixelData()
134   {
135     mAtlas.Upload( CreatePixelData( Vector3(1.f, 1.f, 0.f ), 40, 40 ), 320, 30 );
136     mAtlas.Upload( CreatePixelData( Vector3(0.f, 1.f, 1.f ), 40, 40 ), 320, 80 );
137     mAtlas.Upload( CreatePixelData( Vector3(1.f, 0.f, 1.f ), 40, 40 ), 320, 130 );
138   }
139
140   static void NewWindow(void)
141   {
142     PositionSize posSize(0, 0, 720, 1280);
143     gApplication.ReplaceWindow(posSize, "NewWindow"); // Generates a new window
144   }
145
146   bool OnLoseContextButtonClicked( Toolkit::Button button )
147   {
148     // Add as an idle callback to avoid ProcessEvents being recursively called.
149     mApplication.AddIdle(MakeCallback( AtlasController::NewWindow ));
150     return true;
151   }
152
153   void OnKeyEvent( const KeyEvent& event )
154   {
155     if(event.state == KeyEvent::Down)
156     {
157       if( IsKey( event, Dali::DALI_KEY_ESCAPE) || IsKey( event, Dali::DALI_KEY_BACK) )
158       {
159         mApplication.Quit();
160       }
161     }
162   }
163
164   void OnPanGesture( Actor actor, const PanGesture& gesture )
165   {
166     if( gesture.state == Gesture::Continuing )
167     {
168       actor.TranslateBy( Vector3( gesture.displacement ) );
169     }
170   }
171
172   void OnContextLost()
173   {
174     printf("Stage reporting context loss\n");
175   }
176
177   void OnContextRegained()
178   {
179     printf("Stage reporting context regain\n");
180     UploadBufferImages();
181     UploadPixelData();
182   }
183
184 private:
185
186   BufferImage CreateBufferImage( const Vector4& color, const unsigned int width, const unsigned int height )
187   {
188     BufferImage imageData = BufferImage::New( width, height, Pixel::RGBA8888 );
189
190     // Create the image
191     PixelBuffer* pixbuf = imageData.GetBuffer();
192     const unsigned int bitmapSize = width * height;
193     for( size_t i = 0; i < bitmapSize; ++i )
194     {
195       pixbuf[i*4+0] = 0xFF * color.r;
196       pixbuf[i*4+1] = 0xFF * color.g;
197       pixbuf[i*4+2] = 0xFF * color.b;
198       pixbuf[i*4+3] = 0xFF * color.a;
199     }
200
201     return imageData;
202   }
203
204   PixelData CreatePixelData( const Vector3& color, const unsigned int width, const unsigned int height )
205   {
206     unsigned int size = width*height;
207     unsigned int bufferSize = size * Pixel::GetBytesPerPixel(Pixel::RGB888);
208     unsigned char* pixels = new unsigned char [bufferSize];
209     for( unsigned int i = 0; i < size; i++ )
210     {
211       pixels[i*3u] = 0xFF * color.x;
212       pixels[i*3u+1u] = 0xFF * color.y;
213       pixels[i*3u+2u] = 0xFF * color.z;
214     }
215     return PixelData::New( pixels, bufferSize, width, height, Pixel::RGB888, PixelData::DELETE_ARRAY );
216   }
217
218
219 private:
220   Application&  mApplication;
221   PanGestureDetector mPanGestureDetector;
222
223   Toolkit::Control           mView;                              ///< The View instance.
224   Toolkit::ToolBar           mToolBar;                           ///< The View's Toolbar.
225   Layer                      mContentLayer;                      ///< Content layer (scrolling cluster content)
226   Toolkit::PushButton        mLoseContextButton;
227   Atlas                      mAtlas;
228 };
229
230 void RunTest( Application& application )
231 {
232   gAtlasController = new AtlasController(application);
233   application.MainLoop(Configuration::APPLICATION_DOES_NOT_HANDLE_CONTEXT_LOSS);
234 }
235
236 // Entry point for Linux & Tizen applications
237 //
238 int DALI_EXPORT_API main( int argc, char **argv )
239 {
240   gApplication = Application::New( &argc, &argv, DEMO_THEME_PATH );
241
242   RunTest( gApplication );
243
244   return 0;
245 }