Updated demos to use DALi clang-format
[platform/core/uifw/dali-demo.git] / examples / visual-fitting-mode / visual-fitting-mode-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/visuals/visual-properties-devel.h>
20 #include <dali/devel-api/object/handle-devel.h>
21
22 using namespace Dali;
23 using namespace Dali::Toolkit;
24
25 namespace
26 {
27 const char* const IMAGE_NAME = DEMO_IMAGE_DIR "gallery-medium-1.jpg"; ///< The image to use.
28 const Vector3     IMAGE_SIZE = Vector3(300, 200, 0);                  ///< The size of the image-views.
29
30 const float           BORDER_SIZE = 2.0f; ///< The size of the border.
31 const Property::Value BORDER              ///< The border to use for each image-view.
32   {
33     {Visual::Property::TYPE, Visual::BORDER},
34     {BorderVisual::Property::COLOR, Color::RED},
35     {BorderVisual::Property::SIZE, BORDER_SIZE}};
36 const Extents LARGE_PADDING(100.0f, 100.0f, 2.0f, 2.0f);                               ///< The large padding extents.
37 const Extents BORDER_ONLY_PADDING(BORDER_SIZE, BORDER_SIZE, BORDER_SIZE, BORDER_SIZE); ///< The border only padding extents.
38
39 const std::string INSTRUCTIONS_TEXT = "\n(Tap or Key Press To Change)";                 ///< Instructions on how to change the padding mode.
40 const std::string LARGE_PADDING_TEXT("Padding: Left/Right Large" + INSTRUCTIONS_TEXT);  ///< Label to shown when large padding enabled.
41 const std::string BORDER_ONLY_PADDING_TEXT("Padding: Border Only" + INSTRUCTIONS_TEXT); ///< Label to shown when border-only padding enabled.
42 const std::string FILL_LABEL("FILL");
43 const std::string FIT_KEEP_ASPECT_LABEL("FIT\nKEEP ASPECT");
44
45 const Property::Map TEXT_LABEL_PROPERTIES ///< All the properties of the Large Text Label shown in the example.
46   {
47     {Actor::Property::ANCHOR_POINT, AnchorPoint::CENTER},
48     {Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER},
49     {Actor::Property::WIDTH_RESIZE_POLICY, ResizePolicy::FILL_TO_PARENT},
50     {Actor::Property::HEIGHT_RESIZE_POLICY, ResizePolicy::FILL_TO_PARENT},
51     {Control::Property::BACKGROUND,
52      {{Toolkit::Visual::Property::TYPE, Visual::GRADIENT},
53       {GradientVisual::Property::STOP_COLOR, Property::Array{Vector4(167.0f, 207.0f, 223.0f, 255.0f) / 255.0f, Vector4(0.0f, 64.0f, 137.0f, 255.0f) / 255.0f}},
54       {GradientVisual::Property::START_POSITION, Vector2(0.0f, -0.5f)},
55       {GradientVisual::Property::END_POSITION, Vector2(0.0f, 0.5f)}}},
56     {TextLabel::Property::HORIZONTAL_ALIGNMENT, HorizontalAlignment::CENTER},
57     {TextLabel::Property::VERTICAL_ALIGNMENT, VerticalAlignment::CENTER},
58     {TextLabel::Property::MULTI_LINE, true}};
59
60 const Property::Map FILL_IMAGE_PROPERTIES ///< The basic properties of the Fill image view.
61   {
62     {Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_CENTER},
63     {Actor::Property::PARENT_ORIGIN, ParentOrigin::TOP_CENTER},
64     {Actor::Property::SIZE, IMAGE_SIZE},
65     {Control::Property::BACKGROUND, BORDER}};
66
67 const Property::Map FIT_KEEP_ASPECT_RATIO_IMAGE_BASIC_PROPERTIES ///< The basic properties of the Fit Keep Aspect image view.
68   {
69     {Actor::Property::ANCHOR_POINT, AnchorPoint::BOTTOM_CENTER},
70     {Actor::Property::PARENT_ORIGIN, ParentOrigin::BOTTOM_CENTER},
71     {Actor::Property::SIZE, IMAGE_SIZE},
72     {Control::Property::BACKGROUND, BORDER}};
73
74 const Property::Map OVERLAY_LABEL_PROPERTIES ///< The image view overlay label properties
75   {
76     {TextLabel::Property::TEXT_COLOR, Color::WHITE},
77     {TextLabel::Property::OUTLINE, {{"color", Color::BLACK}, {"width", 1.0f}}},
78     {TextLabel::Property::HORIZONTAL_ALIGNMENT, HorizontalAlignment::CENTER},
79     {TextLabel::Property::VERTICAL_ALIGNMENT, VerticalAlignment::CENTER},
80     {TextLabel::Property::MULTI_LINE, true},
81   };
82 } // unnamed namespace
83
84 /**
85  * @brief This example shows how to use the Dali::Toolkit::DevelVisual::Property::VISUAL_FITTING_MODE property.
86  */
87 class VisualFittingModeController : public ConnectionTracker
88 {
89 public:
90   /**
91    * @brief Constructor.
92    * @param[in]  application A reference to the Application class.
93    */
94   VisualFittingModeController(Application& application)
95   : mApplication(application),
96     mLargePadding(true)
97   {
98     // Connect to the Application's Init signal
99     mApplication.InitSignal().Connect(this, &VisualFittingModeController::Create);
100   }
101
102 private:
103   /**
104    * @brief Called to initialise the application content
105    * @param[in] application A reference to the Application class.
106    */
107   void Create(Application& application)
108   {
109     // Get a handle to the window
110     Window window = application.GetWindow();
111     window.SetBackgroundColor(Color::WHITE);
112
113     // Text Label filling the entire screen, with a background
114     mTextLabel = Handle::New<TextLabel>(TEXT_LABEL_PROPERTIES);
115     window.Add(mTextLabel);
116
117     // We want to change the padding when tapping
118     mTapDetector = TapGestureDetector::New();
119     mTapDetector.Attach(mTextLabel);
120     mTapDetector.DetectedSignal().Connect(this, &VisualFittingModeController::OnTap);
121
122     // Create an ImageView with the default behaviour, i.e. image fills to control size
123     mFillImage = ImageView::New(IMAGE_NAME);
124     mFillImage.SetProperties(FILL_IMAGE_PROPERTIES);
125     window.Add(mFillImage);
126
127     // Create an ImageView that Keeps the aspect ratio while fitting within the given size
128     mFitKeepAspectRatioImage = Handle::New<ImageView>(FIT_KEEP_ASPECT_RATIO_IMAGE_BASIC_PROPERTIES);
129     mFitKeepAspectRatioImage.SetProperty(ImageView::Property::IMAGE,
130                                          Property::Map{
131                                            {Visual::Property::TYPE, Visual::IMAGE},
132                                            {ImageVisual::Property::URL, IMAGE_NAME},
133                                            {DevelVisual::Property::VISUAL_FITTING_MODE, DevelVisual::FIT_KEEP_ASPECT_RATIO}});
134     window.Add(mFitKeepAspectRatioImage);
135
136     // Create an overlay label for fill image
137     Actor fillLabel = TextLabel::New(FILL_LABEL);
138     fillLabel.SetProperties(FILL_IMAGE_PROPERTIES);
139     fillLabel.SetProperties(OVERLAY_LABEL_PROPERTIES);
140     window.Add(fillLabel);
141
142     // Create an overlay label for the Fit/Keep Aspect image
143     Actor fitLabel = TextLabel::New(FIT_KEEP_ASPECT_LABEL);
144     fitLabel.SetProperties(FIT_KEEP_ASPECT_RATIO_IMAGE_BASIC_PROPERTIES);
145     fitLabel.SetProperties(OVERLAY_LABEL_PROPERTIES);
146     window.Add(fitLabel);
147
148     // Respond to key events, exit if ESC/Back, change the padding if anything else
149     window.KeyEventSignal().Connect(this, &VisualFittingModeController::OnKeyEvent);
150
151     // Set the initial padding
152     ChangePadding();
153   }
154
155   /**
156    * @brief Changes the padding of both image-views to show how the VisualFittingMode is applied.
157    */
158   void ChangePadding()
159   {
160     mLargePadding = !mLargePadding;
161
162     const Extents padding(mLargePadding ? LARGE_PADDING : BORDER_ONLY_PADDING);
163     mFitKeepAspectRatioImage.SetProperty(Control::Property::PADDING, padding);
164     mFillImage.SetProperty(Control::Property::PADDING, padding);
165
166     mTextLabel.SetProperty(TextLabel::Property::TEXT, mLargePadding ? LARGE_PADDING_TEXT : BORDER_ONLY_PADDING_TEXT);
167   }
168
169   /**
170    * @brief Called when the main text-label is tapped.
171    *
172    * We just want to change the padding when this happens.
173    */
174   void OnTap(Actor /* actor */, const TapGesture& /* tap */)
175   {
176     ChangePadding();
177   }
178
179   /**
180    * @brief Called when any key event is received
181    *
182    * Will use this to quit the application if we receive the Back or the Escape key & change
183    * the padding if any other key.
184    * @param[in] event The key event information
185    */
186   void OnKeyEvent(const KeyEvent& event)
187   {
188     if(event.GetState() == KeyEvent::DOWN)
189     {
190       if(IsKey(event, Dali::DALI_KEY_ESCAPE) || IsKey(event, Dali::DALI_KEY_BACK))
191       {
192         mApplication.Quit();
193       }
194       else
195       {
196         ChangePadding();
197       }
198     }
199   }
200
201 private:
202   Application&       mApplication;             ///< Reference to the application class.
203   Actor              mFillImage;               ///< An image-view that fills to the control size.
204   Actor              mFitKeepAspectRatioImage; ///< An image-view that fits within the given size & keeps the aspect ratio.
205   Actor              mTextLabel;               ///< A text label to show the current padding mode.
206   TapGestureDetector mTapDetector;             ///< A tap detector to change the padding mode.
207   bool               mLargePadding;            ///< If true, the large padding values are used. When false, only the border padding is applied.
208 };
209
210 int DALI_EXPORT_API main(int argc, char** argv)
211 {
212   Application                 application = Application::New(&argc, &argv);
213   VisualFittingModeController visualFittingModeController(application);
214   application.MainLoop();
215   return 0;
216 }