Added stage-devel to support KeyEvent propagation 82/122982/8
authorminho.sun <minho.sun@samsung.com>
Tue, 4 Apr 2017 06:25:59 +0000 (15:25 +0900)
committerminho.sun <minho.sun@samsung.com>
Thu, 6 Apr 2017 16:03:43 +0000 (01:03 +0900)
To support KeyEvent propagation, made stage-devel.

In stage-devel, there is one new signal.

 Signal< bool( const Dali::KeyEvent& ) > KeyEventGeneratedSignal
 : Emitted when KeyEvent is generated

And also, now when Propagation result is false, then emit
Stage::KeyEventSignal for app & KeyboardFocus.

Change-Id: Ibd95ba2e082f4d3ee43ddf51b5ec6c09010164fb
Signed-off-by: minho.sun <minho.sun@samsung.com>
automated-tests/src/dali/utc-Dali-Stage.cpp
dali/devel-api/common/stage-devel.cpp [new file with mode: 0644]
dali/devel-api/common/stage-devel.h [new file with mode: 0644]
dali/devel-api/file.list
dali/internal/event/common/stage-impl.cpp
dali/internal/event/common/stage-impl.h
dali/internal/event/events/key-event-processor.cpp

index 10496fd..459061f 100644 (file)
 #include <stdlib.h>
 
 #include <dali/public-api/dali-core.h>
+#include <dali/devel-api/common/stage-devel.h>
 #include <dali/integration-api/context-notifier.h>
 #include <dali/integration-api/events/key-event-integ.h>
+#include <dali/public-api/events/key-event.h>
 #include <dali/integration-api/events/touch-event-integ.h>
 #include <dali/integration-api/events/wheel-event-integ.h>
 
@@ -60,6 +62,50 @@ struct EventProcessingFinishedFunctor
   bool& mEventProcessingFinished;
 };
 
+// Stores data that is populated in the KeyEventGeneratedSignal callback and will be read by the TET cases
+struct KeyEventGeneratedSignalData
+{
+  KeyEventGeneratedSignalData()
+  : functorCalled(false)
+  {}
+
+  void Reset()
+  {
+    functorCalled = false;
+
+    receivedKeyEvent.keyModifier = 0;
+    receivedKeyEvent.keyPressedName.clear();
+    receivedKeyEvent.keyPressed.clear();
+  }
+
+  bool functorCalled;
+  KeyEvent receivedKeyEvent;
+};
+
+// Functor that sets the data when called
+struct KeyEventGeneratedReceivedFunctor
+{
+  KeyEventGeneratedReceivedFunctor( KeyEventGeneratedSignalData& data )
+  : signalData( data )
+  {}
+
+  bool operator()( const KeyEvent& keyEvent )
+  {
+    signalData.functorCalled = true;
+    signalData.receivedKeyEvent = keyEvent;
+
+    return true;
+  }
+
+  bool operator()()
+  {
+    signalData.functorCalled = true;
+    return true;
+  }
+
+  KeyEventGeneratedSignalData& signalData;
+};
+
 // Stores data that is populated in the key-event callback and will be read by the TET cases
 struct KeyEventSignalData
 {
@@ -144,6 +190,11 @@ struct TouchFunctor
     signalData.receivedTouchData = touch;
   }
 
+  void operator()()
+  {
+    signalData.functorCalled = true;
+  }
+
   TouchedSignalData& signalData;
 };
 
@@ -817,6 +868,63 @@ int UtcDaliStageEventProcessingFinishedN(void)
   END_TEST;
 }
 
