예제 #1
0
void CGUIFixedListContainer::SelectItem(int item)
{
  // Check that GetOffset() is valid
  ValidateOffset();
  // only select an item if it's in a valid range
  if (item >= 0 && item < (int)m_items.size())
  {
    // Select the item requested - we first set the cursor position
    // which may be different at either end of the list, then the offset
    int minCursor, maxCursor;
    GetCursorRange(minCursor, maxCursor);

    int cursor;
    if ((int)m_items.size() - 1 - item <= maxCursor - m_fixedCursor)
      cursor = std::max(m_fixedCursor, maxCursor + item - (int)m_items.size() + 1);
    else if (item <= m_fixedCursor - minCursor)
      cursor = std::min(m_fixedCursor, minCursor + item);
    else
      cursor = m_fixedCursor;
    if (cursor != GetCursor())
      SetContainerMoving(cursor - GetCursor());
    SetCursor(cursor);
    ScrollToOffset(item - GetCursor());
  }
}
예제 #2
0
EVENT_RESULT CGUIBaseContainer::OnMouseEvent(const CPoint &point, const CMouseEvent &event)
{
    if (event.m_id >= ACTION_MOUSE_LEFT_CLICK && event.m_id <= ACTION_MOUSE_DOUBLE_CLICK)
    {
        if (SelectItemFromPoint(point - CPoint(m_posX, m_posY)))
        {
            OnClick(event.m_id);
            return EVENT_RESULT_HANDLED;
        }
    }
    else if (event.m_id == ACTION_MOUSE_WHEEL_UP)
    {
        Scroll(-1);
        return EVENT_RESULT_HANDLED;
    }
    else if (event.m_id == ACTION_MOUSE_WHEEL_DOWN)
    {
        Scroll(1);
        return EVENT_RESULT_HANDLED;
    }
    else if (event.m_id == ACTION_GESTURE_NOTIFY)
    {
        return (m_orientation == HORIZONTAL) ? EVENT_RESULT_PAN_HORIZONTAL : EVENT_RESULT_PAN_VERTICAL;
    }
    else if (event.m_id == ACTION_GESTURE_BEGIN)
    {   // grab exclusive access
        CGUIMessage msg(GUI_MSG_EXCLUSIVE_MOUSE, GetID(), GetParentID());
        SendWindowMessage(msg);
        return EVENT_RESULT_HANDLED;
    }
    else if (event.m_id == ACTION_GESTURE_PAN)
    {   // do the drag and validate our offset (corrects for end of scroll)
        m_scroller.SetValue(m_scroller.GetValue() - ((m_orientation == HORIZONTAL) ? event.m_offsetX : event.m_offsetY));
        float size = (m_layout) ? m_layout->Size(m_orientation) : 10.0f;
        int offset = (int)MathUtils::round_int(m_scroller.GetValue() / size);
        m_lastScrollStartTimer.Stop();
        m_scrollTimer.Start();
        SetOffset(offset);
        ValidateOffset();
        return EVENT_RESULT_HANDLED;
    }
    else if (event.m_id == ACTION_GESTURE_END)
    {   // release exclusive access
        CGUIMessage msg(GUI_MSG_EXCLUSIVE_MOUSE, 0, GetParentID());
        SendWindowMessage(msg);
        m_scrollTimer.Stop();
        // and compute the nearest offset from this and scroll there
        float size = (m_layout) ? m_layout->Size(m_orientation) : 10.0f;
        float offset = m_scroller.GetValue() / size;
        int toOffset = (int)MathUtils::round_int(offset);
        if (toOffset < offset)
            SetOffset(toOffset+1);
        else
            SetOffset(toOffset-1);
        ScrollToOffset(toOffset);
        return EVENT_RESULT_HANDLED;
    }
    return EVENT_RESULT_UNHANDLED;
}
예제 #3
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);
}
예제 #4
0
void CGUIFixedListContainer::SelectItem(int item)
{
  // Check that m_offset is valid
  ValidateOffset();
  // only select an item if it's in a valid range
  if (item >= 0 && item < (int)m_items.size())
  {
    // Select the item requested
    ScrollToOffset(item - m_cursor);
  }
}
예제 #5
0
void CGUIControlGroupList::Process(unsigned int currentTime, CDirtyRegionList &dirtyregions)
{
  if (m_scroller.Update(currentTime))
    MarkDirtyRegion();

  // first we update visibility of all our items, to ensure our size and
  // alignment computations are correct.
  for (iControls it = m_children.begin(); it != m_children.end(); ++it)
  {
    CGUIControl *control = *it;
    GUIPROFILER_VISIBILITY_BEGIN(control);
    control->UpdateVisibility();
    GUIPROFILER_VISIBILITY_END(control);
  }

  ValidateOffset();
  if (m_pageControl && m_lastScrollerValue != m_scroller.GetValue())
  {
    CGUIMessage message(GUI_MSG_LABEL_RESET, GetParentID(), m_pageControl, (int)Size(), (int)m_totalSize);
    SendWindowMessage(message);
    CGUIMessage message2(GUI_MSG_ITEM_SELECT, GetParentID(), m_pageControl, (int)m_scroller.GetValue());
    SendWindowMessage(message2);
    m_lastScrollerValue = m_scroller.GetValue();
  }
  // we run through the controls, rendering as we go
  int index = 0;
  float pos = GetAlignOffset();
  for (iControls it = m_children.begin(); it != m_children.end(); ++it)
  {
    // note we render all controls, even if they're offscreen, as then they'll be updated
    // with respect to animations
    CGUIControl *control = *it;
    if (m_orientation == VERTICAL)
      g_graphicsContext.SetOrigin(m_posX, m_posY + pos - m_scroller.GetValue());
    else
      g_graphicsContext.SetOrigin(m_posX + pos - m_scroller.GetValue(), m_posY);
    control->DoProcess(currentTime, dirtyregions);

    if (control->IsVisible())
    {
      if (IsControlOnScreen(pos, control))
      {
        if (control->HasFocus())
          m_focusedPosition = index;
        index++;
      }

      pos += Size(control) + m_itemGap;
    }
    g_graphicsContext.RestoreOrigin();
  }
  CGUIControl::Process(currentTime, dirtyregions);
}
예제 #6
0
void CGUIControlGroupList::Process(unsigned int currentTime, CDirtyRegionList &dirtyregions)
{
  if (m_scrollSpeed != 0)
  {
    MarkDirtyRegion();
    m_offset += m_scrollSpeed * (currentTime - m_scrollLastTime);
    if ((m_scrollSpeed < 0 && m_offset < m_scrollOffset) ||
        (m_scrollSpeed > 0 && m_offset > m_scrollOffset))
    {
      m_offset = m_scrollOffset;
      m_scrollSpeed = 0;
    }
  }
  m_scrollLastTime = currentTime;

  // first we update visibility of all our items, to ensure our size and
  // alignment computations are correct.
  for (iControls it = m_children.begin(); it != m_children.end(); ++it)
  {
    CGUIControl *control = *it;
    GUIPROFILER_VISIBILITY_BEGIN(control);
    control->UpdateVisibility();
    GUIPROFILER_VISIBILITY_END(control);
  }

  ValidateOffset();
  if (m_pageControl)
  {
    CGUIMessage message(GUI_MSG_LABEL_RESET, GetParentID(), m_pageControl, (int)m_height, (int)m_totalSize);
    SendWindowMessage(message);
    CGUIMessage message2(GUI_MSG_ITEM_SELECT, GetParentID(), m_pageControl, (int)m_offset);
    SendWindowMessage(message2);
  }
  // we run through the controls, rendering as we go
  float pos = GetAlignOffset();
  for (iControls it = m_children.begin(); it != m_children.end(); ++it)
  {
    // note we render all controls, even if they're offscreen, as then they'll be updated
    // with respect to animations
    CGUIControl *control = *it;
    if (m_orientation == VERTICAL)
      g_graphicsContext.SetOrigin(m_posX, m_posY + pos - m_offset);
    else
      g_graphicsContext.SetOrigin(m_posX + pos - m_offset, m_posY);
    control->DoProcess(currentTime, dirtyregions);

    if (control->IsVisible())
      pos += Size(control) + m_itemGap;
    g_graphicsContext.RestoreOrigin();
  }
  CGUIControl::Process(currentTime, dirtyregions);
}
예제 #7
0
void CGUIFixedListContainer::SelectItem(int item)
{
  // Check that m_offset is valid
  ValidateOffset();
  // only select an item if it's in a valid range
  if (item >= 0 && item < (int)m_items.size())
  {
    if (m_items[item]->GetPropertyBOOL("isseparator"))
    {
      SelectItem(item + 1);
      return;
    }

    ScrollToOffset(item - m_cursor);
  }
}
예제 #8
0
void CGUIPanelContainer::SelectItem(int item)
{
  // Check that our offset is valid
  ValidateOffset();
  // only select an item if it's in a valid range
  if (item >= 0 && item < (int)m_items.size())
  {
    // Select the item requested
    if (item >= GetOffset() * m_itemsPerRow && item < (GetOffset() + m_itemsPerPage) * m_itemsPerRow)
    { // the item is on the current page, so don't change it.
      SetCursor(item - GetOffset() * m_itemsPerRow);
    }
    else if (item < GetOffset() * m_itemsPerRow)
    { // item is on a previous page - make it the first item on the page
      SetCursor(item % m_itemsPerRow);
      ScrollToOffset((item - GetCursor()) / m_itemsPerRow);
    }
    else // (item >= GetOffset()+m_itemsPerPage)
    { // item is on a later page - make it the last row on the page
      SetCursor(item % m_itemsPerRow + m_itemsPerRow * (m_itemsPerPage - 1));
      ScrollToOffset((item - GetCursor()) / m_itemsPerRow);
    }
  }
}
예제 #9
0
void CGUIListContainer::SelectItem(int item)
{
  // Check that m_offset is valid
  ValidateOffset();
  // only select an item if it's in a valid range
  if (item >= 0 && item < (int)m_items.size())
  {
    // Select the item requested
    if (item >= m_offset && item < m_offset + m_itemsPerPage)
    { // the item is on the current page, so don't change it.
      SetCursor(item - m_offset);
    }
    else if (item < m_offset)
    { // item is on a previous page - make it the first item on the page
      SetCursor(0);
      ScrollToOffset(item);
    }
    else // (item >= m_offset+m_itemsPerPage)
    { // item is on a later page - make it the last item on the page
      SetCursor(m_itemsPerPage - 1);
      ScrollToOffset(item - m_cursor);
    }
  }
}
예제 #10
0
bool CGUIControlGroupList::OnMessage(CGUIMessage& message)
{
  switch (message.GetMessage() )
  {
  case GUI_MSG_FOCUSED:
    { // a control has been focused
      // scroll if we need to and update our page control
      ValidateOffset();
      float offset = 0;
      for (iControls it = m_children.begin(); it != m_children.end(); ++it)
      {
        CGUIControl *control = *it;
        if (!control->IsVisible())
          continue;
        if (control->GetID() == message.GetControlId())
        {
          // find out whether this is the first or last control
          if (IsFirstFocusableControl(control))
            ScrollTo(0);
          else if (IsLastFocusableControl(control))
            ScrollTo(m_totalSize - Size());
          else if (offset < m_scroller.GetValue())
            ScrollTo(offset);
          else if (offset + Size(control) > m_scroller.GetValue() + Size())
            ScrollTo(offset + Size(control) - Size());
          break;
        }
        offset += Size(control) + m_itemGap;
      }
    }
    break;
  case GUI_MSG_SETFOCUS:
    {
      // we've been asked to focus.  We focus the last control if it's on this page,
      // else we'll focus the first focusable control from our offset (after verifying it)
      ValidateOffset();
      // now check the focusControl's offset
      float offset = 0;
      for (iControls it = m_children.begin(); it != m_children.end(); ++it)
      {
        CGUIControl *control = *it;
        if (!control->IsVisible())
          continue;
        if (control->GetID() == m_focusedControl)
        {
          if (IsControlOnScreen(offset, control))
            return CGUIControlGroup::OnMessage(message);
          break;
        }
        offset += Size(control) + m_itemGap;
      }
      // find the first control on this page
      offset = 0;
      for (iControls it = m_children.begin(); it != m_children.end(); ++it)
      {
        CGUIControl *control = *it;
        if (!control->IsVisible())
          continue;
        if (control->CanFocus() && IsControlOnScreen(offset, control))
        {
          m_focusedControl = control->GetID();
          break;
        }
        offset += Size(control) + m_itemGap;
      }
    }
    break;
  case GUI_MSG_PAGE_CHANGE:
    {
      if (message.GetSenderId() == m_pageControl)
      { // it's from our page control
        ScrollTo((float)message.GetParam1());
        return true;
      }
    }
    break;
  }
  return CGUIControlGroup::OnMessage(message);
}
예제 #11
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);
}
예제 #12
0
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();
}
예제 #13
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();
}
예제 #14
0
void CGUIControlGroupList::Render()
{
  if (m_scrollSpeed != 0)
  {
    m_offset += m_scrollSpeed * (m_renderTime - m_scrollTime);
    if (m_scrollSpeed < 0 && m_offset < m_scrollOffset ||
        m_scrollSpeed > 0 && m_offset > m_scrollOffset)
    {
      m_offset = m_scrollOffset;
      m_scrollSpeed = 0;
    }
  }
  m_scrollTime = m_renderTime;

  ValidateOffset();
  if (m_pageControl)
  {
    CGUIMessage message(GUI_MSG_LABEL_RESET, GetParentID(), m_pageControl, (DWORD)m_height, (DWORD)m_totalSize);
    SendWindowMessage(message);
    CGUIMessage message2(GUI_MSG_ITEM_SELECT, GetParentID(), m_pageControl, (DWORD)m_offset);
    SendWindowMessage(message2);
  }
  // we run through the controls, rendering as we go
  bool render(g_graphicsContext.SetClipRegion(m_posX, m_posY, m_width, m_height));
  float pos = 0;
  float focusedPos = 0;
  CGUIControl *focusedControl = NULL;
  for (iControls it = m_children.begin(); it != m_children.end(); ++it)
  {
    // note we render all controls, even if they're offscreen, as then they'll be updated
    // with respect to animations
    CGUIControl *control = *it;
    control->UpdateVisibility();
    if (m_renderFocusedLast && control->HasFocus())
    {
      focusedControl = control;
      focusedPos = pos;
    }
    else
    {
      if (m_orientation == VERTICAL)
        g_graphicsContext.SetOrigin(m_posX, m_posY + pos - m_offset);
      else
        g_graphicsContext.SetOrigin(m_posX + pos - m_offset, m_posY);
      control->DoRender(m_renderTime);
    }
    if (control->IsVisible())
      pos += Size(control) + m_itemGap;
    g_graphicsContext.RestoreOrigin();
  }
  if (focusedControl)
  {
    if (m_orientation == VERTICAL)
      g_graphicsContext.SetOrigin(m_posX, m_posY + focusedPos - m_offset);
    else
      g_graphicsContext.SetOrigin(m_posX + focusedPos - m_offset, m_posY);
    focusedControl->DoRender(m_renderTime);
  }
  if (render) g_graphicsContext.RestoreClipRegion();
  CGUIControl::Render();
}