示例#1
0
void CGUIPanelContainer::Process(unsigned int currentTime, CDirtyRegionList &dirtyregions)
{
  ValidateOffset();

  if (m_bInvalidated)
    UpdateLayout();

  if (!m_layout || !m_focusedLayout) return;

  UpdateScrollOffset(currentTime);

  int offset = (int)(m_scroller.GetValue() / m_layout->Size(m_orientation));

  int cacheBefore, cacheAfter;
  GetCacheOffsets(cacheBefore, cacheAfter);

  // Free memory not used on screen
  if ((int)m_items.size() > m_itemsPerPage + cacheBefore + cacheAfter)
    FreeMemory(CorrectOffset(offset - cacheBefore, 0), CorrectOffset(offset + m_itemsPerPage + 1 + cacheAfter, 0));

  CPoint origin = CPoint(m_posX, m_posY) + m_renderOffset;
  float pos = (m_orientation == VERTICAL) ? origin.y : origin.x;
  float end = (m_orientation == VERTICAL) ? m_posY + m_height : m_posX + m_width;
  pos += (offset - cacheBefore) * m_layout->Size(m_orientation) - m_scroller.GetValue();
  end += cacheAfter * m_layout->Size(m_orientation);

  int current = (offset - cacheBefore) * m_itemsPerRow;
  int col = 0;
  while (pos < end && m_items.size())
  {
    if (current >= (int)m_items.size())
      break;
    if (current >= 0)
    {
      CGUIListItemPtr item = m_items[current];
      bool focused = (current == GetOffset() * m_itemsPerRow + GetCursor()) && m_bHasFocus;

      if (m_orientation == VERTICAL)
        ProcessItem(origin.x + col * m_layout->Size(HORIZONTAL), pos, item, focused, currentTime, dirtyregions);
      else
        ProcessItem(pos, origin.y + col * m_layout->Size(VERTICAL), item, focused, currentTime, dirtyregions);
    }
    // increment our position
    if (col < m_itemsPerRow - 1)
      col++;
    else
    {
      pos += m_layout->Size(m_orientation);
      col = 0;
    }
    current++;
  }

  // when we are scrolling up, offset will become lower (integer division, see offset calc)
  // to have same behaviour when scrolling down, we need to set page control to offset+1
  UpdatePageControl(offset + (m_scroller.IsScrollingDown() ? 1 : 0));

  CGUIControl::Process(currentTime, dirtyregions);
}
int CGUIFixedListContainer::GetCurrentPage() const
{
  int offset = CorrectOffset(GetOffset(), GetCursor());
  if (offset + m_itemsPerPage - GetCursor() >= (int)GetRows())  // last page
    return (GetRows() + m_itemsPerPage - 1) / m_itemsPerPage;
  return offset / m_itemsPerPage + 1;
}
int CGUIWrappingListContainer::GetCurrentPage() const
{
  int offset = CorrectOffset(m_offset, m_cursor);
  if (offset + m_itemsPerPage - m_cursor >= (int)GetRows())  // last page
    return (GetRows() + m_itemsPerPage - 1) / m_itemsPerPage;
  return offset / m_itemsPerPage + 1;
}
bool PipeManager::CheckTubes(std::shared_ptr<BirdObject> bird)
{
	if (m_pipes[0]->ShouldBeDeleted())
	{
		CorrectOffset();
		m_pipes.erase(m_pipes.begin() + 0);
		m_pipes.erase(m_pipes.begin() + 0);
		AddPipe(true);
		AddPipe(false);
		return false;
	}
	else if (!bird->GetIsDead() && !bird->GetIsInvulnerable() && (bird->CheckInteractWithTube(m_pipes[0]) || bird->CheckInteractWithTube(m_pipes[1])))
	{
		bird->SetIsDead(true);
		return false;
	}
	else if (!bird->GetIsDead() && !m_pipes[0]->IsScored())
	{
		if (bird->CheckScore(m_pipes[0]))
		{
			m_pipes[0]->SetIsScored(true);
			return true;
		}
	}
	return false;
}
示例#5
0
void CGUIBaseContainer::OnNextLetter()
{
  int offset = CorrectOffset(GetOffset(), GetCursor());
  for (unsigned int i = 0; i < m_letterOffsets.size(); i++)
  {
    if (m_letterOffsets[i].first > offset)
    {
      SelectItem(m_letterOffsets[i].first);
      return;
    }
  }
}
示例#6
0
void CGUIBaseContainer::OnPrevLetter()
{
  int offset = CorrectOffset(GetOffset(), GetCursor());
  if (!m_letterOffsets.size())
    return;
  for (int i = (int)m_letterOffsets.size() - 1; i >= 0; i--)
  {
    if (m_letterOffsets[i].first < offset)
    {
      SelectItem(m_letterOffsets[i].first);
      return;
    }
  }
}
示例#7
0
CGUIListItemPtr CGUIBaseContainer::GetListItem(int offset, unsigned int flag) const
{
  if (!m_items.size() || !m_layout)
    return CGUIListItemPtr();
  int item = GetSelectedItem() + offset;
  if (flag & INFOFLAG_LISTITEM_POSITION) // use offset from the first item displayed, taking into account scrolling
    item = CorrectOffset((int)(m_scroller.GetValue() / m_layout->Size(m_orientation)), offset);
  
  if (flag & INFOFLAG_LISTITEM_ABSOLUTE) // use offset from the first item
    item = CorrectOffset(0, offset);

  if (flag & INFOFLAG_LISTITEM_WRAP)
  {
    item %= ((int)m_items.size());
    if (item < 0) item += m_items.size();
    return m_items[item];
  }
  else
  {
    if (item >= 0 && item < (int)m_items.size())
      return m_items[item];
  }
  return CGUIListItemPtr();
}
示例#8
0
void CGUIBaseContainer::OnJumpSMS(int letter)
{
  static const char letterMap[8][6] = { "ABC2", "DEF3", "GHI4", "JKL5", "MNO6", "PQRS7", "TUV8", "WXYZ9" };

  // only 2..9 supported
  if (letter < 2 || letter > 9 || !m_letterOffsets.size())
    return;

  const std::string letters = letterMap[letter - 2];
  // find where we currently are
  int offset = CorrectOffset(GetOffset(), GetCursor());
  unsigned int currentLetter = 0;
  while (currentLetter + 1 < m_letterOffsets.size() && m_letterOffsets[currentLetter + 1].first <= offset)
    currentLetter++;

  // now switch to the next letter
  std::string current = m_letterOffsets[currentLetter].second;
  size_t startPos = (letters.find(current) + 1) % letters.size();
  // now jump to letters[startPos], or another one in the same range if possible
  size_t pos = startPos;
  while (true)
  {
    // check if we can jump to this letter
    for (size_t i = 0; i < m_letterOffsets.size(); i++)
    {
      if (m_letterOffsets[i].second == letters.substr(pos, 1))
      {
        SelectItem(m_letterOffsets[i].first);
        return;
      }
    }
    pos = (pos + 1) % letters.size();
    if (pos == startPos)
      return;
  }
}
示例#9
0
void CGUIBaseContainer::OnJumpLetter(char letter, bool skip /*=false*/)
{
  if (m_matchTimer.GetElapsedMilliseconds() < letter_match_timeout)
    m_match.push_back(letter);
  else
    m_match = StringUtils::Format("%c", letter);

  m_matchTimer.StartZero();

  // we can't jump through letters if we have none
  if (0 == m_letterOffsets.size())
    return;

  // find the current letter we're focused on
  unsigned int offset = CorrectOffset(GetOffset(), GetCursor());
  unsigned int i      = (offset + ((skip) ? 1 : 0)) % m_items.size();
  do
  {
    CGUIListItemPtr item = m_items[i];
    std::string label = item->GetLabel();
    if (CServiceBroker::GetSettings().GetBool(CSettings::SETTING_FILELISTS_IGNORETHEWHENSORTING))
      label = SortUtils::RemoveArticles(label);
    if (0 == strnicmp(label.c_str(), m_match.c_str(), m_match.size()))
    {
      SelectItem(i);
      return;
    }
    i = (i+1) % m_items.size();
  } while (i != offset);
  // no match found - repeat with a single letter
  if (m_match.size() > 1)
  {
    m_match.clear();
    OnJumpLetter(letter, true);
  }
}
示例#10
0
void CGUIBaseContainer::Process(unsigned int currentTime, CDirtyRegionList &dirtyregions)
{
  // update our auto-scrolling as necessary
  UpdateAutoScrolling(currentTime);

  ValidateOffset();

  if (m_bInvalidated)
    UpdateLayout();

  if (!m_layout || !m_focusedLayout) return;

  UpdateScrollOffset(currentTime);

  int offset = (int)floorf(m_scroller.GetValue() / m_layout->Size(m_orientation));

  int cacheBefore, cacheAfter;
  GetCacheOffsets(cacheBefore, cacheAfter);

  // Free memory not used on screen
  if ((int)m_items.size() > m_itemsPerPage + cacheBefore + cacheAfter)
    FreeMemory(CorrectOffset(offset - cacheBefore, 0), CorrectOffset(offset + m_itemsPerPage + 1 + cacheAfter, 0));

  CPoint origin = CPoint(m_posX, m_posY) + m_renderOffset;
  float pos = (m_orientation == VERTICAL) ? origin.y : origin.x;
  float end = (m_orientation == VERTICAL) ? m_posY + m_height : m_posX + m_width;

  // we offset our draw position to take into account scrolling and whether or not our focused
  // item is offscreen "above" the list.
  float drawOffset = (offset - cacheBefore) * m_layout->Size(m_orientation) - m_scroller.GetValue();
  if (GetOffset() + GetCursor() < offset)
    drawOffset += m_focusedLayout->Size(m_orientation) - m_layout->Size(m_orientation);
  pos += drawOffset;
  end += cacheAfter * m_layout->Size(m_orientation);

  int current = offset - cacheBefore;
  while (pos < end && m_items.size())
  {
    int itemNo = CorrectOffset(current, 0);
    if (itemNo >= (int)m_items.size())
      break;
    bool focused = (current == GetOffset() + GetCursor());
    if (itemNo >= 0)
    {
      CGUIListItemPtr item = m_items[itemNo];
      // render our item
      if (m_orientation == VERTICAL)
        ProcessItem(origin.x, pos, item, focused, currentTime, dirtyregions);
      else
        ProcessItem(pos, origin.y, item, focused, currentTime, dirtyregions);
    }
    // increment our position
    pos += focused ? m_focusedLayout->Size(m_orientation) : m_layout->Size(m_orientation);
    current++;
  }

  // when we are scrolling up, offset will become lower (integer division, see offset calc)
  // to have same behaviour when scrolling down, we need to set page control to offset+1
  UpdatePageControl(offset + (m_scroller.IsScrollingDown() ? 1 : 0));

  m_lastRenderTime = currentTime;

  CGUIControl::Process(currentTime, dirtyregions);
}
示例#11
0
int CGUIBaseContainer::GetSelectedItem() const
{
  return CorrectOffset(GetOffset(), GetCursor());
}
示例#12
0
void CGUIBaseContainer::Render()
{
  if (!m_layout || !m_focusedLayout) return;

  int offset = (int)floorf(m_scroller.GetValue() / m_layout->Size(m_orientation));

  int cacheBefore, cacheAfter;
  GetCacheOffsets(cacheBefore, cacheAfter);

  if (g_graphicsContext.SetClipRegion(m_posX, m_posY, m_width, m_height))
  {
    CPoint origin = CPoint(m_posX, m_posY) + m_renderOffset;
    float pos = (m_orientation == VERTICAL) ? origin.y : origin.x;
    float end = (m_orientation == VERTICAL) ? m_posY + m_height : m_posX + m_width;

    // we offset our draw position to take into account scrolling and whether or not our focused
    // item is offscreen "above" the list.
    float drawOffset = (offset - cacheBefore) * m_layout->Size(m_orientation) - m_scroller.GetValue();
    if (GetOffset() + GetCursor() < offset)
      drawOffset += m_focusedLayout->Size(m_orientation) - m_layout->Size(m_orientation);
    pos += drawOffset;
    end += cacheAfter * m_layout->Size(m_orientation);

    float focusedPos = 0;
    CGUIListItemPtr focusedItem;
    int current = offset - cacheBefore;
    while (pos < end && m_items.size())
    {
      int itemNo = CorrectOffset(current, 0);
      if (itemNo >= (int)m_items.size())
        break;
      bool focused = (current == GetOffset() + GetCursor());
      if (itemNo >= 0)
      {
        CGUIListItemPtr item = m_items[itemNo];
        // render our item
        if (focused)
        {
          focusedPos = pos;
          focusedItem = item;
        }
        else
        {
          if (m_orientation == VERTICAL)
            RenderItem(origin.x, pos, item.get(), false);
          else
            RenderItem(pos, origin.y, item.get(), false);
        }
      }
      // increment our position
      pos += focused ? m_focusedLayout->Size(m_orientation) : m_layout->Size(m_orientation);
      current++;
    }
    // render focused item last so it can overlap other items
    if (focusedItem)
    {
      if (m_orientation == VERTICAL)
        RenderItem(origin.x, focusedPos, focusedItem.get(), true);
      else
        RenderItem(focusedPos, origin.y, focusedItem.get(), true);
    }

    g_graphicsContext.RestoreClipRegion();
  }

  CGUIControl::Render();
}
void CGUIWrappingListContainer::Render()
{
  if (!IsVisible()) return;

  ValidateOffset();

  if (m_bInvalidated)
    UpdateLayout();

  if (!m_layout || !m_focusedLayout) return;

  UpdateScrollOffset();

  int offset = (int)floorf(m_scrollOffset / m_layout->Size(m_orientation));
  // Free memory not used on scre  if (m_scrollSpeed)
  if ((int)m_items.size() > m_itemsPerPage)
    FreeMemory(CorrectOffset(offset, 0), CorrectOffset(offset, m_itemsPerPage + 1));

  g_graphicsContext.SetClipRegion(m_posX, m_posY, m_width, m_height);
  float posX = m_posX;
  float posY = m_posY;
  if (m_orientation == VERTICAL)
    posY += (offset * m_layout->Size(m_orientation) - m_scrollOffset);
  else
    posX += (offset * m_layout->Size(m_orientation) - m_scrollOffset);;

  float focusedPosX = 0;
  float focusedPosY = 0;
  CGUIListItemPtr focusedItem;
  int current = offset;
  while (posX < m_posX + m_width && posY < m_posY + m_height && m_items.size())
  {
    CGUIListItemPtr item = m_items[CorrectOffset(current, 0)];
    bool focused = (current == m_offset + m_cursor) && m_bHasFocus;
    // render our item
    if (focused)
    {
      focusedPosX = posX;
      focusedPosY = posY;
      focusedItem = item;
    }
    else
      RenderItem(posX, posY, item.get(), focused);

    // increment our position
    if (m_orientation == VERTICAL)
      posY += focused ? m_focusedLayout->Size(m_orientation) : m_layout->Size(m_orientation);
    else
      posX += focused ? m_focusedLayout->Size(m_orientation) : m_layout->Size(m_orientation);

    current++;
  }
  // render focused item last so it can overlap other items
  if (focusedItem)
    RenderItem(focusedPosX, focusedPosY, focusedItem.get(), true);

  g_graphicsContext.RestoreClipRegion();

  if (m_pageControl)
  { // tell our pagecontrol (scrollbar or whatever) to update
    CGUIMessage msg(GUI_MSG_ITEM_SELECT, GetID(), m_pageControl, CorrectOffset(offset, 0));
    SendWindowMessage(msg);
  }
  CGUIBaseContainer::Render();
}
示例#14
0
void CGUIFixedListContainer::Render()
{
  ValidateOffset();

  if (m_bInvalidated)
    UpdateLayout();

  if (!m_focusedLayout || !m_layout) return;

  UpdateScrollOffset();

  int offset = (int)(m_scrollOffset / m_layout->Size(m_orientation));
  // Free memory not used on screen at the moment, do this first so there's more memory for the new items.
  FreeMemory(CorrectOffset(offset, 0), CorrectOffset(offset, m_itemsPerPage + 1));

  g_graphicsContext.SetClipRegion(m_posX, m_posY, m_width, m_height);
  float posX = m_posX;
  float posY = m_posY;
  if (m_orientation == VERTICAL)
    posY += (offset * m_layout->Size(m_orientation) - m_scrollOffset);
  else
    posX += (offset * m_layout->Size(m_orientation) - m_scrollOffset);;

  float focusedPosX = 0;
  float focusedPosY = 0;
  CGUIListItemPtr focusedItem;
  int current = offset;
  while (posX < m_posX + m_width && posY < m_posY + m_height && m_items.size())
  {
    if (current >= (int)m_items.size())
      break;
    bool focused = (current == m_offset + m_cursor);
    if (current >= 0)
    {
      CGUIListItemPtr item = m_items[current];
      // render our item
      if (focused)
      {
        focusedPosX = posX;
        focusedPosY = posY;
        focusedItem = item;
      }
      else
        RenderItem(posX, posY, item.get(), focused);
    }

    // increment our position
    if (m_orientation == VERTICAL)
      posY += focused ? m_focusedLayout->Size(m_orientation) : m_layout->Size(m_orientation);
    else
      posX += focused ? m_focusedLayout->Size(m_orientation) : m_layout->Size(m_orientation);

    current++;
  }
  // and render the focused item last (for overlapping purposes)
  if (focusedItem)
    RenderItem(focusedPosX, focusedPosY, focusedItem.get(), true);

  g_graphicsContext.RestoreClipRegion();

  if (m_pageControl)
  { // tell our pagecontrol (scrollbar or whatever) to update
    CGUIMessage msg(GUI_MSG_ITEM_SELECT, GetID(), m_pageControl, offset);
    SendWindowMessage(msg);
  }
  CGUIBaseContainer::Render();
}
void CGUIFixedListContainer::ScrollToOffset(int offset)
{
  CLog::Log(LOGDEBUG,"CGUIFixedListContainer::ScrollToOffset - ENTER. [m_cursor=%d][offset=%d][m_offset=%d] (scroll)", m_cursor, offset, m_offset);

  bool wrapAround = IsWrapAround();
  if ( wrapAround || m_bPinnedPosition)
  {
    CGUIBaseContainer::ScrollToOffset(offset);
    return; 
  }

  int nCurrOffset = CorrectOffset(m_offset, m_cursor); 
  int nTargetOffset = CorrectOffset(offset, m_cursor); 
  
  int last_section = m_items.size() - (m_itemsPerPage / 2);
  int first_section = (m_itemsPerPage / 2);

  CLog::Log(LOGDEBUG, "CGUIFixedListContainer::ScrollToOffset - [m_cursor=%d][offset=%d][m_offset=%d][nCurrOffset=%d][nTargetOffset=%d][numOfItems=%zu][m_itemsPerPage=%d] (scroll)",
      m_cursor, offset, m_offset, nCurrOffset, nTargetOffset, m_items.size(), m_itemsPerPage);
  
  // Case 1:
  // Someone initialized the window and immediately scrolled to a cached offset, and we have more than one page of content
  // We detect this case by seeing that we are not stepping by an increment of one
  // In this situation we recalculate the cursor and the list offset from scratch and call base seek, but only if we have more than a page
  // if we have less than a page we never scroll

  if( nTargetOffset != nCurrOffset+1 && nTargetOffset != nCurrOffset-1 && nTargetOffset != nCurrOffset)
  {
    // BUGBUG: we don't handle separators properly here, but normally SelectItem will handle that for us (since that is the likely call path here)
    
    // See if any scroll is required. If we have a page or less then no
    if( m_items.size() > (size_t) m_itemsPerPage )
    {
      // see if we are in the first block
      if( nTargetOffset <= first_section )
      {
        m_cursor = nTargetOffset;
        nTargetOffset = 0;
      }
      // or in the last block
      else if( nTargetOffset >= last_section )
      {
        int off = m_items.size() - m_itemsPerPage;
        m_cursor = nTargetOffset - off;
        nTargetOffset = off;
      }
      // otherwise, just center us
      else
      {
        m_cursor = m_itemsPerPage / 2;
        nTargetOffset -= m_cursor;
      }

      //avoid scrolling and starting the scrolltimer, used when we're setting selection on specific item
      m_wasReset = true;
      CGUIBaseContainer::ScrollToOffset(nTargetOffset);
    }
    else
    {
      CGUIBaseContainer::ScrollToOffset(0);
      m_cursor = nTargetOffset;
    }
  }
  else
  // Case 2:
  // We are stepping backwards in the list. I.e. moving up or left depending on orientation (nCurrOffset > nTargetOffset)
  // We are moving in the fixed pane of the content
  // If we hit a separator then we recurse to ensure we shift appropriately.
  if (nCurrOffset >= nTargetOffset && ((size_t) nCurrOffset >= m_items.size() - (m_itemsPerPage / 2) || nCurrOffset == 0 ))
  {
    // Move the cursor by the requested delta
    m_cursor -= (nCurrOffset - nTargetOffset);
    
    // Handle the case where we land on a separator by moving us along one extra space
    if (m_items.size() > (size_t) (m_offset +m_cursor) && m_items[m_offset +m_cursor]->GetPropertyBOOL("isseparator"))
    {
      if (m_offset +m_cursor == 0)
      {
        MoveDown(false);
      }
      else
      {
        MoveUp(false);
      }
    }
  }
  // Case 3:
  // We are stepping forwards in the list. I.e. moving down or right depending on the orientation (nTargetOffset > nCurrOffset)
  // We are moving in the fixed pane of the content
  // If we hit a separator then we recurse to ensure we shift appropriately.
  else if (nCurrOffset <= nTargetOffset && (nCurrOffset < m_itemsPerPage / 2 || (m_items.size() - m_itemsPerPage) == (size_t) m_offset) )
  {
    // Move the cursor by the requested delta
    m_cursor += (nTargetOffset - nCurrOffset);
    
    // Handle the case where we land ona  separator by moving us along one extra space
    if (m_items.size() > (size_t) (m_offset +m_cursor) && m_items[m_offset +m_cursor]->GetPropertyBOOL("isseparator"))
    {
      if ((size_t) (m_offset +m_cursor) == m_items.size() - 1)
      {
        MoveUp(false);
      }
      else
      {
        MoveDown(false);
      }
    }
  }
  else if( (size_t) m_itemsPerPage < m_items.size() )
  {
    // Case 4:
    // We are stepping forwards or back in the list, not within the fixed block, and have no special conditions.
    // We actually need to scroll the contents of the list
    // BUGBUG: in a long list this means we land on separators and don't shuffle off them??
    if( offset >= 0 )
      CGUIBaseContainer::ScrollToOffset(offset);
    else
      m_cursor += offset;
  }
  else
  {
    // Case 5:
    // Don't scroll; just move the cursor
    m_cursor += offset;
  }
  
  // This centers the cursor in the list
  if (m_cursor > m_itemsPerPage)
  {
    CGUIBaseContainer::ScrollToOffset(m_cursor - m_itemsPerPage / 2);
    m_cursor = m_itemsPerPage / 2;
  }

  CLog::Log(LOGDEBUG,"CGUIFixedListContainer::ScrollToOffset - EXIT. [m_cursor=%d][offset=%d][m_offset=%d] (scroll)",m_cursor,offset,m_offset);
}