Removed feedback controller Boost dependency 91/42891/10
authorLee Morgan <Lee.morgan@partner.samsung.com>
Fri, 3 Jul 2015 13:57:46 +0000 (14:57 +0100)
committerLee Morgan <Lee.morgan@partner.samsung.com>
Tue, 14 Jul 2015 14:16:58 +0000 (15:16 +0100)
Moved feedback controller to toolkit to use json parser

Change-Id: I57372ecd78c0147d58cd9c7620c812fd3a1da6e0

12 files changed:
dali-toolkit/devel-api/builder/json-parser.cpp
dali-toolkit/devel-api/builder/json-parser.h
dali-toolkit/internal/builder/json-parser-impl.cpp
dali-toolkit/internal/builder/json-parser-impl.h
dali-toolkit/internal/feedback/feedback-ids.h [new file with mode: 0644]
dali-toolkit/internal/feedback/feedback-style.cpp [new file with mode: 0644]
dali-toolkit/internal/feedback/feedback-style.h [new file with mode: 0644]
dali-toolkit/internal/file.list
dali-toolkit/internal/styling/style-manager-impl.cpp
dali-toolkit/internal/styling/style-manager-impl.h
dali-toolkit/public-api/controls/control-impl.cpp
dali-toolkit/styles/default-feedback-theme.json [new file with mode: 0644]

index 5d3838e..5e8c0ae 100644 (file)
@@ -59,7 +59,7 @@ JsonParser DownCast( BaseHandle handle )
   return JsonParser( dynamic_cast<Internal::JsonParser*>(handle.GetObjectPtr()) );
 }
 
-int JsonParser::Parse(const std::string& source)
+bool JsonParser::Parse(const std::string& source)
 {
   return GetImplementation(*this).Parse(source);
 }
index b871948..05b8e80 100644 (file)
@@ -81,9 +81,9 @@ public:
    * Parse the source and construct a node tree.
    * Subsequent calls to this function will merge the trees.
    * @param source The json source to parse
-   * @return zero if parsed okay, otherwise an error.
+   * @return true if parsed okay, otherwise an error.
    */
-  int Parse(const std::string& source);
+  bool Parse(const std::string& source);
 
   /*
    * Optimize memory usage by packing strings
index 2cff977..fdec738 100644 (file)
@@ -96,7 +96,7 @@ JsonParser::~JsonParser()
   }
 }
 
-int JsonParser::Parse(const std::string& source)
+bool JsonParser::Parse(const std::string& source)
 {
   mSources.push_back( VectorChar(source.begin(), source.end()) );
 
index 9936974..dbdbf45 100644 (file)
@@ -62,7 +62,7 @@ public:
   /*
    * @copydoc Toolkit::JsonParser::Parse()
    */
