[dali_1.4.33] Merge branch 'devel/master' 78/212178/1
authorCheng-Shiun Tsai <cheng.tsai@samsung.com>
Fri, 16 Aug 2019 09:41:18 +0000 (10:41 +0100)
committerCheng-Shiun Tsai <cheng.tsai@samsung.com>
Fri, 16 Aug 2019 09:41:18 +0000 (10:41 +0100)
Change-Id: Ia4fda8194be3e12985f86c3923f1b8941fa329c3

12 files changed:
automated-tests/src/dali/utc-Dali-Animation.cpp
automated-tests/src/dali/utc-Dali-Renderer.cpp
automated-tests/src/dali/utc-Dali-Scene.cpp
dali/integration-api/scene.cpp
dali/integration-api/scene.h
dali/internal/event/animation/animation-impl.cpp
dali/internal/event/animation/animation-impl.h
dali/internal/event/common/scene-impl.cpp
dali/internal/event/common/scene-impl.h
dali/internal/event/events/key-event-processor.cpp
dali/public-api/dali-core-version.cpp
packaging/dali.spec

index 254c862..41517d1 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2019 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.
@@ -42,6 +42,7 @@ namespace
 
 static const float ROTATION_EPSILON = 0.0001f;
 static const float VECTOR4_EPSILON = 0.0001f;
+static const float VECTOR3_EPSILON = 0.0001f;
 
 // Functor to test whether a Finish signal is emitted
 struct AnimationFinishCheck
@@ -815,7 +816,7 @@ int UtcDaliAnimationIsLoopingP(void)
   END_TEST;
 }
 
-int UtcDaliAnimationSetEndActioN(void)
+int UtcDaliAnimationSetEndActionN(void)
 {
   TestApplication application;
 
@@ -13311,3 +13312,145 @@ int UtcDaliAnimationAnimateBetweenInvalidParameters(void)
 
   END_TEST;
 }
