2 * Copyright (c) 2023 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.
19 #include <dali/internal/event/events/wheel-event-processor.h>
22 #include <dali/public-api/events/wheel-event.h>
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>
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");
44 Dali::Actor EmitInterceptWheelSignals(Dali::Actor actor, const Dali::WheelEvent& wheelEvent)
46 Dali::Actor interceptedActor;
50 Dali::Actor parent = actor.GetParent();
53 // Recursively deliver events to the actor and its parents for intercept wheel event.
54 interceptedActor = EmitInterceptWheelSignals(parent, wheelEvent);
59 bool intercepted = false;
60 Actor& actorImpl(GetImplementation(actor));
61 if(actorImpl.GetInterceptWheelRequired())
63 DALI_TRACE_SCOPE(gTraceFilter, "DALI_EMIT_INTERCEPT_WHEEL_EVENT_SIGNAL");
64 intercepted = actorImpl.EmitInterceptWheelEventSignal(wheelEvent);
67 interceptedActor = Dali::Actor(&actorImpl);
73 return interceptedActor;
77 * Recursively deliver events to the actor and its parents, until the event is consumed or the stage is reached.
79 Dali::Actor EmitWheelSignals(Dali::Actor actor, const Dali::WheelEvent& event)
81 Dali::Actor consumedActor;
85 Dali::Actor oldParent(actor.GetParent());
87 Actor& actorImpl(GetImplementation(actor));
91 // Only do the conversion and emit the signal if the actor's wheel signal has connections.
92 if(actorImpl.GetWheelEventRequired())
94 // Emit the signal to the parent
95 DALI_TRACE_SCOPE(gTraceFilter, "DALI_EMIT_WHEEL_EVENT_SIGNAL");
96 consumed = actorImpl.EmitWheelEventSignal(event);
101 // One of this actor's listeners has consumed the event so set this actor as the consumed actor.
102 consumedActor = Dali::Actor(&actorImpl);
106 // The actor may have been removed/reparented during the signal callbacks.
107 Dali::Actor parent = actor.GetParent();
110 (parent == oldParent))
112 // One of the actor's parents may consumed the event and they should be set as the consumed actor.
113 consumedActor = EmitWheelSignals(parent, event);
118 return consumedActor;
122 * The function to be used in the hit-test algorithm to check whether the actor is wheelable.
124 bool IsActorWheelableFunction(Dali::Actor actor, Dali::HitTestAlgorithm::TraverseType type)
126 bool hittable = false;
130 case Dali::HitTestAlgorithm::CHECK_ACTOR:
132 if((GetImplementation(actor).GetWheelEventRequired() || GetImplementation(actor).GetInterceptWheelRequired()) && // Does the Application or derived actor type require a wheel event?
133 GetImplementation(actor).IsHittable())
139 case Dali::HitTestAlgorithm::DESCEND_ACTOR_TREE:
141 if(actor.GetProperty<bool>(Dali::Actor::Property::VISIBLE)) // Actor is visible, if not visible then none of its children are visible.
156 } // unnamed namespace
158 WheelEventProcessor::WheelEventProcessor(Scene& scene)
163 WheelEventProcessor::~WheelEventProcessor() = default;
165 void WheelEventProcessor::ProcessWheelEvent(const Integration::WheelEvent& event)
167 WheelEventPtr wheelEvent = WheelEvent::New(static_cast<Dali::WheelEvent::Type>(event.type), event.direction, event.modifiers, event.point, event.delta, event.timeStamp);
168 Dali::WheelEvent wheelEventHandle(wheelEvent.Get());
170 DALI_TRACE_SCOPE(gTraceFilter, "DALI_PROCESS_WHEEL_EVENT");
172 if(wheelEvent->GetType() == Dali::WheelEvent::MOUSE_WHEEL)
174 Dali::HitTestAlgorithm::Results hitTestResults;
175 HitTestAlgorithm::HitTest(mScene.GetSize(), mScene.GetRenderTaskList(), mScene.GetLayerList(), event.point, hitTestResults, IsActorWheelableFunction);
177 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);
179 // Recursively deliver events to the actor and its parents, until the event is consumed or the stage is reached.
180 Dali::Actor consumedActor;
182 // Emit the intercept wheel event signal
183 Dali::Actor interceptedActor = EmitInterceptWheelSignals(hitTestResults.actor, wheelEventHandle);
186 consumedActor = EmitWheelSignals(interceptedActor, wheelEventHandle);
190 consumedActor = EmitWheelSignals(hitTestResults.actor, wheelEventHandle);
193 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() : "");
194 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() : "");
198 // if CUSTOM_WHEEL, emit the wheel event signal from the scene.
199 bool consumed = mScene.EmitWheelEventGeneratedSignal(wheelEventHandle);
202 mScene.EmitWheelEventSignal(wheelEventHandle);
207 } // namespace Internal