diff --git a/xbmc/Application.cpp b/xbmc/Application.cpp index 5d79596eb1178..4bb699bf4a6cd 100644 --- a/xbmc/Application.cpp +++ b/xbmc/Application.cpp @@ -2478,10 +2478,23 @@ bool CApplication::OnKey(const CKey& key) if (!key.IsAnalogButton()) CLog::Log(LOGDEBUG, "%s: %s pressed, action is %s", __FUNCTION__, g_Keyboard.GetKeyName((int) key.GetButtonCode()).c_str(), action.GetName().c_str()); - // Play a sound based on the action - g_audioManager.PlayActionSound(action); + bool bResult = false; - return OnAction(action); + // play sound before the action unless the button is held, + // where we execute after the action as held actions aren't fired every time. + if(action.GetHoldTime()) + { + bResult = OnAction(action); + if(bResult) + g_audioManager.PlayActionSound(action); + } + else + { + g_audioManager.PlayActionSound(action); + bResult = OnAction(action); + } + + return bResult; } // OnAppCommand is called in response to a XBMC_APPCOMMAND event. @@ -3308,8 +3321,23 @@ bool CApplication::ProcessJoystickEvent(const std::string& joystickName, int wKe if (CButtonTranslator::GetInstance().TranslateJoystickString(iWin, joystickName.c_str(), wKeyID, isAxis ? JACTIVE_AXIS : JACTIVE_BUTTON, actionID, actionName, fullRange)) { CAction action(actionID, fAmount, 0.0f, actionName, holdTime); - g_audioManager.PlayActionSound(action); - return OnAction(action); + bool bResult = false; + + // play sound before the action unless the button is held, + // where we execute after the action as held actions aren't fired every time. + if(action.GetHoldTime()) + { + bResult = OnAction(action); + if(bResult) + g_audioManager.PlayActionSound(action); + } + else + { + g_audioManager.PlayActionSound(action); + bResult = OnAction(action); + } + + return bResult; } else { diff --git a/xbmc/guilib/GUIBaseContainer.cpp b/xbmc/guilib/GUIBaseContainer.cpp index fd13aa7b9092b..536e2712a8f92 100644 --- a/xbmc/guilib/GUIBaseContainer.cpp +++ b/xbmc/guilib/GUIBaseContainer.cpp @@ -59,6 +59,7 @@ CGUIBaseContainer::CGUIBaseContainer(int parentID, int controlID, float posX, fl m_layout = NULL; m_focusedLayout = NULL; m_cacheItems = preloadItems; + m_scrollItemsPerFrame = 0.0f; } CGUIBaseContainer::~CGUIBaseContainer(void) @@ -294,24 +295,33 @@ bool CGUIBaseContainer::OnAction(const CAction &action) case ACTION_NAV_BACK: { if (!HasFocus()) return false; + if (action.GetHoldTime() > HOLD_TIME_START && ((m_orientation == VERTICAL && (action.GetID() == ACTION_MOVE_UP || action.GetID() == ACTION_MOVE_DOWN)) || (m_orientation == HORIZONTAL && (action.GetID() == ACTION_MOVE_LEFT || action.GetID() == ACTION_MOVE_RIGHT)))) { // action is held down - repeat a number of times float speed = std::min(1.0f, (float)(action.GetHoldTime() - HOLD_TIME_START) / (HOLD_TIME_END - HOLD_TIME_START)); - unsigned int itemsPerFrame = 1; - if (m_lastHoldTime) // number of rows/10 items/second max speed - itemsPerFrame = std::max((unsigned int)1, (unsigned int)(speed * 0.0001f * GetRows() * (CTimeUtils::GetFrameTime() - m_lastHoldTime))); + unsigned int frameDuration = CTimeUtils::GetFrameTime() - m_lastHoldTime; + + //scrollrate is minimum 4 items/sec and max rows/10 items/sec + m_scrollItemsPerFrame += std::max(0.004f*(float)frameDuration, (float)(speed * 0.0001f * GetRows() * frameDuration)); m_lastHoldTime = CTimeUtils::GetFrameTime(); + + if(m_scrollItemsPerFrame < 1.0f)//not enough hold time accumulated for one step + return false; + if (action.GetID() == ACTION_MOVE_LEFT || action.GetID() == ACTION_MOVE_UP) - while (itemsPerFrame--) MoveUp(false); + while (m_scrollItemsPerFrame-- >= 1) MoveUp(false); else - while (itemsPerFrame--) MoveDown(false); + while (m_scrollItemsPerFrame-- >= 1) MoveDown(false); return true; } else { - m_lastHoldTime = 0; + //if HOLD_TIME_START is reached we need + //a sane initial value for calculating m_scrollItemsPerPage + m_lastHoldTime = CTimeUtils::GetFrameTime(); + m_scrollItemsPerFrame = 0.0f; return CGUIControl::OnAction(action); } } diff --git a/xbmc/guilib/GUIBaseContainer.h b/xbmc/guilib/GUIBaseContainer.h index 8c7925d15d8b6..ef6353ab433ac 100644 --- a/xbmc/guilib/GUIBaseContainer.h +++ b/xbmc/guilib/GUIBaseContainer.h @@ -208,6 +208,7 @@ class CGUIBaseContainer : public CGUIControl // letter match searching CStopWatch m_matchTimer; CStdString m_match; + float m_scrollItemsPerFrame; static const int letter_match_timeout = 1000; };