+int UtcDaliStageKeyEventGeneratedSignalP(void)
+{
+  TestApplication application;
+  Stage stage = Stage::GetCurrent();
+
+  KeyEventGeneratedSignalData data;
+  KeyEventGeneratedReceivedFunctor functor( data );
+  DevelStage::KeyEventGeneratedSignal( stage ).Connect( &application, functor );
+
+  KeyEventGeneratedSignalData data2;
+  KeyEventGeneratedReceivedFunctor functor2( data2 );
+  GetImplementation( stage ).ConnectSignal( &application, "keyEventGenerated", functor2 );
+
+  Integration::KeyEvent event( "a", "a", 0, 0, 0, Integration::KeyEvent::Up );
+  application.ProcessEvent( event );
+
+  DALI_TEST_EQUALS( true, data.functorCalled, TEST_LOCATION );
+  DALI_TEST_CHECK( event.keyModifier == data.receivedKeyEvent.keyModifier );
+  DALI_TEST_CHECK( event.keyName == data.receivedKeyEvent.keyPressedName );
+  DALI_TEST_CHECK( event.keyString == data.receivedKeyEvent.keyPressed );
+  DALI_TEST_CHECK( event.state == static_cast<Integration::KeyEvent::State>( data.receivedKeyEvent.state ) );
+
+  data.Reset();
+
+  Integration::KeyEvent event2( "i", "i", 0, 0, 0, Integration::KeyEvent::Up );
+  application.ProcessEvent( event2 );
+
+  DALI_TEST_EQUALS( true, data.functorCalled, TEST_LOCATION );
+  DALI_TEST_CHECK( event2.keyModifier == data.receivedKeyEvent.keyModifier );
+  DALI_TEST_CHECK( event2.keyName == data.receivedKeyEvent.keyPressedName );
+  DALI_TEST_CHECK( event2.keyString == data.receivedKeyEvent.keyPressed );
+  DALI_TEST_CHECK( event2.state == static_cast<Integration::KeyEvent::State>( data.receivedKeyEvent.state ) );
+
+  data.Reset();
+
+  Integration::KeyEvent event3( "a", "a", 0, 0, 0, Integration::KeyEvent::Down );
+  application.ProcessEvent( event3 );
+
+  DALI_TEST_EQUALS( true, data.functorCalled, TEST_LOCATION );
+  DALI_TEST_CHECK( event3.keyModifier == data.receivedKeyEvent.keyModifier );
+  DALI_TEST_CHECK( event3.keyName == data.receivedKeyEvent.keyPressedName );
+  DALI_TEST_CHECK( event3.keyString == data.receivedKeyEvent.keyPressed );
+  DALI_TEST_CHECK( event3.state == static_cast<Integration::KeyEvent::State>( data.receivedKeyEvent.state ) );
+
+  data.Reset();
+
+  Integration::KeyEvent event4( "a", "a", 0, 0, 0, Integration::KeyEvent::Up );
+  application.ProcessEvent( event4 );
+
+  DALI_TEST_EQUALS( true, data.functorCalled, TEST_LOCATION );
+  DALI_TEST_CHECK( event4.keyModifier == data.receivedKeyEvent.keyModifier );
+  DALI_TEST_CHECK( event4.keyName == data.receivedKeyEvent.keyPressedName );
+  DALI_TEST_CHECK( event4.keyString == data.receivedKeyEvent.keyPressed );
+  DALI_TEST_CHECK( event4.state == static_cast<Integration::KeyEvent::State>( data.receivedKeyEvent.state ) );
+  END_TEST;
+}
+
 int UtcDaliStageSignalKeyEventP(void)
 {
   TestApplication application;
@@ -1221,12 +1329,17 @@ int UtcDaliStageTouchSignalN(void)
   TouchFunctor functor( data );
   stage.TouchSignal().Connect( &application, functor );
 
+  TouchedSignalData data2;
+  TouchFunctor functor2( data2 );
+  GetImplementation( stage ).ConnectSignal( &application, "touch", functor2 );
+
   // Render and notify.
   application.SendNotification();
   application.Render();
 
   // Confirm functor not called before there has been any touch event.
   DALI_TEST_EQUALS( false, data.functorCalled, TEST_LOCATION );
+  DALI_TEST_EQUALS( false, data2.functorCalled, TEST_LOCATION );
 
   // No actors, single touch, down, motion then up.
   {
@@ -1235,7 +1348,11 @@ int UtcDaliStageTouchSignalN(void)
     DALI_TEST_EQUALS( true, data.functorCalled, TEST_LOCATION );
     DALI_TEST_CHECK( data.receivedTouchData.GetPointCount() != 0u );
     DALI_TEST_CHECK( !data.receivedTouchData.GetHitActor(0));
+
+    DALI_TEST_EQUALS( true, data2.functorCalled, TEST_LOCATION );
+
     data.Reset();
+    data2.Reset();
 
     // Confirm there is no signal when the touchpoint is only moved.
     GenerateTouch( application, PointState::MOTION, Vector2( 1200.0f, 10.0f ) ); // Some motion
diff --git a/dali/devel-api/common/stage-devel.cpp b/dali/devel-api/common/stage-devel.cpp
new file mode 100644 (file)
index 0000000..d68a5a0
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// INTERNAL INCLUDES
+#include <dali/devel-api/common/stage-devel.h>
+#include <dali/internal/event/common/stage-impl.h>
+
+namespace Dali
+{
+
+namespace DevelStage
+{
+
+KeyEventGeneratedSignalType& KeyEventGeneratedSignal( Dali::Stage stage )
+{
+  return GetImplementation( stage ).KeyEventGeneratedSignal();
+}
+
+} // namespace DevelStage
+
+} // namespace Dali
diff --git a/dali/devel-api/common/stage-devel.h b/dali/devel-api/common/stage-devel.h
new file mode 100644 (file)
index 0000000..f54e411
--- /dev/null
@@ -0,0 +1,44 @@
+#ifndef DALI_STAGE_DEVEL_H
+#define DALI_STAGE_DEVEL_H
+
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// INTERNAL INCLUDES
+#include <dali/public-api/common/stage.h>
+
+namespace Dali
+{
+
+namespace DevelStage
+{
+
+typedef Signal< bool (const KeyEvent&) > KeyEventGeneratedSignalType;      ///< Stage key event generated signal type
+
+/**
+ * @brief The user would connect to this signal to get a KeyEvent when KeyEvent is generated.
+ *
+ * @param[in] stage The stage to emit a signal
+ * @return The return is true if KeyEvent is consumed, otherwise false.
+ */
+DALI_IMPORT_API KeyEventGeneratedSignalType& KeyEventGeneratedSignal( Dali::Stage stage );
+
+} // namespace DevelStage
+
+} // namespace Dali
+
+#endif // DALI_STAGE_DEVEL_H
index 7d2eb05..84f9117 100644 (file)
@@ -4,6 +4,7 @@ devel_api_src_files = \
   $(devel_api_src_dir)/animation/animation-data.cpp \
   $(devel_api_src_dir)/animation/path-constrainer.cpp \
   $(devel_api_src_dir)/common/hash.cpp \
+  $(devel_api_src_dir)/common/stage-devel.cpp \
   $(devel_api_src_dir)/events/hit-test-algorithm.cpp \
   $(devel_api_src_dir)/images/distance-field.cpp \
   $(devel_api_src_dir)/images/texture-set-image.cpp \
@@ -32,7 +33,8 @@ devel_api_core_common_header_files = \
   $(devel_api_src_dir)/common/map-wrapper.h \
   $(devel_api_src_dir)/common/owner-container.h \
   $(devel_api_src_dir)/common/ref-counted-dali-vector.h \
-  $(devel_api_src_dir)/common/set-wrapper.h
+  $(devel_api_src_dir)/common/set-wrapper.h \
+  $(devel_api_src_dir)/common/stage-devel.h
 
 devel_api_core_events_header_files = \
   $(devel_api_src_dir)/events/hit-test-algorithm.h
index a9abac8..c036a5d 100644 (file)
@@ -56,8 +56,10 @@ const float DEFAULT_STEREO_BASE( 65.0f );
 // Signals
 
 const char* const SIGNAL_KEY_EVENT =                 "keyEvent";
+const char* const SIGNAL_KEY_EVENT_GENERATED =       "keyEventGenerated";
 const char* const SIGNAL_EVENT_PROCESSING_FINISHED = "eventProcessingFinished";
 const char* const SIGNAL_TOUCHED =                   "touched";
+const char* const SIGNAL_TOUCH =                     "touch";
 const char* const SIGNAL_WHEEL_EVENT =               "wheelEvent";
 const char* const SIGNAL_CONTEXT_LOST =              "contextLost";
 const char* const SIGNAL_CONTEXT_REGAINED =          "contextRegained";
@@ -72,6 +74,8 @@ SignalConnectorType signalConnector4( mType, SIGNAL_WHEEL_EVENT,               &
 SignalConnectorType signalConnector5( mType, SIGNAL_CONTEXT_LOST,              &Stage::DoConnectSignal );
 SignalConnectorType signalConnector6( mType, SIGNAL_CONTEXT_REGAINED,          &Stage::DoConnectSignal );
 SignalConnectorType signalConnector7( mType, SIGNAL_SCENE_CREATED,             &Stage::DoConnectSignal );
+SignalConnectorType signalConnector8( mType, SIGNAL_KEY_EVENT_GENERATED,       &Stage::DoConnectSignal );
+SignalConnectorType signalConnector9( mType, SIGNAL_TOUCH,                     &Stage::DoConnectSignal );
 
 } // unnamed namespace
 
@@ -526,6 +530,10 @@ bool Stage::DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tra
   {
     stage->KeyEventSignal().Connect( tracker, functor );
   }
+  else if( 0 == strcmp( signalName.c_str(), SIGNAL_KEY_EVENT_GENERATED ) )
+  {
+    stage->KeyEventGeneratedSignal().Connect( tracker, functor );
+  }
   else if( 0 == strcmp( signalName.c_str(), SIGNAL_EVENT_PROCESSING_FINISHED ) )
   {
     stage->EventProcessingFinishedSignal().Connect( tracker, functor );
@@ -534,6 +542,10 @@ bool Stage::DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tra
   {
     stage->TouchedSignal().Connect( tracker, functor );
   }
+  else if( 0 == strcmp( signalName.c_str(), SIGNAL_TOUCH ) )
+  {
+    stage->TouchSignal().Connect( tracker, functor );
+  }
   else if( 0 == strcmp( signalName.c_str(), SIGNAL_WHEEL_EVENT ) )
   {
     stage->WheelEventSignal().Connect( tracker, functor );
@@ -566,6 +578,13 @@ void Stage::EmitKeyEventSignal(const KeyEvent& event)
   mKeyEventSignal.Emit( event );
 }
 
+bool Stage::EmitKeyEventGeneratedSignal(const KeyEvent& event)
+{
+  // Emit the KeyEventGenerated signal when KeyEvent is generated
+
+  return mKeyEventGeneratedSignal.Emit( event );
+}
+
 void Stage::EmitEventProcessingFinishedSignal()
 {
    mEventProcessingFinishedSignal.Emit();
@@ -594,6 +613,11 @@ Dali::Stage::KeyEventSignalType& Stage::KeyEventSignal()
   return mKeyEventSignal;
 }
 
+Dali::DevelStage::KeyEventGeneratedSignalType& Stage::KeyEventGeneratedSignal()
+{
+  return mKeyEventGeneratedSignal;
+}
+
 Dali::Stage::EventProcessingFinishedSignalType& Stage::EventProcessingFinishedSignal()
 {
   return mEventProcessingFinishedSignal;
index 415f87b..ef2c2c4 100644 (file)
@@ -21,6 +21,7 @@
 // INTERNAL INCLUDES
 #include <dali/public-api/object/ref-object.h>
 #include <dali/public-api/common/stage.h>
+#include <dali/devel-api/common/stage-devel.h>
 #include <dali/public-api/object/base-object.h>
 #include <dali/integration-api/context-notifier.h>
 #include <dali/internal/common/owner-pointer.h>
@@ -307,6 +308,13 @@ public:
   void EmitKeyEventSignal(const KeyEvent& event);
 
   /**
+   * Used by the KeyEventProcessor to emit KeyEventGenerated signals.
+   * @param[in] event The key event.
+   * @return The return is true if KeyEvent is consumed, otherwise false.
+   */
+  bool EmitKeyEventGeneratedSignal(const KeyEvent& event);
+
+  /**
    * Emits the event processing finished signal.
    *
    * @see Dali::Stage::SignalEventProcessingFinished()
@@ -372,6 +380,11 @@ public:
   Dali::Stage::SceneCreatedSignalType& SceneCreatedSignal();
 
   /**
+   * @copydoc Dali::DevelStage::KeyEventGeneratedSignal()
+   */
+  Dali::DevelStage::KeyEventGeneratedSignalType& KeyEventGeneratedSignal();
+
+  /**
    * Connects a callback function with the object's signals.
    * @param[in] object The object providing the signal.
    * @param[in] tracker Used to disconnect the signal.
@@ -482,6 +495,7 @@ private:
 
   // The key event signal
   Dali::Stage::KeyEventSignalType                 mKeyEventSignal;
+  Dali::DevelStage::KeyEventGeneratedSignalType   mKeyEventGeneratedSignal;
 
   // The event processing finished signal
   Dali::Stage::EventProcessingFinishedSignalType  mEventProcessingFinishedSignal;
index 5261d26..86d9592 100644 (file)
@@ -41,10 +41,16 @@ KeyEventProcessor::~KeyEventProcessor()
 
 void KeyEventProcessor::ProcessKeyEvent(const Integration::KeyEvent& event)
 {
+  bool consumed = false;
   KeyEvent keyEvent(event.keyName, event.keyString, event.keyCode, event.keyModifier, event.time, static_cast<KeyEvent::State>(event.state));
 
   // Emit the key event signal from stage.
-  mStage.EmitKeyEventSignal(keyEvent);
+  consumed = mStage.EmitKeyEventGeneratedSignal( keyEvent );
+
+  if( !consumed )
+  {
+    mStage.EmitKeyEventSignal(keyEvent);
+  }
 }
 
 } // namespace Internal