-  int Parse(const std::string& source);
+  bool Parse(const std::string& source);
 
   /*
    * @copydoc Toolkit::JsonParser::Pack()
diff --git a/dali-toolkit/internal/feedback/feedback-ids.h b/dali-toolkit/internal/feedback/feedback-ids.h
new file mode 100644 (file)
index 0000000..cb7ffa3
--- /dev/null
@@ -0,0 +1,105 @@
+#ifndef __DALI_FEEDBACK_IDS_H__
+#define __DALI_FEEDBACK_IDS_H__
+
+/*
+ * Copyright (c) 2014 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.
+ *
+ */
+
+namespace Dali
+{
+
+/**
+ *  Enumerations for the types of feedback
+ *  Note: These are based on feedback_type_e in libsvi
+ */
+enum FeedbackType
+{
+  FEEDBACK_TYPE_NONE,
+
+  FEEDBACK_TYPE_SOUND,
+  FEEDBACK_TYPE_VIBRATION,
+  FEEDBACK_TYPE_LED,
+
+  FEEDBACK_TYPE_END
+};
+
+/**
+ *  The pattern list for feedback effects.
+ *  Note: These are based on feedback_pattern_e in libsvi
+ */
+enum FeedbackPattern
+{
+  FEEDBACK_PATTERN_NONE = -1,
+
+  FEEDBACK_PATTERN_TAP = 0,           /**< feedback pattern when general touch */
+  FEEDBACK_PATTERN_SIP,               /**< feedback pattern when touch text key */
+  FEEDBACK_PATTERN_SIP_BACKSPACE,     /**< feedback pattern when touch backspace key */
+  FEEDBACK_PATTERN_MAX_CHARACTER,     /**< feedback pattern when max character */
+  FEEDBACK_PATTERN_KEY0,              /**< feedback pattern when touch numeric 0 key */
+  FEEDBACK_PATTERN_KEY1,              /**< feedback pattern when touch numeric 1 key */
+  FEEDBACK_PATTERN_KEY2,              /**< feedback pattern when touch numeric 2 key */
+  FEEDBACK_PATTERN_KEY3,              /**< feedback pattern when touch numeric 3 key */
+  FEEDBACK_PATTERN_KEY4,              /**< feedback pattern when touch numeric 4 key */
+  FEEDBACK_PATTERN_KEY5,              /**< feedback pattern when touch numeric 5 key */
+  FEEDBACK_PATTERN_KEY6,              /**< feedback pattern when touch numeric 6 key */
+  FEEDBACK_PATTERN_KEY7,              /**< feedback pattern when touch numeric 7 key */
+  FEEDBACK_PATTERN_KEY8,              /**< feedback pattern when touch numeric 8 key */
+  FEEDBACK_PATTERN_KEY9,              /**< feedback pattern when touch numeric 9 key */
+  FEEDBACK_PATTERN_KEY_STAR,          /**< feedback pattern when touch star key */
+  FEEDBACK_PATTERN_KEY_SHARP,         /**< feedback pattern when touch sharp key */
+  FEEDBACK_PATTERN_HOLD,              /**< feedback pattern when touch hold */
+  FEEDBACK_PATTERN_MULTI_TAP,         /**< feedback pattern when multi touch */
+  FEEDBACK_PATTERN_HW_TAP,            /**< feedback pattern when press hardware key */
+  FEEDBACK_PATTERN_HW_HOLD,           /**< feedback pattern when holding press hardware key */
+
+  FEEDBACK_PATTERN_MESSAGE,           /**< feedback pattern when incoming a message */
+  FEEDBACK_PATTERN_MESSAGE_ON_CALL,   /**< feedback pattern when incoming a message on call */
+  FEEDBACK_PATTERN_EMAIL,             /**< feedback pattern when incoming an email */
+  FEEDBACK_PATTERN_EMAIL_ON_CALL,     /**< feedback pattern when incoming an email on call */
+  FEEDBACK_PATTERN_WAKEUP,            /**< feedback pattern when alert wake up call */
+  FEEDBACK_PATTERN_WAKEUP_ON_CALL,    /**< feedback pattern when alert wake up call on call */
+  FEEDBACK_PATTERN_SCHEDULE,          /**< feedback pattern when alert schedule alarm */
+  FEEDBACK_PATTERN_SCHEDULE_ON_CALL,    /**< feedback pattern when alert schedule alarm on call */
+  FEEDBACK_PATTERN_TIMER,             /**< feedback pattern when alert timer */
+  FEEDBACK_PATTERN_TIMER_ON_CALL,     /**< feedback pattern when alert timer on call */
+  FEEDBACK_PATTERN_GENERAL,           /**< feedback pattern when alert general event */
+  FEEDBACK_PATTERN_GENERAL_ON_CALL,   /**< feedback pattern when alert general event on call */
+
+  FEEDBACK_PATTERN_POWER_ON,           /**< feedback pattern when power on */
+  FEEDBACK_PATTERN_POWER_OFF,           /**< feedback pattern when power off */
+  FEEDBACK_PATTERN_CHARGERCONN,         /**< feedback pattern when connecting charger */
+  FEEDBACK_PATTERN_CHARGERCONN_ON_CALL, /**< feedback pattern when connecting charger on call */
+  FEEDBACK_PATTERN_FULLCHARGED,         /**< feedback pattern when full charged */
+  FEEDBACK_PATTERN_FULLCHARGED_ON_CALL, /**< feedback pattern when full charged on call */
+  FEEDBACK_PATTERN_LOWBATT,             /**< feedback pattern when low battery */
+  FEEDBACK_PATTERN_LOWBATT_ON_CALL,     /**< feedback pattern when low battery on call */
+  FEEDBACK_PATTERN_LOCK,                /**< feedback pattern when lock */
+  FEEDBACK_PATTERN_UNLOCK,              /**< feedback pattern when unlock */
+  FEEDBACK_PATTERN_CALLCONNECT,         /**< feedback pattern when connecting call */
+  FEEDBACK_PATTERN_DISCALLCONNECT,      /**< feedback pattern when disconnecting call */
+  FEEDBACK_PATTERN_MINUTEMINDER,        /**< feedback pattern when minute minder */
+  FEEDBACK_PATTERN_VIBRATION,           /**< feedback pattern when vibration */
+  FEEDBACK_PATTERN_SHUTTER,             /**< feedback pattern when screen capture or camera shutter */
+  FEEDBACK_PATTERN_LIST_REORDER,        /**< feedback pattern when list reorder */
+  FEEDBACK_PATTERN_SLIDER_SWEEP,        /**< feedback pattern when slider sweep */
+
+  FEEDBACK_PATTERN_END,
+};
+
+
+}  // namespace Dali
+
+#endif // __DALI_FEEDBACK_IDS_H__
diff --git a/dali-toolkit/internal/feedback/feedback-style.cpp b/dali-toolkit/internal/feedback/feedback-style.cpp
new file mode 100644 (file)
index 0000000..c1dca7e
--- /dev/null
@@ -0,0 +1,470 @@
+/*
+ * Copyright (c) 2014 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.
+ *
+ */
+
+// CLASS HEADER
+#include <dali-toolkit/internal/feedback/feedback-style.h>
+
+// EXTERNAL INCLUDES
+#include <dali/integration-api/debug.h>
+#include <dali/public-api/common/stage.h>
+#include <dali/public-api/object/object-registry.h>
+#include <dali/devel-api/adaptor-framework/style-monitor.h>
+
+// INTERNAL INCLUDES
+#include <dali-toolkit/devel-api/builder/json-parser.h>
+#include <dali-toolkit/internal/feedback/feedback-ids.h>
+
+using std::string;
+
+namespace // unnamed namespace
+{
+
+#if defined(DEBUG_ENABLED)
+Debug::Filter* gLogFilter = Debug::Filter::New(Debug::General, false, "LOG_FEEDBACK");
+#endif
+
+const char* DEFAULT_FEEDBACK_THEME_PATH = DALI_STYLE_DIR"default-feedback-theme.json";
+
+// Sets bool and string if the node has a child "name"
+void GetIfString(const Dali::Toolkit::TreeNode& node, const std::string& name, bool& exists, std::string& str)
+{
+  const Dali::Toolkit::TreeNode* child = node.GetChild(name);
+  if( child &&
+      Dali::Toolkit::TreeNode::STRING == child->GetType() )
+  {
+    exists = true;
+    str = child->GetString();
+  }
+}
+
+} // unnamed namespace
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+namespace Internal
+{
+
+struct SignalFeedbackInfo
+{
+  /**
+   * Default constructor.
+   */
+  SignalFeedbackInfo()
+  :mHasHapticFeedbackInfo(false),
+   mHasSoundFeedbackInfo(false)
+  {
+  }
+
+  bool mHasHapticFeedbackInfo;
+  bool mHasSoundFeedbackInfo;
+  string mSignalName;
+  string mHapticFeedbackPattern;
+  string mSoundFeedbackPattern;
+  string mHapticFeedbackFile;
+  string mSoundFeedbackFile;
+};
+
+typedef std::vector<SignalFeedbackInfo> SignalFeedbackInfoContainer;
+typedef SignalFeedbackInfoContainer::const_iterator SignalFeedbackInfoConstIter;
+
+struct FeedbackStyleInfo
+{
+  /**
+   * Default constructor.
+   */
+  FeedbackStyleInfo()
+  {
+  }
+
+  string mTypeName;
+
+  SignalFeedbackInfoContainer mSignalFeedbackInfoList;
+};
+
+static const FeedbackStyleInfo DEFAULT_FEEDBACK_STYLE_INFO;
+
+FeedbackStyle::FeedbackStyle()
+: mConnections( this )
+{
+  mFeedback = Dali::FeedbackPlayer::Get();
+
+  string defaultTheme;
+
+  if( mFeedback && mFeedback.LoadFile( DEFAULT_FEEDBACK_THEME_PATH, defaultTheme ) )
+  {
+    LoadTheme( defaultTheme );
+    DALI_LOG_INFO( gLogFilter, Debug::Verbose, "ResourceLoader::LoadTheme(%s) - loaded %d bytes\n",
+                   DEFAULT_FEEDBACK_THEME_PATH, defaultTheme.size() );
+  }
+  else
+  {
+    DALI_LOG_ERROR("ResourceLoader::LoadTheme(%s) - failed to load\n", DEFAULT_FEEDBACK_THEME_PATH);
+  }
+
+}
+
+FeedbackStyle::~FeedbackStyle()
+{
+}
+
+struct PlayFeedbackFromSignal
+{
+  PlayFeedbackFromSignal( FeedbackStyle& controller, const string& typeName, const string& signalName )
+  : mController( controller ),
+    mTypeName( typeName ),
+    mSignalName( signalName )
+  {
+  }
+
+  void operator()()
+  {
+    mController.PlayFeedback( mTypeName, mSignalName );
+  }
+
+  FeedbackStyle& mController;
+  string mTypeName;
+  string mSignalName;
+};
+
+
+void FeedbackStyle::ObjectCreated( BaseHandle handle )
+{
+  std::string typeName = handle.GetTypeName();
+
+  if( handle )
+  {
+    string type = handle.GetTypeName();
+
+    const FeedbackStyleInfo styleInfo = GetStyleInfo( type );
+
+    for( SignalFeedbackInfoConstIter iter = styleInfo.mSignalFeedbackInfoList.begin(); iter != styleInfo.mSignalFeedbackInfoList.end(); ++iter )
+    {
+      const SignalFeedbackInfo& info = *iter;
+
+      if( info.mHasHapticFeedbackInfo || info.mHasSoundFeedbackInfo )
+      {
+        if( !info.mHapticFeedbackPattern.empty() || !info.mHapticFeedbackFile.empty() ||
+            !info.mSoundFeedbackPattern.empty()  || !info.mSoundFeedbackFile.empty() )
+        {
+          handle.ConnectSignal( this,
+                                info.mSignalName,
+                                PlayFeedbackFromSignal( *this, type, info.mSignalName ) );
+
+          DALI_LOG_INFO( gLogFilter, Debug::Verbose, "FeedbackStyle::Set found Haptic pattern %s for Object type: %s, Signal Type: %s\n",
+                         info.mHapticFeedbackPattern.c_str(), type.c_str(), info.mSignalName.c_str() );
+        }
+        else
+        {
+          DALI_LOG_ERROR("FeedbackStyle::Set() Warning Inconsistent data in theme file!\n");
+        }
+      }
+    }
+  }
+}
+
+const FeedbackStyleInfo& FeedbackStyle::GetStyleInfo( const string& type ) const
+{
+  std::map<const string, FeedbackStyleInfo>::const_iterator iter( mStyleInfoLut.find( type ) );
+  if( iter != mStyleInfoLut.end() )
+  {
+    return iter->second;
+  }
+  else
+  {
+    return DEFAULT_FEEDBACK_STYLE_INFO;
+  }
+}
+
+void FeedbackStyle::StyleChanged( const std::string& userDefinedThemePath, Dali::StyleChange::Type styleChange )
+{
+  if( StyleChange::THEME_CHANGE )
+  {
+    string userDefinedTheme;
+
+    if( mFeedback && mFeedback.LoadFile( userDefinedThemePath, userDefinedTheme ) )
+    {
+      if( !LoadTheme( userDefinedTheme ) )
+      {
+        DALI_LOG_ERROR("FeedbackStyle::StyleChanged() User defined theme failed to load! \n");
+
+        //If there is any problem is using the user defined theme, then fall back to default theme
+        if( !LoadTheme( DEFAULT_FEEDBACK_THEME_PATH ) )
+        {
+          //If the default theme fails, Then No luck!
+          DALI_LOG_ERROR("FeedbackStyle::StyleChanged() Default theme failed to load! \n");
+        }
+      }
+      else
+      {
+        DALI_LOG_INFO( gLogFilter, Debug::Verbose, "ResourceLoader::LoadTheme(%s) - loaded %d bytes\n",
+                       userDefinedThemePath.c_str(), userDefinedTheme.size() );
+      }
+    }
+    else
+    {
+      DALI_LOG_ERROR("ResourceLoader::LoadTheme(%s) - failed to load\n", userDefinedThemePath.c_str());
+    }
+  }
+}
+
+bool FeedbackStyle::LoadTheme( const string& data )
+{
+  bool result = false;
+
+  try
+  {
+    LoadFromString( data );
+
+    result = true;
+  }
+  catch(...)
+  {
+    //Problem in user set theme, So fallback to use default theme.
+    DALI_LOG_ERROR( "FeedbackStyle::LoadTheme() Failed to load theme\n" );
+  }
+
+  return result;
+}
+
+void FeedbackStyle::LoadFromString( const string& data )
+{
+  Toolkit::JsonParser parser = Toolkit::JsonParser::New();
+  const Toolkit::TreeNode* root = NULL;
+
+  if( !parser.Parse( data ) )
+  {
+    DALI_LOG_WARNING( "JSON Parse Error:'%s'\n", parser.GetErrorDescription().c_str() );
+    DALI_LOG_WARNING( "JSON Parse Line :'%d (%d)'\n",
+                      parser.GetErrorLineNumber(),
+                      parser.GetErrorColumn() );
+  }
+  else
+  {
+    root = parser.GetRoot();
+  }
+
+  if(root)
+  {
+    // Clear previously loaded style
+    mStyleInfoLut.clear();
+
+    // Parse style
+    if( const TreeNode* node = root->GetChild("style") )
+    {
+      Toolkit::TreeNode::ConstIterator iter = node->CBegin();
+      Toolkit::TreeNode::ConstIterator end = node->CEnd();
+      for( ; iter != end; ++iter )
+      {
+        const char* key = (*iter).first;
+        FeedbackStyleInfo themeInfo;
+        themeInfo.mTypeName = key;
+
+        if( const TreeNode* signals = (*iter).second.GetChild("signals") )
+        {
+          TreeNode::ConstIterator signalIter = signals->CBegin();
+          TreeNode::ConstIterator signalEnd = signals->CEnd();
+          for( ; signalIter != signalEnd; ++signalIter )
+          {
+            SignalFeedbackInfo signalFeedbackInfo;
+
+            const TreeNode* type = (*signalIter).second.GetChild("type");
+            DALI_ASSERT_ALWAYS(type && TreeNode::STRING == type->GetType() && "Signal must have a type");
+            signalFeedbackInfo.mSignalName = type->GetString();
+
+            GetIfString( (*signalIter).second, "haptic-feedback-pattern",
+                         signalFeedbackInfo.mHasHapticFeedbackInfo,
+                         signalFeedbackInfo.mHapticFeedbackPattern );
+
+            GetIfString( (*signalIter).second, "haptic-feedback-file",
+                         signalFeedbackInfo.mHasHapticFeedbackInfo,
+                         signalFeedbackInfo.mHapticFeedbackFile );
+
+            GetIfString( (*signalIter).second, "sound-feedback-pattern",
+                         signalFeedbackInfo.mHasSoundFeedbackInfo,
+                         signalFeedbackInfo.mSoundFeedbackPattern );
+
+            GetIfString( (*signalIter).second, "haptic-feedback-file",
+                         signalFeedbackInfo.mHasSoundFeedbackInfo,
+                         signalFeedbackInfo.mSoundFeedbackFile );
+
+            if( signalFeedbackInfo.mHasHapticFeedbackInfo || signalFeedbackInfo.mHasSoundFeedbackInfo )
+            {
+              AddSignalInfo( themeInfo, signalFeedbackInfo );
+            }
+          }
+        }
+
+        mStyleInfoLut[key] = themeInfo;
+
+      } // for styles
+    } // if(style)
+  } // if(root)
+
+} // LoadFromString()
+
+void FeedbackStyle::AddSignalInfo( FeedbackStyleInfo& styleInfo, SignalFeedbackInfo signalInfo )
+{
+  bool updated = false;
+  std::vector<SignalFeedbackInfo>::iterator iter;
+
+  // If info exists for the signal then update it, else add new
+  for( iter = styleInfo.mSignalFeedbackInfoList.begin(); iter != styleInfo.mSignalFeedbackInfoList.end(); ++iter )
+  {
+    if( (*iter).mSignalName == signalInfo.mSignalName )
+    {
+      (*iter).mHasHapticFeedbackInfo = signalInfo.mHasHapticFeedbackInfo;
+      (*iter).mHapticFeedbackPattern = signalInfo.mHapticFeedbackPattern;
+      (*iter).mHapticFeedbackFile    = signalInfo.mHapticFeedbackFile;
+      (*iter).mHasSoundFeedbackInfo  = signalInfo.mHasSoundFeedbackInfo;
+      (*iter).mSoundFeedbackPattern  = signalInfo.mSoundFeedbackPattern;
+      (*iter).mSoundFeedbackFile     = signalInfo.mSoundFeedbackFile;
+
+      updated = true;
+      break;
+    }
+  }
+
+  if( !updated )
+  {
+    styleInfo.mSignalFeedbackInfoList.push_back( signalInfo );
+  }
+}
+
+void FeedbackStyle::PlayFeedback(const string& type, const string& signalName)
+{
+  const FeedbackStyleInfo styleInfo = GetStyleInfo(type);
+  SignalFeedbackInfoConstIter iter;
+
+  for(iter = styleInfo.mSignalFeedbackInfoList.begin(); iter != styleInfo.mSignalFeedbackInfoList.end(); ++iter)
+  {
+    const SignalFeedbackInfo& info = *iter;
+
+    if(info.mSignalName == signalName)
+    {
+      if(info.mHasHapticFeedbackInfo)
+      {
+        if(!info.mHapticFeedbackPattern.empty())
+        {
+          DALI_LOG_INFO( gLogFilter, Debug::Verbose, "FeedbackStyle::PlayFeedback Playing Haptic effect: Object type: %s, Signal type: %s, pattern type: %s\n",
+              type.c_str(), signalName.c_str(), info.mHapticFeedbackPattern.c_str());
+
+          mFeedback.PlayFeedbackPattern( FEEDBACK_TYPE_VIBRATION, GetFeedbackPattern(info.mHapticFeedbackPattern) );
+        }
+        else if(!info.mHapticFeedbackFile.empty())
+        {
+          mFeedback.PlayFile( info.mHapticFeedbackFile );
+        }
+      }
+
+      if(info.mHasSoundFeedbackInfo)
+      {
+        if(!info.mSoundFeedbackPattern.empty())
+        {
+          DALI_LOG_INFO( gLogFilter, Debug::Verbose, "FeedbackStyle::PlayFeedback Playing Sound effect: Object type: %s, Signal type: %s, pattern type: %s\n",
+              type.c_str(), signalName.c_str(), info.mHapticFeedbackPattern.c_str());
+
+          mFeedback.PlayFeedbackPattern( FEEDBACK_TYPE_SOUND, GetFeedbackPattern(info.mSoundFeedbackPattern) );
+        }
+        else if(!info.mSoundFeedbackFile.empty())
+        {
+          mFeedback.PlaySound( info.mSoundFeedbackFile );
+        }
+      }
+
+      break;
+    }
+  }
+}
+
+FeedbackPattern FeedbackStyle::GetFeedbackPattern( const string &pattern )
+{
+  if( 0 == mFeedbackPatternLut.size() )
+  {
+    mFeedbackPatternLut["FEEDBACK_PATTERN_NONE"]                = Dali::FEEDBACK_PATTERN_NONE;
+    mFeedbackPatternLut["FEEDBACK_PATTERN_TAP"]                 = Dali::FEEDBACK_PATTERN_TAP;
+    mFeedbackPatternLut["FEEDBACK_PATTERN_SIP"]                 = Dali::FEEDBACK_PATTERN_SIP;
+    mFeedbackPatternLut["FEEDBACK_PATTERN_SIP_BACKSPACE"]       = Dali::FEEDBACK_PATTERN_SIP_BACKSPACE;
+    mFeedbackPatternLut["FEEDBACK_PATTERN_MAX_CHARACTER"]       = Dali::FEEDBACK_PATTERN_MAX_CHARACTER;
+    mFeedbackPatternLut["FEEDBACK_PATTERN_KEY0"]                = Dali::FEEDBACK_PATTERN_KEY0;
+    mFeedbackPatternLut["FEEDBACK_PATTERN_KEY1"]                = Dali::FEEDBACK_PATTERN_KEY1;
+    mFeedbackPatternLut["FEEDBACK_PATTERN_KEY2"]                = Dali::FEEDBACK_PATTERN_KEY2;
+    mFeedbackPatternLut["FEEDBACK_PATTERN_KEY3"]                = Dali::FEEDBACK_PATTERN_KEY3;
+    mFeedbackPatternLut["FEEDBACK_PATTERN_KEY4"]                = Dali::FEEDBACK_PATTERN_KEY4;
+    mFeedbackPatternLut["FEEDBACK_PATTERN_KEY5"]                = Dali::FEEDBACK_PATTERN_KEY5;
+    mFeedbackPatternLut["FEEDBACK_PATTERN_KEY6"]                = Dali::FEEDBACK_PATTERN_KEY6;
+    mFeedbackPatternLut["FEEDBACK_PATTERN_KEY7"]                = Dali::FEEDBACK_PATTERN_KEY7;
+    mFeedbackPatternLut["FEEDBACK_PATTERN_KEY8"]                = Dali::FEEDBACK_PATTERN_KEY8;
+    mFeedbackPatternLut["FEEDBACK_PATTERN_KEY9"]                = Dali::FEEDBACK_PATTERN_KEY9;
+    mFeedbackPatternLut["FEEDBACK_PATTERN_KEY_STAR"]            = Dali::FEEDBACK_PATTERN_KEY_STAR;
+    mFeedbackPatternLut["FEEDBACK_PATTERN_KEY_SHARP"]           = Dali::FEEDBACK_PATTERN_KEY_SHARP;
+    mFeedbackPatternLut["FEEDBACK_PATTERN_HOLD"]                = Dali::FEEDBACK_PATTERN_HOLD;
+    mFeedbackPatternLut["FEEDBACK_PATTERN_MULTI_TAP"]           = Dali::FEEDBACK_PATTERN_MULTI_TAP;
+    mFeedbackPatternLut["FEEDBACK_PATTERN_HW_TAP"]              = Dali::FEEDBACK_PATTERN_HW_TAP;
+    mFeedbackPatternLut["FEEDBACK_PATTERN_HW_HOLD"]             = Dali::FEEDBACK_PATTERN_HW_HOLD;
+    mFeedbackPatternLut["FEEDBACK_PATTERN_MESSAGE"]             = Dali::FEEDBACK_PATTERN_MESSAGE;
+    mFeedbackPatternLut["FEEDBACK_PATTERN_MESSAGE_ON_CALL"]     = Dali::FEEDBACK_PATTERN_MESSAGE_ON_CALL;
+    mFeedbackPatternLut["FEEDBACK_PATTERN_EMAIL"]               = Dali::FEEDBACK_PATTERN_EMAIL;
+    mFeedbackPatternLut["FEEDBACK_PATTERN_EMAIL_ON_CALL"]       = Dali::FEEDBACK_PATTERN_EMAIL_ON_CALL;
+    mFeedbackPatternLut["FEEDBACK_PATTERN_WAKEUP"]              = Dali::FEEDBACK_PATTERN_WAKEUP;
+    mFeedbackPatternLut["FEEDBACK_PATTERN_WAKEUP_ON_CALL"]      = Dali::FEEDBACK_PATTERN_WAKEUP_ON_CALL;
+    mFeedbackPatternLut["FEEDBACK_PATTERN_SCHEDULE"]            = Dali::FEEDBACK_PATTERN_SCHEDULE;
+    mFeedbackPatternLut["FEEDBACK_PATTERN_SCHEDULE_ON_CALL"]    = Dali::FEEDBACK_PATTERN_SCHEDULE_ON_CALL;
+    mFeedbackPatternLut["FEEDBACK_PATTERN_TIMER"]               = Dali::FEEDBACK_PATTERN_TIMER;
+    mFeedbackPatternLut["FEEDBACK_PATTERN_TIMER_ON_CALL"]       = Dali::FEEDBACK_PATTERN_TIMER_ON_CALL;
+    mFeedbackPatternLut["FEEDBACK_PATTERN_GENERAL"]             = Dali::FEEDBACK_PATTERN_GENERAL;
+    mFeedbackPatternLut["FEEDBACK_PATTERN_GENERAL_ON_CALL"]     = Dali::FEEDBACK_PATTERN_GENERAL_ON_CALL;
+    mFeedbackPatternLut["FEEDBACK_PATTERN_POWER_ON"]            = Dali::FEEDBACK_PATTERN_POWER_ON;
+    mFeedbackPatternLut["FEEDBACK_PATTERN_POWER_OFF"]           = Dali::FEEDBACK_PATTERN_POWER_OFF;
+    mFeedbackPatternLut["FEEDBACK_PATTERN_CHARGERCONN"]         = Dali::FEEDBACK_PATTERN_CHARGERCONN;
+    mFeedbackPatternLut["FEEDBACK_PATTERN_CHARGERCONN_ON_CALL"] = Dali::FEEDBACK_PATTERN_CHARGERCONN_ON_CALL;
+    mFeedbackPatternLut["FEEDBACK_PATTERN_FULLCHARGED"]         = Dali::FEEDBACK_PATTERN_FULLCHARGED;
+    mFeedbackPatternLut["FEEDBACK_PATTERN_FULLCHARGED_ON_CALL"] = Dali::FEEDBACK_PATTERN_FULLCHARGED_ON_CALL;
+    mFeedbackPatternLut["FEEDBACK_PATTERN_LOWBATT"]             = Dali::FEEDBACK_PATTERN_LOWBATT;
+    mFeedbackPatternLut["FEEDBACK_PATTERN_LOWBATT_ON_CALL"]     = Dali::FEEDBACK_PATTERN_LOWBATT_ON_CALL;
+    mFeedbackPatternLut["FEEDBACK_PATTERN_LOCK"]                = Dali::FEEDBACK_PATTERN_LOCK;
+    mFeedbackPatternLut["FEEDBACK_PATTERN_UNLOCK"]              = Dali::FEEDBACK_PATTERN_UNLOCK;
+    mFeedbackPatternLut["FEEDBACK_PATTERN_CALLCONNECT"]         = Dali::FEEDBACK_PATTERN_CALLCONNECT;
+    mFeedbackPatternLut["FEEDBACK_PATTERN_DISCALLCONNECT"]      = Dali::FEEDBACK_PATTERN_DISCALLCONNECT;
+    mFeedbackPatternLut["FEEDBACK_PATTERN_MINUTEMINDER"]        = Dali::FEEDBACK_PATTERN_MINUTEMINDER;
+    mFeedbackPatternLut["FEEDBACK_PATTERN_VIBRATION"]           = Dali::FEEDBACK_PATTERN_VIBRATION;
+    mFeedbackPatternLut["FEEDBACK_PATTERN_SHUTTER"]             = Dali::FEEDBACK_PATTERN_SHUTTER;
+    mFeedbackPatternLut["FEEDBACK_PATTERN_LIST_REORDER"]        = Dali::FEEDBACK_PATTERN_LIST_REORDER;
+    mFeedbackPatternLut["FEEDBACK_PATTERN_SLIDER_SWEEP"]        = Dali::FEEDBACK_PATTERN_SLIDER_SWEEP;
+  }
+
+  std::map<const string, FeedbackPattern>::const_iterator iter( mFeedbackPatternLut.find( pattern ) );
+
+  if( iter != mFeedbackPatternLut.end() )
+  {
+    return iter->second;
+  }
+  else
+  {
+    DALI_LOG_ERROR( "Unknown feedback pattern type: %s, So Defaulting to FEEDBACK_PATTERN_NONE!\n" );
+    return Dali::FEEDBACK_PATTERN_NONE;
+  }
+}
+
+} // namespace Toolkit
+
+} // namespace Internal
+
+} // namespace Dali
diff --git a/dali-toolkit/internal/feedback/feedback-style.h b/dali-toolkit/internal/feedback/feedback-style.h
new file mode 100644 (file)
index 0000000..0f8d270
--- /dev/null
@@ -0,0 +1,162 @@
+#ifndef __DALI_INTERNAL_FEEDBACK_STYLE_H__
+#define __DALI_INTERNAL_FEEDBACK_STYLE_H__
+
+/*
+ * Copyright (c) 2014 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.
+ *
+ */
+
+// EXTERNAL INCLUDES
+#include <map>
+#include <dali/public-api/object/base-handle.h>
+#include <dali/devel-api/adaptor-framework/feedback-player.h>
+#include <dali/public-api/signals/connection-tracker.h>
+#include <dali/public-api/adaptor-framework/style-change.h>
+#include <dali/public-api/signals/slot-delegate.h>
+
+// INTERNAL INCLUDES
+#include <dali-toolkit/internal/feedback/feedback-ids.h>
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+namespace Internal
+{
+
+struct FeedbackStyleInfo;
+struct SignalFeedbackInfo;
+
+/**
+ * Plays feedback effects for Dali-Toolkit UI Controls.
+ *
+ * This functionality relies on an adaptor plugin.
+ * (And will have no effect if this is not loaded)
+ *
+ */
+class FeedbackStyle : public ConnectionTracker
+{
+public:
+
+  /**
+   * Constructor.
+   */
+  FeedbackStyle();
+
+  /**
+   * The destructor
+   */
+  ~FeedbackStyle();
+
+  /**
+   * Called to start playing feedback effects.
+   */
+  void Start();
+
+  /**
+   * Called to stop playing feedback effects.
+   */
+  void Stop();
+
+  /**
+   * Callback function to play a feedback effect when a signal is emitted for an object
+   * Plays feedback effect.
+   * @param [in] type The Object type
+   * @param [in] signalName The name of the signal
+   */
+  void PlayFeedback(const std::string& type, const std::string& signalName);
+
+  /**
+   * Connects feedback to signals for the newly created object
+   * @param [in] object Handle to the newly created object
+   */
+  void ObjectCreated( BaseHandle object );
+
+  /**
+   * Style changed so reload the theme file
+   * @param [in] userDefinedThemePath Theme filename path
+   * @param [in] styleChange The type of style change
+   */
+  void StyleChanged(const std::string& userDefinedThemePath, StyleChange::Type styleChange);
+
+private:
+
+  /**
+   * Helper to retrieve styleInfo from mStyleInfoLut
+   * @param type A string described a type of object
+   * @return The style information for the given object
+   */
+  const FeedbackStyleInfo& GetStyleInfo( const std::string& type) const;
+
+  /**
+   * Callback function for Dali::Toolkit::PushButton::SignalPressed signal
+   * Plays feedback effect.
+   * @param [in] effect The feedback effect to play
+   */
+  bool LoadTheme(const std::string& data);
+
+  /**
+   * Loads a string representation the theme.
+   * @param [in] data A string represenation of the theme.
+   * @param [in] format The string representation format ie JSON.
+   */
+  void LoadFromString( const std::string& data );
+
+  /**
+   * Helper to store signal information.
+   * @param [in] styleInfo The information will be stored here.
+   * @param [in] signalInfo The information to add.
+   */
+  void AddSignalInfo( FeedbackStyleInfo& styleInfo, SignalFeedbackInfo signalInfo );
+
+  /**
+   * Map a pattern string to feedback pattern ID.
+   * @param [in] pattern The pattern string.
+   * @return A feedback pattern ID.
+   */
+  FeedbackPattern GetFeedbackPattern( const std::string& pattern );
+
+  /**
+   * Plays a feedback effect
+   * @param [in] type The feedback type haptic or sound
+   * @param [in] effect The feedback effect to play
+   */
+  void PlayEffect(FeedbackType type, FeedbackPattern effect);
+
+  /**
+   * Plays a haptic or sound effect file
+   * @param [in] type The feedback type haptic or sound
+   * @param [in] file The path to the file containing the effect
+   */
+  void PlayFile(FeedbackType type, const std::string& file);
+
+private:
+  Dali::FeedbackPlayer mFeedback;
+
+  std::map<const std::string, FeedbackPattern>   mFeedbackPatternLut; ///< Used to convert feedback pattern strings into enumerated values
+  std::map<const std::string, FeedbackStyleInfo> mStyleInfoLut;       ///< Converts key strings into style information
+
+  SlotDelegate< FeedbackStyle > mConnections; ///< Maintains the connections to the Object registry.
+};
+
+} // namespace Toolkit
+
+} // namespace Internal
+
+} // namespace Dali
+
+#endif // __DALI_INTERNAL_FEEDBACK_STYLE_H__
index 807c3a2..0b8b570 100644 (file)
@@ -51,6 +51,9 @@ toolkit_src_files = \
    $(toolkit_src_dir)/controls/text-controls/text-selection-toolbar-impl.cpp \
    $(toolkit_src_dir)/controls/tool-bar/tool-bar-impl.cpp \
    $(toolkit_src_dir)/accessibility-manager/accessibility-manager-impl.cpp \
