Updated demos to use DALi clang-format
[platform/core/uifw/dali-demo.git] / examples / image-view-svg / image-view-svg-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/devel-api/actors/actor-devel.h>
20 #include <string.h>
21
22 using namespace Dali;
23
24 namespace
25 {
26 const float MIN_SCALE = 0.6f;
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 const unsigned int NUM_SVG_IMAGES(sizeof(SVG_IMAGES) / sizeof(SVG_IMAGES[0]));
40 const unsigned int NUM_IMAGES_DISPLAYED = 4u;
41 } // unnamed namespace
42
43 // This example shows how to display svg images with ImageView.
44 //
45 class ImageSvgController : public ConnectionTracker
46 {
47 public:
48   ImageSvgController(Application& application)
49   : mApplication(application),
50     mScale(1.f),
51     mIndex(0)
52   {
53     // Connect to the Application's Init signal
54     mApplication.InitSignal().Connect(this, &ImageSvgController::Create);
55   }
56
57   ~ImageSvgController()
58   {
59   }
60
61   // The Init signal is received once (only) during the Application lifetime
62   void Create(Application& application)
63   {
64     // Get a handle to the window
65     Window window = application.GetWindow();
66     window.SetBackgroundColor(Color::WHITE);
67     Vector2 windowSize = window.GetSize();
68     mActorSize         = windowSize / 2.f;
69
70     window.KeyEventSignal().Connect(this, &ImageSvgController::OnKeyEvent);
71
72     // Background, for receiving gestures
73     mWindowBackground = Actor::New();
74     mWindowBackground.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_CENTER);
75     mWindowBackground.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::TOP_CENTER);
76     mWindowBackground.SetProperty(Actor::Property::SIZE, Vector2(windowSize.x, windowSize.y));
77     window.Add(mWindowBackground);
78
79     // Push button,  for changing the image set for displaying
80     Toolkit::PushButton changeButton = Toolkit::PushButton::New();
81     changeButton.SetProperty(Toolkit::Button::Property::LABEL, "Next");
82     changeButton.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_RIGHT);
83     changeButton.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::TOP_RIGHT);
84     window.Add(changeButton);
85     changeButton.ClickedSignal().Connect(this, &ImageSvgController::OnChangeButtonClicked);
86
87     // Push button, for resetting the actor size and position
88     Toolkit::PushButton resetButton = Toolkit::PushButton::New();
89     resetButton.SetProperty(Toolkit::Button::Property::LABEL, "Reset");
90     resetButton.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
91     resetButton.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::TOP_LEFT);
92     window.Add(resetButton);
93     resetButton.ClickedSignal().Connect(this, &ImageSvgController::OnResetButtonClicked);
94
95     // Create and put imageViews to window
96     for(unsigned int i = 0; i < NUM_IMAGES_DISPLAYED; i++)
97     {
98       mSvgActor[i] = Toolkit::ImageView::New(SVG_IMAGES[mIndex + i]);
99       mSvgActor[i].SetProperty(Actor::Property::SIZE, mActorSize);
100       mSvgActor[i].TranslateBy(Vector3(0.0, windowSize.height * 0.05, 0.0f));
101       window.Add(mSvgActor[i]);
102     }
103     mSvgActor[0].SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER);
104     mSvgActor[0].SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::BOTTOM_RIGHT);
105     mSvgActor[1].SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER);
106     mSvgActor[1].SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::BOTTOM_LEFT);
107     mSvgActor[2].SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER);
108     mSvgActor[2].SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_RIGHT);
109     mSvgActor[3].SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER);
110     mSvgActor[3].SetProperty(Actor::Property::ANCHOR_POINT, 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(mWindowBackground);
116
117     // Connect pinch gesture for resizing the actors
118     mPinchGestureDetector = PinchGestureDetector::New();
119     mPinchGestureDetector.Attach(mWindowBackground);
120     mPinchGestureDetector.DetectedSignal().Connect(this, &ImageSvgController::OnPinch);
121
122     changeButton.RaiseToTop();
123     resetButton.RaiseToTop();
124   }
125
126   // Callback of push button, for changing image set
127   bool OnChangeButtonClicked(Toolkit::Button button)
128   {
129     mIndex = (mIndex + NUM_IMAGES_DISPLAYED) % NUM_SVG_IMAGES;
130     for(unsigned int i = 0; i < NUM_IMAGES_DISPLAYED; i++)
131     {
132       mSvgActor[i].SetImage(SVG_IMAGES[mIndex + i]);
133     }
134
135     return true;
136   }
137
138   // Callback of push button, for resetting image size and position
139   bool OnResetButtonClicked(Toolkit::Button button)
140   {
141     for(unsigned int i = 0; i < NUM_IMAGES_DISPLAYED; i++)
142     {
143       mSvgActor[i].SetProperty(Actor::Property::SIZE, mActorSize);
144       mSvgActor[i].SetProperty(Actor::Property::POSITION, Vector3::ZERO);
145       mScale = 1.f;
146     }
147
148     return true;
149   }
150
151   // Callback of pan gesture, for moving the actors
152   void OnPanGesture(Actor actor, const PanGesture& gesture)
153   {
154     if(gesture.GetState() == GestureState::CONTINUING)
155     {
156       for(unsigned int i = 0; i < NUM_IMAGES_DISPLAYED; i++)
157       {
158         mSvgActor[i].TranslateBy(Vector3(gesture.GetDisplacement()));
159       }
160     }
161   }
162
163   // Callback of pinch gesture, for resizing the actors
164   void OnPinch(Actor actor, const PinchGesture& gesture)
165   {
166     switch(gesture.GetState())
167     {
168         // Only scale the image when we start or continue pinching
169
170       case GestureState::STARTED:
171       case GestureState::CONTINUING:
172       {
173         float scale = std::max(gesture.GetScale(), MIN_SCALE / mScale);
174         scale       = std::min(MAX_SCALE / mScale, scale);
175
176         for(unsigned int i = 0; i < NUM_IMAGES_DISPLAYED; i++)
177         {
178           mSvgActor[i].SetProperty(Actor::Property::SCALE, scale);
179         }
180         break;
181       }
182
183       case GestureState::FINISHED:
184       {
185         // Resize the image when pinching is complete, this will rasterize the SVG to the new size
186
187         mScale = mScale * gesture.GetScale();
188         mScale = mScale > MAX_SCALE ? MAX_SCALE : mScale;
189         mScale = mScale < MIN_SCALE ? MIN_SCALE : mScale;
190         for(unsigned int i = 0; i < NUM_IMAGES_DISPLAYED; i++)
191         {
192           mSvgActor[i].SetProperty(Actor::Property::SIZE, mActorSize * mScale);
193           mSvgActor[i].SetProperty(Actor::Property::SCALE, 1.0f);
194         }
195         break;
196       }
197
198       case GestureState::CANCELLED:
199       case GestureState::CLEAR:
200       case GestureState::POSSIBLE:
201         break;
202     }
203   }
204
205   /**
206     * Main key event handler
207     */
208   void OnKeyEvent(const KeyEvent& event)
209   {
210     if(event.GetState() == KeyEvent::DOWN)
211     {
212       if(IsKey(event, Dali::DALI_KEY_ESCAPE) || IsKey(event, Dali::DALI_KEY_BACK))
213       {
214         mApplication.Quit();
215       }
216       else
217       {
218         const char* keyName = event.GetKeyName().c_str();
219         if(strcmp(keyName, "Left") == 0)
220         {
221           if(mScale > MIN_SCALE)
222           {
223             mScale /= 1.1f;
224           }
225           for(unsigned int i = 0; i < NUM_IMAGES_DISPLAYED; i++)
226           {
227             mSvgActor[i].SetProperty(Actor::Property::SIZE, mActorSize * mScale);
228           }
229         }
230         else if(strcmp(keyName, "Right") == 0)
231         {
232           if(mScale < MAX_SCALE)
233           {
234             mScale *= 1.1f;
235           }
236           for(unsigned int i = 0; i < NUM_IMAGES_DISPLAYED; i++)
237           {
238             mSvgActor[i].SetProperty(Actor::Property::SIZE, mActorSize * mScale);
239           }
240         }
241       }
242     }
243   }
244
245 private:
246   Application&         mApplication;
247   Actor                mWindowBackground;
248   PanGestureDetector   mPanGestureDetector;
249   PinchGestureDetector mPinchGestureDetector;
250
251   Toolkit::ImageView mSvgActor[4];
252   Vector2            mActorSize;
253   float              mScale;
254   unsigned int       mIndex;
255 };
256
257 int DALI_EXPORT_API main(int argc, char** argv)
258 {
259   Application        application = Application::New(&argc, &argv);
260   ImageSvgController test(application);
261   application.MainLoop();
262   return 0;
263 }