bool CGUIFixedListContainer::SelectItemFromPoint(const CPoint &point) { if (!m_focusedLayout || !m_layout) return false; MarkDirtyRegion(); const float mouse_scroll_speed = 0.25f; const float mouse_max_amount = 1.5f; float sizeOfItem = m_layout->Size(m_orientation); int minCursor, maxCursor; GetCursorRange(minCursor, maxCursor); // see if the point is either side of our focus range float start = (minCursor + 0.2f) * sizeOfItem; float end = (maxCursor - 0.2f) * sizeOfItem + m_focusedLayout->Size(m_orientation); float pos = (m_orientation == VERTICAL) ? point.y : point.x; if (pos < start && GetOffset() > -minCursor) { // scroll backward if (!InsideLayout(m_layout, point)) return false; float amount = std::min((start - pos) / sizeOfItem, mouse_max_amount); m_analogScrollCount += amount * amount * mouse_scroll_speed; if (m_analogScrollCount > 1) { ScrollToOffset(GetOffset() - 1); m_analogScrollCount = 0; } return true; } else if (pos > end && GetOffset() + maxCursor < (int)m_items.size() - 1) { if (!InsideLayout(m_layout, point)) return false; // scroll forward float amount = std::min((pos - end) / sizeOfItem, mouse_max_amount); m_analogScrollCount += amount * amount * mouse_scroll_speed; if (m_analogScrollCount > 1) { ScrollToOffset(GetOffset() + 1); m_analogScrollCount = 0; } return true; } else { // select the appropriate item int cursor = GetCursorFromPoint(point); if (cursor < 0) return false; // calling SelectItem() here will focus the item and scroll, which isn't really what we're after SetCursor(cursor); return true; } }
int CGUIFixedListContainer::GetCursorFromPoint(const CPoint &point, CPoint *itemPoint) const { if (!m_focusedLayout || !m_layout) return -1; int minCursor, maxCursor; GetCursorRange(minCursor, maxCursor); // see if the point is either side of our focus range float start = (minCursor + 0.2f) * m_layout->Size(m_orientation); float end = (maxCursor - 0.2f) * m_layout->Size(m_orientation) + m_focusedLayout->Size(m_orientation); float pos = (m_orientation == VERTICAL) ? point.y : point.x; if (pos >= start && pos <= end) { // select the appropriate item pos -= minCursor * m_layout->Size(m_orientation); for (int row = minCursor; row <= maxCursor; row++) { const CGUIListItemLayout *layout = (row == GetCursor()) ? m_focusedLayout : m_layout; if (pos < layout->Size(m_orientation)) { if (!InsideLayout(layout, point)) return -1; return row; } pos -= layout->Size(m_orientation); } } return -1; }
bool CGUIWrappingListContainer::SelectItemFromPoint(const CPoint &point) { if (!m_focusedLayout || !m_layout) return false; const float mouse_scroll_speed = 0.05f; const float mouse_max_amount = 1.0f; // max speed: 1 item per frame float sizeOfItem = m_layout->Size(m_orientation); // see if the point is either side of our focused item float start = m_cursor * sizeOfItem; float end = start + m_focusedLayout->Size(m_orientation); float pos = (m_orientation == VERTICAL) ? point.y : point.x; if (pos < start - 0.5f * sizeOfItem) { // scroll backward if (!InsideLayout(m_layout, point)) return false; float amount = std::min((start - pos) / sizeOfItem, mouse_max_amount); m_analogScrollCount += amount * amount * mouse_scroll_speed; CLog::Log(LOGERROR, "%s: Speed %f", __FUNCTION__, amount); if (m_analogScrollCount > 1) { Scroll(-1); m_analogScrollCount-=1.0f; } return true; } else if (pos > end + 0.5f * sizeOfItem) { // scroll forward if (!InsideLayout(m_layout, point)) return false; float amount = std::min((pos - end) / sizeOfItem, mouse_max_amount); m_analogScrollCount += amount * amount * mouse_scroll_speed; if (m_analogScrollCount > 1) { Scroll(1); m_analogScrollCount-=1.0f; } return true; } return InsideLayout(m_focusedLayout, point); }
int CGUIListContainer::GetCursorFromPoint(const CPoint &point, CPoint *itemPoint) const { if (!m_focusedLayout || !m_layout) return -1; int row = 0; float pos = (m_orientation == VERTICAL) ? point.y : point.x; while (row < m_itemsPerPage + 1) // 1 more to ensure we get the (possible) half item at the end. { const CGUIListItemLayout *layout = (row == GetCursor()) ? m_focusedLayout : m_layout; if (pos < layout->Size(m_orientation) && row + GetOffset() < (int)m_items.size()) { // found correct "row" -> check horizontal if (!InsideLayout(layout, point)) return -1; if (itemPoint) *itemPoint = m_orientation == VERTICAL ? CPoint(point.x, pos) : CPoint(pos, point.y); return row; } row++; pos -= layout->Size(m_orientation); } return -1; }