Revert "[Tizen] Not execute the remove callback"
[platform/core/uifw/dali-core.git] / dali / internal / event / events / wheel-event-processor.cpp
1 /*
2  * Copyright (c) 2023 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 // CLASS HEADER
19 #include <dali/internal/event/events/wheel-event-processor.h>
20
21 // INTERNAL INCLUDES
22 #include <dali/public-api/events/wheel-event.h>
23
24 #include <dali/integration-api/debug.h>
25 #include <dali/integration-api/events/wheel-event-integ.h>
26 #include <dali/integration-api/trace.h>
27 #include <dali/internal/event/actors/actor-impl.h>
28 #include <dali/internal/event/common/scene-impl.h>
29 #include <dali/internal/event/events/hit-test-algorithm-impl.h>
30 #include <dali/internal/event/events/wheel-event-impl.h>
31 #include <dali/public-api/math/vector2.h>
32
33 namespace Dali
34 {
35 namespace Internal
36 {
37 namespace
38 {
39 DALI_INIT_TRACE_FILTER(gTraceFilter, DALI_TRACE_PERFORMANCE_MARKER, false);
40 #if defined(DEBUG_ENABLED)
41 Debug::Filter* gLogFilter = Debug::Filter::New(Debug::NoLogging, false, "LOG_WHEEL_PROCESSOR");
42 #endif
43
44 /**
45  *  Recursively deliver events to the actor and its parents, until the event is consumed or the stage is reached.
46  */
47 Dali::Actor EmitWheelSignals(Dali::Actor actor, const Dali::WheelEvent& event)
48 {
49   Dali::Actor consumedActor;
50
51   if(actor)
52   {
53     Dali::Actor oldParent(actor.GetParent());
54
55     Actor& actorImpl(GetImplementation(actor));
56
57     bool consumed(false);
58
59     // Only do the conversion and emit the signal if the actor's wheel signal has connections.
60     if(actorImpl.GetWheelEventRequired())
61     {
62       // Emit the signal to the parent
63       consumed = actorImpl.EmitWheelEventSignal(event);
64     }
65
66     if(consumed)
67     {
68       // One of this actor's listeners has consumed the event so set this actor as the consumed actor.
69       consumedActor = Dali::Actor(&actorImpl);
70     }
71     else
72     {
73       // The actor may have been removed/reparented during the signal callbacks.
74       Dali::Actor parent = actor.GetParent();
75
76       if(parent &&
77          (parent == oldParent))
78       {
79         // One of the actor's parents may consumed the event and they should be set as the consumed actor.
80         consumedActor = EmitWheelSignals(parent, event);
81       }
82     }
83   }
84
85   return consumedActor;
86 }
87
88 /**
89  * The function to be used in the hit-test algorithm to check whether the actor is wheelable.
90  */
91 bool IsActorWheelableFunction(Dali::Actor actor, Dali::HitTestAlgorithm::TraverseType type)
92 {
93   bool hittable = false;
94
95   switch(type)
96   {
97     case Dali::HitTestAlgorithm::CHECK_ACTOR:
98     {
99       if(GetImplementation(actor).GetWheelEventRequired() && // Does the Application or derived actor type require a wheel event?
100          GetImplementation(actor).IsHittable())
101       {
102         hittable = true;
103       }
104       break;
105     }
106     case Dali::HitTestAlgorithm::DESCEND_ACTOR_TREE:
107     {
108       if(actor.GetProperty<bool>(Dali::Actor::Property::VISIBLE)) // Actor is visible, if not visible then none of its children are visible.
109       {
110         hittable = true;
111       }
112       break;
113     }
114     default:
115     {
116       break;
117     }
118   }
119
120   return hittable;
121 };
122
123 } // unnamed namespace
124
125 WheelEventProcessor::WheelEventProcessor(Scene& scene)
126 : mScene(scene)
127 {
128 }
129
130 WheelEventProcessor::~WheelEventProcessor() = default;
131
132 void WheelEventProcessor::ProcessWheelEvent(const Integration::WheelEvent& event)
133 {
134   WheelEventPtr    wheelEvent = WheelEvent::New(static_cast<Dali::WheelEvent::Type>(event.type), event.direction, event.modifiers, event.point, event.delta, event.timeStamp);
135   Dali::WheelEvent wheelEventHandle(wheelEvent.Get());
136
137   DALI_TRACE_SCOPE(gTraceFilter, "DALI_PROCESS_WHEEL_EVENT");
138
139   if(wheelEvent->GetType() == Dali::WheelEvent::MOUSE_WHEEL)
140   {
141     Dali::HitTestAlgorithm::Results hitTestResults;
142     HitTestAlgorithm::HitTest(mScene.GetSize(), mScene.GetRenderTaskList(), mScene.GetLayerList(), event.point, hitTestResults, IsActorWheelableFunction);
143
144     DALI_LOG_INFO(gLogFilter, Debug::General, "  Screen(%.0f, %.0f), HitActor(%p, %s), Local(%.2f, %.2f)\n", event.point.x, event.point.y, (hitTestResults.actor ? reinterpret_cast<void*>(&hitTestResults.actor.GetBaseObject()) : NULL), (hitTestResults.actor ? hitTestResults.actor.GetProperty<std::string>(Dali::Actor::Property::NAME).c_str() : ""), hitTestResults.actorCoordinates.x, hitTestResults.actorCoordinates.y);
145
146     // Recursively deliver events to the actor and its parents, until the event is consumed or the stage is reached.
147     Dali::Actor consumedActor = EmitWheelSignals(hitTestResults.actor, wheelEventHandle);
148
149     DALI_LOG_INFO(gLogFilter, Debug::Concise, "HitActor:      (%p) %s\n", hitTestResults.actor ? reinterpret_cast<void*>(&hitTestResults.actor.GetBaseObject()) : NULL, hitTestResults.actor ? hitTestResults.actor.GetProperty<std::string>(Dali::Actor::Property::NAME).c_str() : "");
150     DALI_LOG_INFO(gLogFilter, Debug::Concise, "ConsumedActor: (%p) %s\n", consumedActor ? reinterpret_cast<void*>(&consumedActor.GetBaseObject()) : NULL, consumedActor ? consumedActor.GetProperty<std::string>(Dali::Actor::Property::NAME).c_str() : "");
151   }
152   else
153   {
154     // if CUSTOM_WHEEL, emit the wheel event signal from the scene.
155     bool consumed = mScene.EmitWheelEventGeneratedSignal(wheelEventHandle);
156     if(!consumed)
157     {
158       mScene.EmitWheelEventSignal(wheelEventHandle);
159     }
160   }
161 }
162
163 } // namespace Internal
164
165 } // namespace Dali