Esempio n. 1
0
void
GridView::MoveFocus(Direction direction)
{
  signed focusPos = GetIndexOfItemInFocus();

  if (focusPos == -1)
    // We are on a page without enabled items.
    // We should show the next page if exists
    ShowNextPage(direction);
  else {
    signed newFocusPos = GetNextItemIndex(focusPos, direction);

    if (newFocusPos != -1) {
      // we are on the same page
      items[newFocusPos]->SetFocus();
      if (!items[newFocusPos]->HasFocus()) {
        /* unable to set the focus, let's try simple Tab/Shift-Tab
           behavior instead */
        newFocusPos = GetNextEnabledItemIndex(focusPos, direction);
        if (newFocusPos != -1)
          items[newFocusPos]->SetFocus();
      }
      RefreshLayout();
    } else
      ShowNextPage(direction);
  }
}
Esempio n. 2
0
void
GridView::RefreshLayout()
{
  const PixelRect rc = GetClientRect();
  unsigned maxColumns = (rc.right - rc.left + horizontal_spacing)
    / (column_width + horizontal_spacing);
  if (maxColumns == 0)
    maxColumns = 1;

  unsigned maxRows = (rc.bottom - rc.top + vertical_spacing)
    / (row_height + vertical_spacing);
  if (maxRows == 0)
    maxRows = 1;

  if (maxColumns < num_columns)
     num_columns = maxColumns;

  if (maxRows < num_rows)
    num_rows = maxRows;

  unsigned pageSize = num_columns * num_rows;

  // Center grid in the client area
  unsigned reminderH = rc.right - rc.left + horizontal_spacing
    - num_columns * (column_width + horizontal_spacing);
  unsigned reminderV = rc.bottom - rc.top + vertical_spacing
    - num_rows * (row_height + vertical_spacing);
  unsigned leftOrigin = rc.left + reminderH / 2;
  unsigned topOrigin= rc.top + reminderV / 2;

  // Determine current page from item that has focus
  // If there is no item with focus or the item with focus is on current page,
  // the current page remains unchanged
  signed focusPos = GetIndexOfItemInFocus();
  if (focusPos != -1)
    current_page = focusPos / pageSize;

  for (unsigned i = items.size(); i--;) {
    unsigned pagePos = i % pageSize;
    unsigned itemPage = i / pageSize;
    unsigned colNum = pagePos % num_columns;
    unsigned rowNum = pagePos / num_columns;

    items[i]->Move(leftOrigin + colNum * (column_width + horizontal_spacing),
                   topOrigin + rowNum * (row_height + vertical_spacing),
                   column_width, row_height);
    items[i]->SetVisible(itemPage == current_page);
  }
}
Esempio n. 3
0
void
GridView::ShowNextPage(Direction direction)
{
  signed newPos = -1;
  unsigned pageSize = num_columns * num_rows;
  unsigned lastPage = items.size() / pageSize;

  if (direction == Direction::LEFT && current_page > 0)
    current_page--;
  else if (direction == Direction::RIGHT && current_page < lastPage)
    current_page++;
  else
    return;

  unsigned currentPageSize = current_page == lastPage
    ? items.size() % pageSize
    : pageSize;

  signed focusPos = GetIndexOfItemInFocus();

  if (focusPos != -1) {
    unsigned oldPagePos = focusPos % pageSize;
    unsigned oldRowNum = oldPagePos / num_columns;

    if (direction == Direction::LEFT)
      // last column in the same row
      newPos = current_page * pageSize + (oldRowNum + 1) * num_columns - 1;
    else { // direction == Direction::RIGHT
      // first column in the same row
      newPos = current_page * pageSize + oldRowNum * num_columns;

      if (newPos >= (signed)items.size()) {
        // first columns in the last row
        newPos = current_page * pageSize + currentPageSize
          - (currentPageSize - 1) % num_columns - 1;
      }
    }
  }

  if (newPos != -1) {
    items[newPos]->SetFocus();
    /* unable to set the focus on the desired item, let's try
       Tab/Shift-Tab behavior instead */
    if (!items[newPos]->HasFocus()) {
      if (direction == Direction::LEFT)
        newPos = GetNextEnabledItemIndex(current_page * pageSize
                                         + currentPageSize, direction);
      else
        newPos = GetNextEnabledItemIndex(current_page * pageSize - 1,
                                         direction);

      // set focus only if it is on the same page
      if (newPos != -1 &&
          newPos >= (signed)(current_page * pageSize) &&
          newPos < (signed)(current_page * pageSize + currentPageSize)) {
        items[newPos]->SetFocus();
      }
    } else if (focusPos != -1) {
#ifdef USE_WINUSER
      HWND oldFocusHwnd = ::GetFocus();
      if (oldFocusHwnd != nullptr)
        ::SendMessage(oldFocusHwnd, WM_CANCELMODE, 0, 0);
#else
      items[focusPos]->ClearFocus();
#endif /* USE_WINUSER */
    }

    RefreshLayout();
  }
}