2 * Copyright (c) 2022 Samsung Electronics Co., Ltd.
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
18 #include <dali-toolkit/dali-toolkit.h>
19 #include <dali-toolkit/devel-api/drag-drop-detector/drag-and-drop-detector.h>
20 #include <dali/devel-api/actors/actor-devel.h>
21 #include <dali/integration-api/debug.h>
24 using Dali::Toolkit::TextLabel;
25 using namespace Dali::Toolkit;
29 Vector4 TEXT_LABEL_COLOR[] =
40 const float TEXT_LABEL_POSITION_X = 100.0f;
41 const float TEXT_LABEL_POSITION_START_Y = 50.0f;
42 const float TEXT_LABEL_WIDTH = 250.0f;
43 const float TEXT_LABEL_HEIGHT = 70.0f;
44 const unsigned int TEXT_LABEL_NUM = sizeof(TEXT_LABEL_COLOR) / sizeof(TEXT_LABEL_COLOR[0]);
46 const float DROP_ANIMATION_DURATION_S = 0.5f;
48 #if defined(DEBUG_ENABLED)
49 Debug::Filter* gDragAndDropFilter = Debug::Filter::New(Debug::NoLogging, false, "LOG_DRAG_AND_DROP_EXAMPLE");
53 //This example shows how to use drag and drop function by several simple TextActors
54 class DragAndDropExample : public ConnectionTracker
57 DragAndDropExample(Application& application)
58 : mApplication(application),
62 // Connect to the Application's Init signal
63 mApplication.InitSignal().Connect(this, &DragAndDropExample::Create);
68 mDragAndDropDetector.DetachAll();
71 // The Init signal is received once (only) during the Application lifetime
72 void Create(Application& application)
74 auto window = application.GetWindow();
75 window.SetBackgroundColor(Color::WHITE);
76 const auto windowHeight = window.GetSize().GetHeight();
78 mDragAndDropDetector = Dali::Toolkit::DragAndDropDetector::New();
80 // Respond to key events
81 window.KeyEventSignal().Connect(this, &DragAndDropExample::OnKeyEvent);
83 TextLabel hintText = TextLabel::New("please drag one textlabel, move and drop on other textlabel");
84 hintText.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::BOTTOM_LEFT);
85 hintText.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::BOTTOM_LEFT);
86 hintText.SetProperty(TextLabel::Property::MULTI_LINE, true);
89 for(unsigned int i = 0; i < TEXT_LABEL_NUM; i++)
91 // Should be able to fit this and another more so if the height is less, then just stop adding new text labels
92 if((TEXT_LABEL_POSITION_START_Y + TEXT_LABEL_HEIGHT * (i + 2)) >= windowHeight)
97 std::string str = "textlabel ";
98 mTextLabel[i] = TextLabel::New(str + std::to_string(i));
99 mTextLabel[i].SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::TOP_LEFT);
100 mTextLabel[i].SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
101 mTextLabel[i].SetProperty(Dali::Actor::Property::NAME, "textlabel " + std::to_string(i));
102 mTextLabel[i].SetProperty(Actor::Property::LEAVE_REQUIRED, true);
103 mTextLabel[i].SetProperty(TextLabel::Property::HORIZONTAL_ALIGNMENT, "CENTER");
104 mTextLabel[i].SetProperty(TextLabel::Property::VERTICAL_ALIGNMENT, "CENTER");
105 mTextLabel[i].SetBackgroundColor(TEXT_LABEL_COLOR[i]);
107 mTextLabel[i].SetProperty(Actor::Property::SIZE, Vector2(TEXT_LABEL_WIDTH, TEXT_LABEL_HEIGHT));
108 mTextLabel[i].SetProperty(Actor::Property::POSITION, Vector2(TEXT_LABEL_POSITION_X, TEXT_LABEL_POSITION_START_Y + TEXT_LABEL_HEIGHT * i));
109 mDragAndDropDetector.Attach(mTextLabel[i]);
111 mRect[i] = Rect<float>(TEXT_LABEL_POSITION_X, TEXT_LABEL_POSITION_START_Y + TEXT_LABEL_HEIGHT * i, TEXT_LABEL_WIDTH, TEXT_LABEL_HEIGHT);
114 window.Add(mTextLabel[i]);
117 mDragAndDropDetector.StartedSignal().Connect(this, &DragAndDropExample::OnStart);
118 mDragAndDropDetector.EnteredSignal().Connect(this, &DragAndDropExample::OnEnter);
119 mDragAndDropDetector.ExitedSignal().Connect(this, &DragAndDropExample::OnExit);
120 mDragAndDropDetector.MovedSignal().Connect(this, &DragAndDropExample::OnMoved);
121 mDragAndDropDetector.DroppedSignal().Connect(this, &DragAndDropExample::OnDropped);
122 mDragAndDropDetector.EndedSignal().Connect(this, &DragAndDropExample::OnEnd);
125 void OnKeyEvent(const KeyEvent& event)
127 if(event.GetState() == KeyEvent::DOWN)
129 if(IsKey(event, Dali::DALI_KEY_ESCAPE) || IsKey(event, Dali::DALI_KEY_BACK))
136 void OnStart(Control control, Dali::Toolkit::DragAndDropDetector detector)
138 DALI_LOG_INFO(gDragAndDropFilter, Debug::General, "---OnStart---\n");
139 DALI_LOG_INFO(gDragAndDropFilter, Debug::General, "---control name is %s---\n", control.GetProperty<std::string>(Dali::Actor::Property::NAME).c_str());
141 control.SetProperty(Actor::Property::OPACITY, 0.1f);
142 Vector2 screenPos = detector.GetCurrentScreenPosition();
143 control.ScreenToLocal(mDragLocalPos.x, mDragLocalPos.y, screenPos.x, screenPos.y);
144 Rect<float> targetRect(screenPos.x, screenPos.y, 0.0f, 0.0f);
146 for(unsigned int i = 0; i < TEXT_LABEL_NUM; i++)
148 if(mRect[i].Contains(targetRect))
154 mDragRealIndex = mOrder[mDragIndex];
157 void OnEnter(Control control, Dali::Toolkit::DragAndDropDetector detector)
159 DALI_LOG_INFO(gDragAndDropFilter, Debug::General, "---OnEnter---\n");
160 DALI_LOG_INFO(gDragAndDropFilter, Debug::General, "---control name is %s---\n", control.GetProperty<std::string>(Dali::Actor::Property::NAME).c_str());
163 void OnExit(Control control, Dali::Toolkit::DragAndDropDetector detector)
165 DALI_LOG_INFO(gDragAndDropFilter, Debug::General, "---OnExit---\n");
166 DALI_LOG_INFO(gDragAndDropFilter, Debug::General, "---control name is %s---\n", control.GetProperty<std::string>(Dali::Actor::Property::NAME).c_str());
169 void OnMoved(Control control, Dali::Toolkit::DragAndDropDetector detector)
171 DALI_LOG_INFO(gDragAndDropFilter, Debug::Verbose, "---OnMoved---\n");
172 DALI_LOG_INFO(gDragAndDropFilter, Debug::Verbose, "---control name is %s---\n", control.GetProperty<std::string>(Dali::Actor::Property::NAME).c_str());
173 DALI_LOG_INFO(gDragAndDropFilter, Debug::Verbose, "---coordinate is (%f, %f)---\n", detector.GetCurrentScreenPosition().x, detector.GetCurrentScreenPosition().y);
176 void OnDropped(Control control, Dali::Toolkit::DragAndDropDetector detector)
178 DALI_LOG_INFO(gDragAndDropFilter, Debug::General, "---OnDropped---\n");
179 DALI_LOG_INFO(gDragAndDropFilter, Debug::General, "---control name is %s---\n", control.GetProperty<std::string>(Dali::Actor::Property::NAME).c_str());
181 Vector2 screenPos = detector.GetCurrentScreenPosition();
182 Rect<float> targetRect(screenPos.x, screenPos.y, 0.0f, 0.0f);
183 int droppedIndex = -1;
184 for(unsigned int i = 0; i < TEXT_LABEL_NUM; i++)
186 if(mRect[i].Contains(targetRect))
192 Animation mAnimation = Animation::New(DROP_ANIMATION_DURATION_S);
194 if(droppedIndex > mDragIndex)
196 for(int i = mDragIndex + 1; i <= droppedIndex; i++)
198 mAnimation.AnimateTo(Property(mTextLabel[mOrder[i]], Actor::Property::POSITION),
199 Vector3(TEXT_LABEL_POSITION_X, TEXT_LABEL_POSITION_START_Y + TEXT_LABEL_HEIGHT * (i - 1), 0.0f),
200 AlphaFunction::EASE_OUT);
204 int tmpId = mOrder[mDragIndex];
205 for(int i = mDragIndex; i < droppedIndex; i++)
207 mOrder[i] = mOrder[i + 1];
210 mOrder[droppedIndex] = tmpId;
212 else if(droppedIndex < mDragIndex)
214 for(int i = mDragIndex - 1; i >= droppedIndex; i--)
216 mAnimation.AnimateTo(Property(mTextLabel[mOrder[i]], Actor::Property::POSITION),
217 Vector3(TEXT_LABEL_POSITION_X, TEXT_LABEL_POSITION_START_Y + TEXT_LABEL_HEIGHT * (i + 1), 0.0f),
218 AlphaFunction::EASE_OUT);
222 int tmpId = mOrder[mDragIndex];
223 for(int i = mDragIndex; i > droppedIndex; i--)
225 mOrder[i] = mOrder[i - 1];
228 mOrder[droppedIndex] = tmpId;
231 Vector2 pos = detector.GetCurrentScreenPosition();
233 control.GetParent().ScreenToLocal(localPos.x, localPos.y, pos.x, pos.y);
235 KeyFrames k0 = KeyFrames::New();
236 k0.Add(0.0f, Vector3(localPos.x - mDragLocalPos.x, localPos.y - mDragLocalPos.y, 0.0f));
237 k0.Add(1.0f, Vector3(TEXT_LABEL_POSITION_X, TEXT_LABEL_POSITION_START_Y + TEXT_LABEL_HEIGHT * droppedIndex, 0.0f));
239 KeyFrames k1 = KeyFrames::New();
243 Animation dropAnimation = Animation::New(DROP_ANIMATION_DURATION_S);
244 dropAnimation.AnimateBetween(Property(mTextLabel[mDragRealIndex], Actor::Property::POSITION), k0, AlphaFunction::EASE_OUT);
245 dropAnimation.AnimateBetween(Property(mTextLabel[mDragRealIndex], Actor::Property::OPACITY), k1, AlphaFunction::EASE_OUT);
246 dropAnimation.Play();
249 void DropAnimationFinished(Animation& animation)
251 for(unsigned int i = 0; i < TEXT_LABEL_NUM; i++)
253 mDragAndDropDetector.Attach(mTextLabel[i]);
257 void OnEnd(Control control, Dali::Toolkit::DragAndDropDetector detector)
259 DALI_LOG_INFO(gDragAndDropFilter, Debug::General, "---OnEnd---\n");
260 DALI_LOG_INFO(gDragAndDropFilter, Debug::General, "---control name is %s---\n", control.GetProperty<std::string>(Dali::Actor::Property::NAME).c_str());
262 control.SetProperty(Actor::Property::OPACITY, 1.0f);
266 Application& mApplication;
267 Dali::Toolkit::DragAndDropDetector mDragAndDropDetector;
269 TextLabel mTextLabel[TEXT_LABEL_NUM];
270 Rect<float> mRect[TEXT_LABEL_NUM];
272 int mOrder[TEXT_LABEL_NUM];
276 Vector2 mDragLocalPos;
279 int DALI_EXPORT_API main(int argc, char** argv)
281 Application application = Application::New(&argc, &argv);
282 DragAndDropExample test(application);
283 application.MainLoop();