+
+namespace // Purposefully left this in the middle as the values in this namespace are only used for the subsequent two test cases
+{
+enum TestFunction
+{
+  STOP,
+  CLEAR
+};
+
+void CheckPropertyValuesWhenCallingAnimationMethod( TestFunction functionToTest, const char * testName )
+{
+  tet_printf( "Testing %s\n", testName );
+
+  // When an Animation::Stop() or Animation::Clear() is called, the event-side property needs to be updated appropriately
+  // This test checks that that is being done
+
+  const float durationSeconds( 1.0f );
+  unsigned int halfAnimationDuration( static_cast< unsigned int >( durationSeconds * 1000.0f * 0.5f ) );
+  const Vector3 originalPosition( Vector3::ZERO );
+  const Vector3 targetPosition( 10.0f, 10.0f, 10.0f );
+  const Vector3 halfWayToTarget( targetPosition * 0.5f );
+
+  struct ExpectedValue
+  {
+    Animation::EndAction endAction;
+    Vector3 expectedGetPropertyValue;
+  };
+
+  ExpectedValue expectedValueTable[] =
+  {
+   { Animation::Bake,      halfWayToTarget  }, // When baking, the current value is the final value.
+   { Animation::BakeFinal, targetPosition   }, // When BakeFinal, we should jump to the final value when clearing or stopping.
+   { Animation::Discard,   originalPosition }, // When discarding, we should jump back to the original value when clearing or stopping.
+  };
+  const auto expectedValueTableCount = sizeof( expectedValueTable ) / sizeof( ExpectedValue );
+
+  for( auto i = 0u; i < expectedValueTableCount; ++i  )
+  {
+    TestApplication application;
+
+    Actor actor = Actor::New();
+    Stage::GetCurrent().Add(actor);
+
+    // Build the animation
+    Animation animation = Animation::New( durationSeconds );
+    animation.SetEndAction( expectedValueTable[ i ].endAction );
+    animation.AnimateTo( Property( actor, Actor::Property::POSITION ), targetPosition, AlphaFunction::LINEAR );
+
+    // Start the animation
+    animation.Play();
+
+    application.SendNotification();
+    application.Render( halfAnimationDuration );
+
+    // Stop or Clear the animation early, both have the same effect
+    if( functionToTest == TestFunction::STOP )
+    {
+      animation.Stop();
+    }
+    else
+    {
+      animation.Clear();
+    }
+
+    // The event side property should be set the expected value immediately, the update side property will still only be halfway as we haven't run an update yet
+    DALI_TEST_EQUALS( actor.GetProperty( Actor::Property::POSITION ).Get< Vector3 >(), expectedValueTable[ i ].expectedGetPropertyValue, VECTOR3_EPSILON, TEST_LOCATION );
+    DALI_TEST_EQUALS( actor.GetCurrentProperty( Actor::Property::POSITION ).Get< Vector3 >(), halfWayToTarget, VECTOR3_EPSILON, TEST_LOCATION );
+
+    // After one frame, both values should match regardless of the End Action
+    application.SendNotification();
+    application.Render();
+
+    DALI_TEST_EQUALS( actor.GetProperty( Actor::Property::POSITION ).Get< Vector3 >(), expectedValueTable[ i ].expectedGetPropertyValue, VECTOR3_EPSILON, TEST_LOCATION );
+    DALI_TEST_EQUALS( actor.GetCurrentProperty( Actor::Property::POSITION ).Get< Vector3 >(), expectedValueTable[ i ].expectedGetPropertyValue, VECTOR3_EPSILON, TEST_LOCATION );
+  }
+}
+} // unnamed namespace
+
+int UtcDaliAnimationStopPropertyValue(void)
+{
+  CheckPropertyValuesWhenCallingAnimationMethod( TestFunction::STOP, "UtcDaliAnimationStopPropertyValue" );
+  END_TEST;
+}
+
+int UtcDaliAnimationClearPropertyValue(void)
+{
+  CheckPropertyValuesWhenCallingAnimationMethod( TestFunction::CLEAR, "UtcDaliAnimationStopPropertyValue" );
+  END_TEST;
+}
+
+int UtcDaliAnimationPausePropertyValue(void)
+{
+  const float durationSeconds( 1.0f );
+  unsigned int halfAnimationDuration( static_cast< unsigned int >( durationSeconds * 1000.0f * 0.5f ) );
+  const Vector3 originalPosition( Vector3::ZERO );
+  const Vector3 targetPosition( 10.0f, 10.0f, 10.0f );
+  const Vector3 halfWayToTarget( targetPosition * 0.5f );
+
+  Animation::EndAction endActions[] =
+  {
+   Animation::Bake,
+   Animation::BakeFinal,
+   Animation::Discard,
+  };
+  const auto endActionCount = sizeof( endActions ) / sizeof( endActions[0] );
+
+  // For all end actions, when pausing, we stay at the current value
+  for( auto i = 0u; i < endActionCount; ++i  )
+  {
+    TestApplication application;
+
+    Actor actor = Actor::New();
+    Stage::GetCurrent().Add(actor);
+
+    // Build the animation
+    Animation animation = Animation::New( durationSeconds );
+    animation.SetEndAction( endActions[ i ] );
+    animation.AnimateTo( Property( actor, Actor::Property::POSITION ), targetPosition, AlphaFunction::LINEAR );
+
+    // Start the animation
+    animation.Play();
+
+    application.SendNotification();
+    application.Render( halfAnimationDuration );
+
+    // Puase the animation early
+    animation.Pause();
+
+    // The event side property should be set the current value immediately, the update side property will still only be halfway
+    DALI_TEST_EQUALS( actor.GetProperty( Actor::Property::POSITION ).Get< Vector3 >(), halfWayToTarget, VECTOR3_EPSILON, TEST_LOCATION );
+    DALI_TEST_EQUALS( actor.GetCurrentProperty( Actor::Property::POSITION ).Get< Vector3 >(), halfWayToTarget, VECTOR3_EPSILON, TEST_LOCATION );
+
+    // After one frame, both values should match regardless of the End Action
+    application.SendNotification();
+    application.Render();
+
+    DALI_TEST_EQUALS( actor.GetProperty( Actor::Property::POSITION ).Get< Vector3 >(), halfWayToTarget, VECTOR3_EPSILON, TEST_LOCATION );
+    DALI_TEST_EQUALS( actor.GetCurrentProperty( Actor::Property::POSITION ).Get< Vector3 >(), halfWayToTarget, VECTOR3_EPSILON, TEST_LOCATION );
+  }
+
+  END_TEST;
+}
index d1c81f6..0410a52 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2019 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.
@@ -2897,9 +2897,10 @@ int UtcDaliRendererOpacityAnimation(void)
   DALI_TEST_CHECK( value.Get( opacity ) );
   DALI_TEST_EQUALS( opacity, 0.0f, Dali::Math::MACHINE_EPSILON_1, TEST_LOCATION );
 