+   \
+   $(toolkit_src_dir)/feedback/feedback-style.cpp \
+   \
    $(toolkit_src_dir)/focus-manager/keyboard-focus-manager-impl.cpp \
    $(toolkit_src_dir)/focus-manager/keyinput-focus-manager-impl.cpp \
    $(toolkit_src_dir)/filters/blur-two-pass-filter.cpp \
index e0e1d4c..c245c15 100644 (file)
@@ -27,6 +27,7 @@
 #include <dali-toolkit/public-api/controls/control.h>
 #include <dali-toolkit/public-api/controls/control-impl.h>
 #include <dali-toolkit/devel-api/styling/style-manager.h>
+#include <dali-toolkit/internal/feedback/feedback-style.h>
 
 namespace
 {
@@ -99,7 +100,8 @@ Toolkit::StyleManager StyleManager::Get()
 StyleManager::StyleManager()
 : mOrientationDegrees( 0 ),  // Portrait
   mDefaultFontSize( -1 ),
-  mThemeFile( DEFAULT_THEME )
+  mThemeFile( DEFAULT_THEME ),
+  mFeedbackStyle( NULL )
 {
   // Add theme builder constants
   mThemeBuilderConstants[ PACKAGE_PATH_KEY ] = DEFAULT_PACKAGE_PATH;
@@ -111,10 +113,15 @@ StyleManager::StyleManager()
 
     mDefaultFontSize = mStyleMonitor.GetDefaultFontSize();
   }
+
+  // Sound & haptic style
+  mFeedbackStyle = new FeedbackStyle();
+
 }
 
 StyleManager::~StyleManager()
 {
+  delete mFeedbackStyle;
 }
 
 void StyleManager::SetOrientationValue( int orientation )
