From: Adeel Kazmi Date: Tue, 14 Jul 2015 16:05:22 +0000 (-0700) Subject: Merge "Removed feedback controller Boost dependency" into devel/master X-Git-Tag: dali_1.0.49~6 X-Git-Url: http://review.tizen.org/git/?p=platform%2Fcore%2Fuifw%2Fdali-toolkit.git;a=commitdiff_plain;h=4f1a814c47a80f11892a6a887cd98099a2eace09;hp=b65021c94cd148c37c246ba3a7833ddabb1571d2 Merge "Removed feedback controller Boost dependency" into devel/master --- diff --git a/dali-toolkit/devel-api/builder/json-parser.cpp b/dali-toolkit/devel-api/builder/json-parser.cpp index 5d3838e..5e8c0ae 100644 --- a/dali-toolkit/devel-api/builder/json-parser.cpp +++ b/dali-toolkit/devel-api/builder/json-parser.cpp @@ -59,7 +59,7 @@ JsonParser DownCast( BaseHandle handle ) return JsonParser( dynamic_cast(handle.GetObjectPtr()) ); } -int JsonParser::Parse(const std::string& source) +bool JsonParser::Parse(const std::string& source) { return GetImplementation(*this).Parse(source); } diff --git a/dali-toolkit/devel-api/builder/json-parser.h b/dali-toolkit/devel-api/builder/json-parser.h index b871948..05b8e80 100644 --- a/dali-toolkit/devel-api/builder/json-parser.h +++ b/dali-toolkit/devel-api/builder/json-parser.h @@ -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 diff --git a/dali-toolkit/internal/builder/json-parser-impl.cpp b/dali-toolkit/internal/builder/json-parser-impl.cpp index 2cff977..fdec738 100644 --- a/dali-toolkit/internal/builder/json-parser-impl.cpp +++ b/dali-toolkit/internal/builder/json-parser-impl.cpp @@ -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()) ); diff --git a/dali-toolkit/internal/builder/json-parser-impl.h b/dali-toolkit/internal/builder/json-parser-impl.h index 9936974..dbdbf45 100644 --- a/dali-toolkit/internal/builder/json-parser-impl.h +++ b/dali-toolkit/internal/builder/json-parser-impl.h @@ -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 index 0000000..cb7ffa3 --- /dev/null +++ b/dali-toolkit/internal/feedback/feedback-ids.h @@ -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 index 0000000..c1dca7e --- /dev/null +++ b/dali-toolkit/internal/feedback/feedback-style.cpp @@ -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 + +// EXTERNAL INCLUDES +#include +#include +#include +#include + +// INTERNAL INCLUDES +#include +#include + +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 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_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::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_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 index 0000000..0f8d270 --- /dev/null +++ b/dali-toolkit/internal/feedback/feedback-style.h @@ -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 +#include +#include +#include +#include +#include + +// INTERNAL INCLUDES +#include + +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 mFeedbackPatternLut; ///< Used to convert feedback pattern strings into enumerated values + std::map 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__ diff --git a/dali-toolkit/internal/file.list b/dali-toolkit/internal/file.list index 807c3a2..0b8b570 100644 --- a/dali-toolkit/internal/file.list +++ b/dali-toolkit/internal/file.list @@ -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 \ diff --git a/dali-toolkit/internal/styling/style-manager-impl.cpp b/dali-toolkit/internal/styling/style-manager-impl.cpp index e0e1d4c..c245c15 100644 --- a/dali-toolkit/internal/styling/style-manager-impl.cpp +++ b/dali-toolkit/internal/styling/style-manager-impl.cpp @@ -27,6 +27,7 @@ #include #include #include +#include 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 diff --git a/dali-toolkit/internal/styling/style-manager-impl.h b/dali-toolkit/internal/styling/style-manager-impl.h index c612f7d..86c6d4c 100644 --- a/dali-toolkit/internal/styling/style-manager-impl.h +++ b/dali-toolkit/internal/styling/style-manager-impl.h @@ -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 }; diff --git a/dali-toolkit/public-api/controls/control-impl.cpp b/dali-toolkit/public-api/controls/control-impl.cpp index 6434772..c0780c4 100644 --- a/dali-toolkit/public-api/controls/control-impl.cpp +++ b/dali-toolkit/public-api/controls/control-impl.cpp @@ -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 index 0000000..25b0c7d --- /dev/null +++ b/dali-toolkit/styles/default-feedback-theme.json @@ -0,0 +1,20 @@ +//****************************************************************************** +// +// Default feedback theme for dali-toolkit +// +//****************************************************************************** +{ + "style": + { + "PushButton": + { + "signals": + [ + { + "type": "clicked", + "sound-feedback-pattern": "FEEDBACK_PATTERN_TAP" + } + ] + } + } +}