+  // Need to clear the animation before setting the property as the animation value is baked and will override any previous setters
+  animation.Clear();
   renderer.SetProperty( DevelRenderer::Property::OPACITY, 0.1f );
 
-  animation.Clear();
   animation.AnimateBy( Property( renderer, DevelRenderer::Property::OPACITY ), 0.5f );
   animation.Play();
 
@@ -2909,6 +2910,7 @@ int UtcDaliRendererOpacityAnimation(void)
   value = renderer.GetProperty( DevelRenderer::Property::OPACITY );
   DALI_TEST_CHECK( value.Get( opacity ) );
   DALI_TEST_EQUALS( opacity, 0.6f, Dali::Math::MACHINE_EPSILON_1, TEST_LOCATION );
+  DALI_TEST_EQUALS( opacity, renderer.GetCurrentProperty( DevelRenderer::Property::OPACITY ).Get< float >(), Dali::Math::MACHINE_EPSILON_1, TEST_LOCATION );
 
   END_TEST;
 }
index b914478..8508728 100644 (file)
@@ -190,6 +190,50 @@ struct WheelEventReceivedFunctor
   WheelEventSignalData& signalData;
 };
 
+// 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;
+};
+
 void GenerateTouch( TestApplication& application, PointState::Type state, const Vector2& screenPosition )
 {
   Integration::TouchEvent touchEvent;
@@ -1134,3 +1178,56 @@ int UtcDaliSceneSetSurface(void)
 
   END_TEST;
 }
+
+int UtcDaliSceneKeyEventGeneratedSignalP(void)
+{
+  TestApplication application;
+  Dali::Integration::Scene scene = application.GetScene();
+
+  KeyEventGeneratedSignalData data;
+  KeyEventGeneratedReceivedFunctor functor( data );
+  scene.KeyEventGeneratedSignal().Connect( &application, functor );
+
+  Integration::KeyEvent event( "a", "", "a", 0, 0, 0, Integration::KeyEvent::Up, "a", DEFAULT_DEVICE_NAME, Device::Class::NONE, Device::Subclass::NONE );
+  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, "i", DEFAULT_DEVICE_NAME, Device::Class::NONE, Device::Subclass::NONE );
+  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, "a", DEFAULT_DEVICE_NAME, Device::Class::NONE, Device::Subclass::NONE );
+  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, "a", DEFAULT_DEVICE_NAME, Device::Class::NONE, Device::Subclass::NONE );
+  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;
+}
index 38e2477..8fef6db 100644 (file)
@@ -164,6 +164,11 @@ Scene::KeyEventSignalType& Scene::KeyEventSignal()
   return GetImplementation(*this).KeyEventSignal();
 }
 