@@ -245,6 +252,7 @@ void StyleManager::BuildQualifiedStyleName( const std::string& styleName, const
 void StyleManager::ApplyStyle( Toolkit::Builder builder, Toolkit::Control control )
 {
   std::string styleName = control.GetStyleName();
+
   if( styleName.empty() )
   {
     // Convert control name to lower case
@@ -293,6 +301,19 @@ void StyleManager::ApplyThemeStyle( Toolkit::Control control )
   }
 }
 
+void StyleManager::ApplyThemeStyleAtInit( Toolkit::Control control )
+{
+  if( mThemeBuilder )
+  {
+    ApplyStyle( mThemeBuilder, control );
+  }
+
+  if(mFeedbackStyle)
+  {
+    mFeedbackStyle->ObjectCreated( control );
+  }
+}
+
 void StyleManager::ApplyStyle( Toolkit::Control control, const std::string& jsonFileName, const std::string& styleName )
 {
   bool builderReady = false;
@@ -361,8 +382,14 @@ void StyleManager::RequestDefaultTheme()
 void StyleManager::SetTheme()
 {
   mThemeBuilder = CreateBuilder( mThemeBuilderConstants );
-  if ( LoadJSON( mThemeBuilder, mThemeFile ) )
+
+  if( LoadJSON( mThemeBuilder, mThemeFile ) )
   {
+    if(mFeedbackStyle)
+    {
+      mFeedbackStyle->StyleChanged( mThemeFile, StyleChange::THEME_CHANGE );
+    }
+
     mStyleChangeSignal.Emit( Toolkit::StyleManager::Get(), StyleChange::THEME_CHANGE );
   }
   else
index c612f7d..86c6d4c 100644 (file)
@@ -38,6 +38,9 @@ namespace Toolkit
 
 namespace Internal
 {
+
+class FeedbackStyle;
+
 /**
  * @copydoc Toolkit::StyleManager
  */
@@ -111,6 +114,13 @@ public:
   void ApplyThemeStyle( Toolkit::Control control );
 
   /**
+   * @brief Apply the theme style to a control at initialization.
+   *
+   * @param[in] control The control to apply style.
+   */
+  void ApplyThemeStyleAtInit( Toolkit::Control control );
+
+  /**
    * @copydoc Toolkit::StyleManager::ApplyStyle
    */
   void ApplyStyle( Toolkit::Control control, const std::string& jsonFileName, const std::string& styleName );
@@ -251,6 +261,8 @@ private:
 
   BuilderMap mBuilderCache;           ///< Cache of builders keyed by JSON file name
 
+  Toolkit::Internal::FeedbackStyle* mFeedbackStyle; ///< Feedback style
+
   // Signals
   Toolkit::StyleManager::StyleChangeSignalType       mStyleChangeSignal;         ///< Emitted when the style( theme/font ) changes
 };
index 6434772..c0780c4 100644 (file)
@@ -875,7 +875,7 @@ void Control::Initialize()
       styleManager.StyleChangeSignal().Connect( this, &Control::OnStyleChange );
 
       // Apply the current style
-      GetImpl( styleManager ).ApplyThemeStyle( Toolkit::Control( GetOwner() ) );
+      GetImpl( styleManager ).ApplyThemeStyleAtInit( Toolkit::Control( GetOwner() ) );
     }
   }
 
diff --git a/dali-toolkit/styles/default-feedback-theme.json b/dali-toolkit/styles/default-feedback-theme.json
new file mode 100644 (file)
index 0000000..25b0c7d
--- /dev/null
@@ -0,0 +1,20 @@
+//******************************************************************************
+//
+// Default feedback theme for dali-toolkit
+//
+//******************************************************************************
+{
+  "style":
+  {
+    "PushButton":
+    {
+      "signals":
+      [
+        {
+          "type": "clicked",
+          "sound-feedback-pattern": "FEEDBACK_PATTERN_TAP"
+        }
+      ]
+    }
+  }
+}