void CGUIBaseContainer::UpdateListProvider(bool forceRefresh /* = false */)
{
  if (m_listProvider)
  {
    if (m_listProvider->Update(forceRefresh))
    {
      // save the current item
      int currentItem = GetSelectedItem();
      CGUIListItem *current = (currentItem >= 0 && currentItem < (int)m_items.size()) ? m_items[currentItem].get() : NULL;
      const std::string prevSelectedPath((current && current->IsFileItem()) ? static_cast<CFileItem *>(current)->GetPath() : "");

      Reset();
      m_listProvider->Fetch(m_items);
      SetPageControlRange();
      // update the newly selected item
      bool found = false;

      // first, try to re-identify selected item by comparing item pointers, though it is not guaranteed that item instances got not recreated on update.
      for (int i = 0; i < (int)m_items.size(); i++)
      {
        if (m_items[i].get() == current)
        {
          found = true;
          if (i != currentItem)
          {
            SelectItem(i);
            break;
          }
        }
      }
      if (!found && !prevSelectedPath.empty())
      {
        // as fallback, try to re-identify selected item by comparing item paths.
        for (int i = 0; i < static_cast<int>(m_items.size()); i++)
        {
          const CGUIListItemPtr c(m_items[i]);
          if (c->IsFileItem())
          {
            const std::string &selectedPath = static_cast<CFileItem *>(c.get())->GetPath();
            if (selectedPath == prevSelectedPath)
            {
              found = true;
              if (i != currentItem)
              {
                SelectItem(i);
                break;
              }
            }
          }
        }
      }
      if (!found && currentItem >= (int)m_items.size())
        SelectItem(m_items.size()-1);
      SetInvalid();
    }
    // always update the scroll by letter, as the list provider may have altered labels
    // while not actually changing the list items.
    UpdateScrollByLetter();
  }
}
Exemple #2
0
void CGUIBaseContainer::UpdateListProvider(bool forceRefresh /* = false */)
{
    if (m_listProvider)
    {
        if (m_listProvider->Update(forceRefresh))
        {
            // save the current item
            int currentItem = GetSelectedItem();
            CGUIListItem *current = (currentItem >= 0 && currentItem < (int)m_items.size()) ? m_items[currentItem].get() : NULL;
            Reset();
            m_listProvider->Fetch(m_items);
            SetPageControlRange();
            // update the newly selected item
            bool found = false;
            for (int i = 0; i < (int)m_items.size(); i++)
            {
                if (m_items[i].get() == current)
                {
                    found = true;
                    if (i != currentItem)
                    {
                        SelectItem(i);
                        break;
                    }
                }
            }
            if (!found && currentItem >= (int)m_items.size())
                SelectItem(m_items.size()-1);
            SetInvalid();
        }
        // always update the scroll by letter, as the list provider may have altered labels
        // while not actually changing the list items.
        UpdateScrollByLetter();
    }
}
void CGUIBaseContainer::UpdateLayout(bool updateAllItems)
{
  if (updateAllItems)
  { // free memory of items
    for (iItems it = m_items.begin(); it != m_items.end(); ++it)
      (*it)->FreeMemory();
  }
  // and recalculate the layout
  CalculateLayout();
  SetPageControlRange();
  MarkDirtyRegion();
}
bool CGUIBaseContainer::OnMessage(CGUIMessage& message)
{
  if (message.GetControlId() == GetID() )
  {
    if (!m_listProvider)
    {
      if (message.GetMessage() == GUI_MSG_LABEL_BIND && message.GetPointer())
      { // bind our items
        Reset();
        CFileItemList *items = static_cast<CFileItemList*>(message.GetPointer());
        for (int i = 0; i < items->Size(); i++)
          m_items.push_back(items->Get(i));
        UpdateLayout(true); // true to refresh all items
        UpdateScrollByLetter();
        SelectItem(message.GetParam1());
        return true;
      }
      else if (message.GetMessage() == GUI_MSG_LABEL_RESET)
      {
        Reset();
        SetPageControlRange();
        return true;
      }
    }
    if (message.GetMessage() == GUI_MSG_ITEM_SELECT)
    {
      SelectItem(message.GetParam1());
      return true;
    }
    else if (message.GetMessage() == GUI_MSG_SETFOCUS)
    {
      if (message.GetParam1()) // subfocus item is specified, so set the offset appropriately
      {
        int offset = GetOffset();
        if (message.GetParam2() && message.GetParam2() == 1)
          offset = 0;
        int item = std::min(offset + (int)message.GetParam1() - 1, (int)m_items.size() - 1);
        SelectItem(item);
      }
    }
    else if (message.GetMessage() == GUI_MSG_ITEM_SELECTED)
    {
      message.SetParam1(GetSelectedItem());
      return true;
    }
    else if (message.GetMessage() == GUI_MSG_PAGE_CHANGE)
    {
      if (message.GetSenderId() == m_pageControl && IsVisible())
      { // update our page if we're visible - not much point otherwise
        if ((int)message.GetParam1() != GetOffset())
          m_pageChangeTimer.StartZero();
        ScrollToOffset(message.GetParam1());
        return true;
      }
    }
    else if (message.GetMessage() == GUI_MSG_REFRESH_LIST)
    { // update our list contents
      for (unsigned int i = 0; i < m_items.size(); ++i)
        m_items[i]->SetInvalid();
    }
    else if (message.GetMessage() == GUI_MSG_MOVE_OFFSET)
    {
      int count = (int)message.GetParam1();
      while (count < 0)
      {
        MoveUp(true);
        count++;
      }
      while (count > 0)
      {
        MoveDown(true);
        count--;
      }
      return true;
    }
  }
  return CGUIControl::OnMessage(message);
}