+Scene::KeyEventGeneratedSignalType& Scene::KeyEventGeneratedSignal()
+{
+  return GetImplementation(*this).KeyEventGeneratedSignal();
+}
+
 Scene::TouchSignalType& Scene::TouchSignal()
 {
   return GetImplementation(*this).TouchSignal();
index c53c413..dca7cbc 100755 (executable)
@@ -55,6 +55,7 @@ class DALI_CORE_API Scene : public BaseHandle
 public:
   typedef Signal< void () > EventProcessingFinishedSignalType; ///< Event Processing finished signal type
   typedef Signal< void (const Dali::KeyEvent&) > KeyEventSignalType; ///< Key event signal type
+  typedef Signal< bool (const Dali::KeyEvent&) > KeyEventGeneratedSignalType; ///< key event generated signal type
   typedef Signal< void (const Dali::TouchData&) > TouchSignalType; ///< Touch signal type
   typedef Signal< void (const Dali::WheelEvent&) > WheelEventSignalType; ///< Touched signal type
 
@@ -254,6 +255,22 @@ public:
   KeyEventSignalType& KeyEventSignal();
 
   /**
+   * @brief The user would connect to this signal to get a KeyEvent when KeyEvent is generated.
+   *
+   * If the control already consumed key event, KeyEventProcessor do not need to Emit keyEvent.
+   * Therefore, KeyinputManager first checks whether KeyEvent is generated as KeyEventGeneratedSignal.
+   * After that keyEventProcessor must invoke KeyEvent only if KeyEventGeneratedSignal () is not consumed.
+   *
+   * A callback of the following type may be connected:
+   * @code
+   *   bool YourCallbackName(const KeyEvent& event);
+   * @endcode
+   *
+   * @return The return is true if KeyEvent is consumed, otherwise false.
+   */
+  KeyEventGeneratedSignalType& KeyEventGeneratedSignal();
+
+  /**
    * @brief This signal is emitted when the screen is touched and when the touch ends
    * (i.e. the down & up touch events only).
    *
index 876ec29..ceab690 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2019 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.
@@ -319,7 +319,7 @@ void Animation::Play()
 
   mState = Dali::Animation::PLAYING;
 
-  NotifyObjects();
+  NotifyObjects( Notify::USE_TARGET_VALUE );
 
   SendFinalProgressNotificationMessage();
 
@@ -336,7 +336,7 @@ void Animation::PlayFrom( float progress )
 
     mState = Dali::Animation::PLAYING;
 
-    NotifyObjects();
+    NotifyObjects( Notify::USE_TARGET_VALUE );
 
     SendFinalProgressNotificationMessage();
 
@@ -357,7 +357,7 @@ void Animation::PlayAfter( float delaySeconds )
 
   mState = Dali::Animation::PLAYING;
 
-  NotifyObjects();
+  NotifyObjects( Notify::USE_TARGET_VALUE );
 
   SendFinalProgressNotificationMessage();
 
@@ -371,6 +371,9 @@ void Animation::Pause()
 
   // mAnimation is being used in a separate thread; queue a Pause message
   PauseAnimationMessage( mEventThreadServices, *mAnimation );
+
+  // Notify the objects with the _paused_, i.e. current values
+  NotifyObjects( Notify::FORCE_CURRENT_VALUE );
 }
 
 Dali::Animation::State Animation::GetState() const
@@ -384,12 +387,24 @@ void Animation::Stop()
 
   // mAnimation is being used in a separate thread; queue a Stop message
   StopAnimationMessage( mEventThreadServices.GetUpdateManager(), *mAnimation );
+
+  // Only notify the objects with the _stopped_, i.e. current values if the end action is set to BAKE
+  if( mEndAction == EndAction::Bake )
+  {
+    NotifyObjects( Notify::USE_CURRENT_VALUE );
+  }
 }
 
 void Animation::Clear()
 {
   DALI_ASSERT_DEBUG(mAnimation);
 
+  // Only notify the objects with the current values if the end action is set to BAKE
+  if( mEndAction == EndAction::Bake )
+  {
+    NotifyObjects( Notify::USE_CURRENT_VALUE );
+  }
+
   // Remove all the connectors
   mConnectors.Clear();
 
@@ -1073,12 +1088,17 @@ bool Animation::CompareConnectorEndTimes( const Animation::ConnectorTargetValues
   return ( ( lhs.timePeriod.delaySeconds + lhs.timePeriod.durationSeconds ) < ( rhs.timePeriod.delaySeconds + rhs.timePeriod.durationSeconds ) );
 }
 
-void Animation::NotifyObjects()
+void Animation::NotifyObjects( Animation::Notify notifyValueType )
 {
-  if( mEndAction != EndAction::Discard ) // If the animation is discarded, then we do not want to change the target values
+  // If the animation is discarded, then we do not want to change the target values unless we want to force the current values
+  if( mEndAction != EndAction::Discard || notifyValueType == Notify::FORCE_CURRENT_VALUE )
   {
     // Sort according to end time with earlier end times coming first, if the end time is the same, then the connectors are not moved
-    std::stable_sort( mConnectorTargetValues.begin(), mConnectorTargetValues.end(), CompareConnectorEndTimes );
+    // Only do this if we're using the target value
+    if( notifyValueType == Notify::USE_TARGET_VALUE )
+    {
+      std::stable_sort( mConnectorTargetValues.begin(), mConnectorTargetValues.end(), CompareConnectorEndTimes );
+    }
 
     // Loop through all connector target values sorted by increasing end time
     ConnectorTargetValuesContainer::const_iterator iter = mConnectorTargetValues.begin();
@@ -1090,7 +1110,12 @@ void Animation::NotifyObjects()
       Object* object = connector->GetObject();
       if( object )
       {
-        object->NotifyPropertyAnimation( *this, connector->GetPropertyIndex(), iter->targetValue, iter->animatorType );
+        const auto propertyIndex = connector->GetPropertyIndex();
+        object->NotifyPropertyAnimation(
+          *this,
+          propertyIndex,
+          ( notifyValueType == Notify::USE_TARGET_VALUE ) ? iter->targetValue : object->GetCurrentProperty( propertyIndex ),
+          iter->animatorType );
       }
     }
   }
index 124140c..454b066 100644 (file)
@@ -490,6 +490,13 @@ private:
     Animation::Type animatorType;
   };
 
+  enum class Notify
+  {
+    USE_CURRENT_VALUE,   ///< Set the current value for the property
+    USE_TARGET_VALUE,    ///< Set the animator's target value for the property
+    FORCE_CURRENT_VALUE, ///< Set the current value for the property even if the end action is to discard
+  };
+
 private:
 
   /**
@@ -502,8 +509,9 @@ private:
 
   /**
    * Notifies all the objects whose properties are being animated.
+   * @param[in] notifyValueType Whether we should set the current or target value
    */
-  void NotifyObjects();
+  void NotifyObjects( Notify notifyValueType );
 
   /**
    * Sends message to SceneGraph with final progress value
index a4c65c5..c14470d 100644 (file)
@@ -321,6 +321,12 @@ void Scene::EmitKeyEventSignal(const KeyEvent& event)
   }
 }
 
+bool Scene::EmitKeyEventGeneratedSignal(const KeyEvent& event)
+{
+  // Emit the KeyEventGenerated signal when KeyEvent is generated
+  return mKeyEventGeneratedSignal.Emit( event );
+}
+
 void Scene::EmitEventProcessingFinishedSignal()
 {
   if ( !mEventProcessingFinishedSignal.Empty() )
@@ -357,6 +363,11 @@ Integration::Scene::KeyEventSignalType& Scene::KeyEventSignal()
   return mKeyEventSignal;
 }
 
+Integration::Scene::KeyEventGeneratedSignalType& Scene::KeyEventGeneratedSignal()
+{
+  return mKeyEventGeneratedSignal;
+}
+
 Integration::Scene::EventProcessingFinishedSignalType& Scene::EventProcessingFinishedSignal()
 {
   return mEventProcessingFinishedSignal;
index 2c93c84..f9db963 100644 (file)
@@ -187,6 +187,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::Scene::SignalEventProcessingFinished()
@@ -211,6 +218,11 @@ public:
    */
   Integration::Scene::KeyEventSignalType& KeyEventSignal();
 
+    /**
+   * @copydoc Integration::Scene::KeyEventGeneratedSignal()
+   */
+  Integration::Scene::KeyEventGeneratedSignalType& KeyEventGeneratedSignal();
+
   /**
    * @copydoc Integration::Scene::SignalEventProcessingFinished()
    */
@@ -292,6 +304,7 @@ private:
 
   // The key event signal
   Integration::Scene::KeyEventSignalType mKeyEventSignal;
+  Integration::Scene::KeyEventGeneratedSignalType   mKeyEventGeneratedSignal;
 
   // The event processing finished signal
   Integration::Scene::EventProcessingFinishedSignalType mEventProcessingFinishedSignal;
index 399c209..65be14e 100755 (executable)
@@ -50,7 +50,12 @@ void KeyEventProcessor::ProcessKeyEvent( const Integration::KeyEvent& event )
   GetImplementation( &keyEvent )->SetDeviceSubclass( event.deviceSubclass );
 
   // Emit the key event signal from the scene.
-  mScene.EmitKeyEventSignal( keyEvent );
+  bool consumed = mScene.EmitKeyEventGeneratedSignal( keyEvent );
+  if( !consumed )
+  {
+    mScene.EmitKeyEventSignal(keyEvent);
+  }
+
 }
 
 } // namespace Internal
index 5dd482b..e370ed3 100644 (file)
@@ -28,7 +28,7 @@ namespace Dali
 
 const uint32_t CORE_MAJOR_VERSION = 1;
 const uint32_t CORE_MINOR_VERSION = 4;
-const uint32_t CORE_MICRO_VERSION = 32;
+const uint32_t CORE_MICRO_VERSION = 33;
 const char * const CORE_BUILD_DATE    = __DATE__ " " __TIME__;
 
 #ifdef DEBUG_ENABLED
index fe7b37b..054d2e7 100644 (file)
@@ -1,6 +1,6 @@
 Name:       dali
 Summary:    DALi 3D Engine
-Version:    1.4.32
+Version:    1.4.33
 Release:    1
 Group:      System/Libraries
 License:    Apache-2.0 and BSD-3-Clause and MIT