diff options
Diffstat (limited to 'guilib/GUIPanelContainer.cpp')
-rw-r--r-- | guilib/GUIPanelContainer.cpp | 492 |
1 files changed, 0 insertions, 492 deletions
diff --git a/guilib/GUIPanelContainer.cpp b/guilib/GUIPanelContainer.cpp deleted file mode 100644 index 3031c571b9..0000000000 --- a/guilib/GUIPanelContainer.cpp +++ /dev/null @@ -1,492 +0,0 @@ -/* - * Copyright (C) 2005-2008 Team XBMC - * http://www.xbmc.org - * - * This Program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This Program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with XBMC; see the file COPYING. If not, write to - * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. - * http://www.gnu.org/copyleft/gpl.html - * - */ - -#include "GUIPanelContainer.h" -#include "GUIListItem.h" -#include "utils/GUIInfoManager.h" -#include "Key.h" - -using namespace std; - -CGUIPanelContainer::CGUIPanelContainer(int parentID, int controlID, float posX, float posY, float width, float height, ORIENTATION orientation, int scrollTime, int preloadItems) - : CGUIBaseContainer(parentID, controlID, posX, posY, width, height, orientation, scrollTime, preloadItems) -{ - ControlType = GUICONTAINER_PANEL; - m_type = VIEW_TYPE_ICON; - m_itemsPerRow = 1; -} - -CGUIPanelContainer::~CGUIPanelContainer(void) -{ -} - -void CGUIPanelContainer::Render() -{ - ValidateOffset(); - - if (m_bInvalidated) - UpdateLayout(); - - if (!m_layout || !m_focusedLayout) return; - - UpdateScrollOffset(); - - int offset = (int)(m_scrollOffset / m_layout->Size(m_orientation)); - - int cacheBefore, cacheAfter; - GetCacheOffsets(cacheBefore, cacheAfter); - - // Free memory not used on screen at the moment, do this first so there's more memory for the new items. - FreeMemory(CorrectOffset(offset - cacheBefore, 0), CorrectOffset(offset + cacheAfter + m_itemsPerPage + 1, 0)); - - 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; - pos += (offset - cacheBefore) * m_layout->Size(m_orientation) - m_scrollOffset; - end += cacheAfter * m_layout->Size(m_orientation); - - float focusedPos = 0; - int focusedCol = 0; - CGUIListItemPtr focusedItem; - 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 == m_offset * m_itemsPerRow + m_cursor) && m_bHasFocus; - // render our item - if (focused) - { - focusedPos = pos; - focusedCol = col; - focusedItem = item; - } - else - { - if (m_orientation == VERTICAL) - RenderItem(origin.x + col * m_layout->Size(HORIZONTAL), pos, item.get(), false); - else - RenderItem(pos, origin.y + col * m_layout->Size(VERTICAL), item.get(), false); - } - } - // increment our position - if (col < m_itemsPerRow - 1) - col++; - else - { - pos += m_layout->Size(m_orientation); - col = 0; - } - current++; - } - // and render the focused item last (for overlapping purposes) - if (focusedItem) - { - if (m_orientation == VERTICAL) - RenderItem(origin.x + focusedCol * m_layout->Size(HORIZONTAL), focusedPos, focusedItem.get(), true); - else - RenderItem(focusedPos, origin.y + focusedCol * m_layout->Size(VERTICAL), focusedItem.get(), true); - } - - g_graphicsContext.RestoreClipRegion(); - - UpdatePageControl(offset); - - CGUIControl::Render(); -} - -bool CGUIPanelContainer::OnAction(const CAction &action) -{ - switch (action.GetID()) - { - case ACTION_PAGE_UP: - { - if (m_offset == 0) - { // already on the first page, so move to the first item - SetCursor(0); - } - else - { // scroll up to the previous page - Scroll( -m_itemsPerPage); - } - return true; - } - break; - case ACTION_PAGE_DOWN: - { - if ((m_offset + m_itemsPerPage) * m_itemsPerRow >= (int)m_items.size() || (int)m_items.size() < m_itemsPerPage) - { // already at the last page, so move to the last item. - SetCursor(m_items.size() - m_offset * m_itemsPerRow - 1); - } - else - { // scroll down to the next page - Scroll(m_itemsPerPage); - } - return true; - } - break; - // smooth scrolling (for analog controls) - case ACTION_SCROLL_UP: - { - m_analogScrollCount += action.GetAmount() * action.GetAmount(); - bool handled = false; - while (m_analogScrollCount > AnalogScrollSpeed()) - { - handled = true; - m_analogScrollCount -= AnalogScrollSpeed(); - if (m_offset > 0)// && m_cursor <= m_itemsPerPage * m_itemsPerRow / 2) - { - Scroll(-1); - } - else if (m_cursor > 0) - { - SetCursor(m_cursor - 1); - } - } - return handled; - } - break; - case ACTION_SCROLL_DOWN: - { - m_analogScrollCount += action.GetAmount() * action.GetAmount(); - bool handled = false; - while (m_analogScrollCount > AnalogScrollSpeed()) - { - handled = true; - m_analogScrollCount -= AnalogScrollSpeed(); - if ((m_offset + m_itemsPerPage) * m_itemsPerRow < (int)m_items.size())// && m_cursor >= m_itemsPerPage * m_itemsPerRow / 2) - { - Scroll(1); - } - else if (m_cursor < m_itemsPerPage * m_itemsPerRow - 1 && m_offset * m_itemsPerRow + m_cursor < (int)m_items.size() - 1) - { - SetCursor(m_cursor + 1); - } - } - return handled; - } - break; - } - return CGUIBaseContainer::OnAction(action); -} - -bool CGUIPanelContainer::OnMessage(CGUIMessage& message) -{ - if (message.GetControlId() == GetID() ) - { - if (message.GetMessage() == GUI_MSG_LABEL_RESET) - { - SetCursor(0); - // fall through to base class - } - else if (message.GetMessage() == GUI_MSG_ITEM_SELECT) - { - SelectItem(message.GetParam1()); - return true; - } - } - return CGUIBaseContainer::OnMessage(message); -} - -void CGUIPanelContainer::OnLeft() -{ - bool wrapAround = m_controlLeft == GetID() || !(m_controlLeft || m_leftActions.size()); - if (m_orientation == VERTICAL && MoveLeft(wrapAround)) - return; - if (m_orientation == HORIZONTAL && MoveUp(wrapAround)) - return; - CGUIControl::OnLeft(); -} - -void CGUIPanelContainer::OnRight() -{ - bool wrapAround = m_controlRight == GetID() || !(m_controlRight || m_rightActions.size()); - if (m_orientation == VERTICAL && MoveRight(wrapAround)) - return; - if (m_orientation == HORIZONTAL && MoveDown(wrapAround)) - return; - return CGUIControl::OnRight(); -} - -void CGUIPanelContainer::OnUp() -{ - bool wrapAround = m_controlUp == GetID() || !(m_controlUp || m_upActions.size()); - if (m_orientation == VERTICAL && MoveUp(wrapAround)) - return; - if (m_orientation == HORIZONTAL && MoveLeft(wrapAround)) - return; - CGUIControl::OnUp(); -} - -void CGUIPanelContainer::OnDown() -{ - bool wrapAround = m_controlDown == GetID() || !(m_controlDown || m_downActions.size()); - if (m_orientation == VERTICAL && MoveDown(wrapAround)) - return; - if (m_orientation == HORIZONTAL && MoveRight(wrapAround)) - return; - return CGUIControl::OnDown(); -} - -bool CGUIPanelContainer::MoveDown(bool wrapAround) -{ - if (m_cursor + m_itemsPerRow < m_itemsPerPage * m_itemsPerRow && (m_offset + 1 + m_cursor / m_itemsPerRow) * m_itemsPerRow < (int)m_items.size()) - { // move to last item if necessary - if ((m_offset + 1)*m_itemsPerRow + m_cursor >= (int)m_items.size()) - SetCursor((int)m_items.size() - 1 - m_offset*m_itemsPerRow); - else - SetCursor(m_cursor + m_itemsPerRow); - } - else if ((m_offset + 1 + m_cursor / m_itemsPerRow) * m_itemsPerRow < (int)m_items.size()) - { // we scroll to the next row, and move to last item if necessary - if ((m_offset + 1)*m_itemsPerRow + m_cursor >= (int)m_items.size()) - SetCursor((int)m_items.size() - 1 - (m_offset + 1)*m_itemsPerRow); - ScrollToOffset(m_offset + 1); - } - else if (wrapAround) - { // move first item in list - SetCursor(m_cursor % m_itemsPerRow); - ScrollToOffset(0); - SetContainerMoving(1); - } - else - return false; - return true; -} - -bool CGUIPanelContainer::MoveUp(bool wrapAround) -{ - if (m_cursor >= m_itemsPerRow) - SetCursor(m_cursor - m_itemsPerRow); - else if (m_offset > 0) - ScrollToOffset(m_offset - 1); - else if (wrapAround) - { // move last item in list in this column - SetCursor((m_cursor % m_itemsPerRow) + (m_itemsPerPage - 1) * m_itemsPerRow); - int offset = max((int)GetRows() - m_itemsPerPage, 0); - // should check here whether cursor is actually allowed here, and reduce accordingly - if (offset * m_itemsPerRow + m_cursor >= (int)m_items.size()) - SetCursor((int)m_items.size() - offset * m_itemsPerRow - 1); - ScrollToOffset(offset); - SetContainerMoving(-1); - } - else - return false; - return true; -} - -bool CGUIPanelContainer::MoveLeft(bool wrapAround) -{ - int col = m_cursor % m_itemsPerRow; - if (col > 0) - SetCursor(m_cursor - 1); - else if (wrapAround) - { // wrap around - SetCursor(m_cursor + m_itemsPerRow - 1); - if (m_offset * m_itemsPerRow + m_cursor >= (int)m_items.size()) - SetCursor((int)m_items.size() - m_offset * m_itemsPerRow); - } - else - return false; - return true; -} - -bool CGUIPanelContainer::MoveRight(bool wrapAround) -{ - int col = m_cursor % m_itemsPerRow; - if (col + 1 < m_itemsPerRow && m_offset * m_itemsPerRow + m_cursor + 1 < (int)m_items.size()) - SetCursor(m_cursor + 1); - else if (wrapAround) // move first item in row - SetCursor(m_cursor - col); - else - return false; - return true; -} - -// scrolls the said amount -void CGUIPanelContainer::Scroll(int amount) -{ - // increase or decrease the offset - int offset = m_offset + amount; - if (offset > ((int)GetRows() - m_itemsPerPage) * m_itemsPerRow) - { - offset = ((int)GetRows() - m_itemsPerPage) * m_itemsPerRow; - } - if (offset < 0) offset = 0; - ScrollToOffset(offset); -} - -void CGUIPanelContainer::ValidateOffset() -{ // first thing is we check the range of m_offset - if (!m_layout) return; - if (m_offset > (int)GetRows() - m_itemsPerPage || m_scrollOffset > ((int)GetRows() - m_itemsPerPage) * m_layout->Size(m_orientation)) - { - m_offset = (int)GetRows() - m_itemsPerPage; - m_scrollOffset = m_offset * m_layout->Size(m_orientation); - } - if (m_offset < 0 || m_scrollOffset < 0) - { - m_offset = 0; - m_scrollOffset = 0; - } -} - -void CGUIPanelContainer::SetCursor(int cursor) -{ - // +1 to ensure we're OK if we have a half item - if (cursor > (m_itemsPerPage + 1)*m_itemsPerRow - 1) cursor = (m_itemsPerPage + 1)*m_itemsPerRow - 1; - if (cursor < 0) cursor = 0; - if (!m_wasReset) - SetContainerMoving(cursor - m_cursor); - m_cursor = cursor; -} - -void CGUIPanelContainer::CalculateLayout() -{ - GetCurrentLayouts(); - - if (!m_layout || !m_focusedLayout) return; - // calculate the number of items to display - if (m_orientation == HORIZONTAL) - { - m_itemsPerRow = (int)(m_height / m_layout->Size(VERTICAL)); - m_itemsPerPage = (int)(m_width / m_layout->Size(HORIZONTAL)); - } - else - { - m_itemsPerRow = (int)(m_width / m_layout->Size(HORIZONTAL)); - m_itemsPerPage = (int)(m_height / m_layout->Size(VERTICAL)); - } - if (m_itemsPerRow < 1) m_itemsPerRow = 1; - if (m_itemsPerPage < 1) m_itemsPerPage = 1; - - // ensure that the scroll offset is a multiple of our size - m_scrollOffset = m_offset * m_layout->Size(m_orientation); -} - -unsigned int CGUIPanelContainer::GetRows() const -{ - assert(m_itemsPerRow > 0); - return (m_items.size() + m_itemsPerRow - 1) / m_itemsPerRow; -} - -float CGUIPanelContainer::AnalogScrollSpeed() const -{ - return 10.0f / m_itemsPerPage; -} - -int CGUIPanelContainer::CorrectOffset(int offset, int cursor) const -{ - return offset * m_itemsPerRow + cursor; -} - -int CGUIPanelContainer::GetCursorFromPoint(const CPoint &point, CPoint *itemPoint) const -{ - if (!m_layout) - return -1; - - float sizeX = m_orientation == VERTICAL ? m_layout->Size(HORIZONTAL) : m_layout->Size(VERTICAL); - float sizeY = m_orientation == VERTICAL ? m_layout->Size(VERTICAL) : m_layout->Size(HORIZONTAL); - - float posY = m_orientation == VERTICAL ? point.y : point.x; - for (int y = 0; y < m_itemsPerPage + 1; y++) // +1 to ensure if we have a half item we can select it - { - float posX = m_orientation == VERTICAL ? point.x : point.y; - for (int x = 0; x < m_itemsPerRow; x++) - { - int item = x + y * m_itemsPerRow; - if (posX < sizeX && posY < sizeY && item + m_offset < (int)m_items.size()) - { // found - return item; - } - posX -= sizeX; - } - posY -= sizeY; - } - return false; -} - -bool CGUIPanelContainer::SelectItemFromPoint(const CPoint &point) -{ - int cursor = GetCursorFromPoint(point); - if (cursor < 0) - return false; - SetCursor(cursor); - return true; -} - -bool CGUIPanelContainer::GetCondition(int condition, int data) const -{ // probably only works vertically atm... - int row = m_cursor / m_itemsPerRow; - int col = m_cursor % m_itemsPerRow; - if (m_orientation == HORIZONTAL) - swap(row, col); - switch (condition) - { - case CONTAINER_ROW: - return (row == data); - case CONTAINER_COLUMN: - return (col == data); - default: - return CGUIBaseContainer::GetCondition(condition, data); - } -} - -void CGUIPanelContainer::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 * m_itemsPerRow && item < (m_offset + m_itemsPerPage) * m_itemsPerRow) - { // the item is on the current page, so don't change it. - SetCursor(item - m_offset * m_itemsPerRow); - } - else if (item < m_offset * m_itemsPerRow) - { // item is on a previous page - make it the first item on the page - SetCursor(item % m_itemsPerRow); - ScrollToOffset((item - m_cursor) / m_itemsPerRow); - } - else // (item >= m_offset+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 - m_cursor) / m_itemsPerRow); - } - } -} - -bool CGUIPanelContainer::HasPreviousPage() const -{ - return (m_offset > 0); -} - -bool CGUIPanelContainer::HasNextPage() const -{ - return (m_offset != (int)GetRows() - m_itemsPerPage && (int)GetRows() > m_itemsPerPage); -} - |