Render SVG with ImageView
[platform/core/uifw/dali-demo.git] / examples / image-view-svg / image-view-svg-example.cpp
1 /*
2  * Copyright (c) 2016 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/renderer-factory/renderer-factory.h>
20 #include <dali-toolkit/devel-api/controls/renderer-factory/control-renderer.h>
21 #include <string.h>
22
23 using namespace Dali;
24
25 namespace
26 {
27 const float MAX_SCALE = 6.f;
28
29 const char* SVG_IMAGES[] =
30 {
31     DEMO_IMAGE_DIR "Camera.svg",
32     DEMO_IMAGE_DIR "Contacts.svg",
33     DEMO_IMAGE_DIR "Mail.svg",
34     DEMO_IMAGE_DIR "Message.svg",
35     DEMO_IMAGE_DIR "Phone.svg",
36     DEMO_IMAGE_DIR "Settings.svg",
37     DEMO_IMAGE_DIR "World.svg",
38     DEMO_IMAGE_DIR "Kid1.svg"
39 };
40 const unsigned int NUM_SVG_IMAGES( sizeof( SVG_IMAGES ) / sizeof( SVG_IMAGES[0] ) );
41 }
42
43 // This example shows how to display svg images with ImageView
44 //
45 class ImageSvgController : public ConnectionTracker
46 {
47 public:
48
49   ImageSvgController( Application& application )
50   : mApplication( application ),
51     mScale( 1.f ),
52     mIndex( 0 )
53   {
54     // Connect to the Application's Init signal
55     mApplication.InitSignal().Connect( this, &ImageSvgController::Create );
56   }
57
58   ~ImageSvgController()
59   {
60   }
61
62   // The Init signal is received once (only) during the Application lifetime
63   void Create( Application& application )
64   {
65     // Get a handle to the stage
66     Stage stage = Stage::GetCurrent();
67     stage.SetBackgroundColor( Color::WHITE );
68     Vector2 stageSize = stage.GetSize();
69     mActorSize = stageSize/2.f;
70
71     stage.KeyEventSignal().Connect(this, &ImageSvgController::OnKeyEvent);
72
73     // Background, for receiving gestures
74     mStageBackground = Actor::New();
75     mStageBackground.SetAnchorPoint( AnchorPoint::TOP_CENTER );
76     mStageBackground.SetParentOrigin( ParentOrigin::TOP_CENTER );
77     mStageBackground.SetSize( stageSize.x, stageSize.y );
78     stage.Add(mStageBackground);
79
80     // Push button,  for changing the image set for displaying
81     Toolkit::PushButton changeButton = Toolkit::PushButton::New();
82     changeButton.SetLabelText( "Next" );
83     changeButton.SetAnchorPoint( AnchorPoint::TOP_RIGHT );
84     changeButton.SetParentOrigin( ParentOrigin::TOP_RIGHT );
85     stage.Add( changeButton );
86     changeButton.ClickedSignal().Connect( this, &ImageSvgController::OnChangeButtonClicked );
87
88     // Push button, for resetting the actor size and position
89     Toolkit::PushButton resetButton = Toolkit::PushButton::New();
90     resetButton.SetLabelText( "Reset" );
91     resetButton.SetAnchorPoint( AnchorPoint::TOP_LEFT );
92     resetButton.SetParentOrigin( ParentOrigin::TOP_LEFT );
93     stage.Add( resetButton );
94     resetButton.ClickedSignal().Connect( this, &ImageSvgController::OnResetButtonClicked );
95
96     // Create and put imageViews to stage
97     for( unsigned int i=0; i<4u; i++)
98     {
99       mSvgActor[i] = Toolkit::ImageView::New(SVG_IMAGES[mIndex+i]);
100       mSvgActor[i].SetSize( mActorSize );
101       stage.Add( mSvgActor[i] );
102     }
103     mSvgActor[0].SetParentOrigin( ParentOrigin::CENTER );
104     mSvgActor[0].SetAnchorPoint( AnchorPoint::BOTTOM_RIGHT );
105     mSvgActor[1].SetParentOrigin( ParentOrigin::CENTER );
106     mSvgActor[1].SetAnchorPoint( AnchorPoint::BOTTOM_LEFT );
107     mSvgActor[2].SetParentOrigin( ParentOrigin::CENTER );
108     mSvgActor[2].SetAnchorPoint( AnchorPoint::TOP_RIGHT );
109     mSvgActor[3].SetParentOrigin( ParentOrigin::CENTER );
110     mSvgActor[3].SetAnchorPoint( AnchorPoint::TOP_LEFT );
111
112     // Connect pan gesture for moving the actors
113     mPanGestureDetector = PanGestureDetector::New();
114     mPanGestureDetector.DetectedSignal().Connect( this, &ImageSvgController::OnPanGesture );
115     mPanGestureDetector.Attach( mStageBackground );
116
117     // Connect pinch gesture for resizing the actors
118     mPinchGestureDetector = PinchGestureDetector::New();
119     mPinchGestureDetector.Attach( mStageBackground);
120     mPinchGestureDetector.DetectedSignal().Connect(this, &ImageSvgController::OnPinch);
121   }
122
123   // Callback of push button, for changing image set
124   bool OnChangeButtonClicked( Toolkit::Button button )
125   {
126     mIndex = (mIndex+4) % NUM_SVG_IMAGES;
127     for( unsigned int i=0; i<4u; i++)
128     {
129       mSvgActor[i].SetImage(SVG_IMAGES[mIndex+i]);
130     }
131
132     return true;
133   }
134
135   // Callback of push button, for resetting image size and position
136   bool OnResetButtonClicked( Toolkit::Button button )
137   {
138     for( unsigned int i=0; i<4u; i++)
139     {
140       mSvgActor[i].SetSize(mActorSize);
141       mSvgActor[i].SetPosition( Vector3::ZERO );
142       mScale = 1.f;
143     }
144
145     return true;
146   }
147
148   // Callback of pan gesture, for moving the actors
149   void OnPanGesture( Actor actor, const PanGesture& gesture )
150   {
151     if( gesture.state == Gesture::Continuing )
152     {
153       for( unsigned int i=0; i<4u; i++)
154       {
155         mSvgActor[i].TranslateBy(Vector3(gesture.displacement));
156       }
157     }
158   }
159
160   // Callback of pinch gesture, for resizing the actors
161   void OnPinch(Actor actor, const PinchGesture& gesture)
162   {
163     if (gesture.state == Gesture::Started)
164     {
165       mScaleAtPinchStart = mScale;
166     }
167     if( gesture.state == Gesture::Finished )
168     {
169       mScale = mScaleAtPinchStart * gesture.scale;
170       mScale = mScale > MAX_SCALE ? MAX_SCALE : mScale;
171       for( unsigned int i=0; i<4u; i++)
172       {
173         mSvgActor[i].SetSize( mActorSize * mScale);
174       }
175     }
176   }
177
178   /**
179     * Main key event handler
180     */
181    void OnKeyEvent(const KeyEvent& event)
182    {
183      if(event.state == KeyEvent::Down)
184      {
185        if( IsKey( event, Dali::DALI_KEY_ESCAPE) || IsKey( event, Dali::DALI_KEY_BACK) )
186        {
187          mApplication.Quit();
188        }
189        else
190        {
191          const char* keyName = event.keyPressedName.c_str();
192          if( strcmp(keyName, "Left") == 0 )
193          {
194            mScale /= 1.1f;
195            for( unsigned int i=0; i<4u; i++)
196            {
197              mSvgActor[i].SetSize( mActorSize * mScale);
198            }
199          }
200          else if( strcmp(keyName, "Right") == 0 )
201          {
202            if( mScale < MAX_SCALE )
203            {
204              mScale *= 1.1f;
205            }
206            for( unsigned int i=0; i<4u; i++)
207            {
208              mSvgActor[i].SetSize( mActorSize * mScale);
209            }
210          }
211        }
212      }
213    }
214
215 private:
216   Application&         mApplication;
217   Actor                mStageBackground;
218   PanGestureDetector   mPanGestureDetector;
219   PinchGestureDetector mPinchGestureDetector;
220
221   Toolkit::ImageView  mSvgActor[4];
222   Vector2             mActorSize;
223   float               mScale;
224   float               mScaleAtPinchStart;
225   unsigned int        mIndex;
226 };
227
228 void RunTest( Application& application )
229 {
230   ImageSvgController test( application );
231
232   application.MainLoop();
233 }
234
235 // Entry point for Linux & Tizen applications
236 //
237 int main( int argc, char **argv )
238 {
239   Application application = Application::New( &argc, &argv );
240
241   RunTest( application );
242
243   return 0;
244 }