Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix hold key presses in lists. #1170

Merged
merged 2 commits into from Aug 1, 2012
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
38 changes: 33 additions & 5 deletions xbmc/Application.cpp
Expand Up @@ -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.
Expand Down Expand Up @@ -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
{
Expand Down
22 changes: 16 additions & 6 deletions xbmc/guilib/GUIBaseContainer.cpp
Expand Up @@ -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)
Expand Down Expand Up @@ -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);
}
}
Expand Down
1 change: 1 addition & 0 deletions xbmc/guilib/GUIBaseContainer.h
Expand Up @@ -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;
};
Expand Down