aboutsummaryrefslogtreecommitdiff
path: root/guilib/GUIControlGroupList.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'guilib/GUIControlGroupList.cpp')
-rw-r--r--guilib/GUIControlGroupList.cpp450
1 files changed, 0 insertions, 450 deletions
diff --git a/guilib/GUIControlGroupList.cpp b/guilib/GUIControlGroupList.cpp
deleted file mode 100644
index 0a370b880c..0000000000
--- a/guilib/GUIControlGroupList.cpp
+++ /dev/null
@@ -1,450 +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 "GUIControlGroupList.h"
-#include "Key.h"
-#include "utils/GUIInfoManager.h"
-#include "GUIControlProfiler.h"
-#include "GUIFont.h" // for XBFONT_* definitions
-
-CGUIControlGroupList::CGUIControlGroupList(int parentID, int controlID, float posX, float posY, float width, float height, float itemGap, int pageControl, ORIENTATION orientation, bool useControlPositions, uint32_t alignment, unsigned int scrollTime)
-: CGUIControlGroup(parentID, controlID, posX, posY, width, height)
-{
- m_itemGap = itemGap;
- m_pageControl = pageControl;
- m_offset = 0;
- m_totalSize = 10;
- m_orientation = orientation;
- m_alignment = alignment;
- m_scrollOffset = 0;
- m_scrollSpeed = 0;
- m_scrollLastTime = 0;
- m_scrollTime = scrollTime ? scrollTime : 1;
- m_renderTime = 0;
- m_useControlPositions = useControlPositions;
- ControlType = GUICONTROL_GROUPLIST;
-}
-
-CGUIControlGroupList::~CGUIControlGroupList(void)
-{
-}
-
-void CGUIControlGroupList::Render()
-{
- if (m_scrollSpeed != 0)
- {
- m_offset += m_scrollSpeed * (m_renderTime - 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 = m_renderTime;
-
- // 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
- bool render(g_graphicsContext.SetClipRegion(m_posX, m_posY, m_width, m_height));
- float pos = GetAlignOffset();
- 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;
- 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();
-}
-
-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->HasID(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_offset)
- ScrollTo(offset);
- else if (offset + Size(control) > m_offset + 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->HasID(m_focusedControl))
- {
- if (offset >= m_offset && offset + Size(control) <= m_offset + Size())
- 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() && offset >= m_offset && offset + Size(control) <= m_offset + Size())
- {
- 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);
-}
-
-void CGUIControlGroupList::ValidateOffset()
-{
- // calculate how many items we have on this page
- m_totalSize = 0;
- for (iControls it = m_children.begin(); it != m_children.end(); ++it)
- {
- CGUIControl *control = *it;
- if (!control->IsVisible()) continue;
- m_totalSize += Size(control) + m_itemGap;
- }
- if (m_totalSize > 0) m_totalSize -= m_itemGap;
- // check our m_offset range
- if (m_offset > m_totalSize - Size())
- m_offset = m_totalSize - Size();
- if (m_offset < 0) m_offset = 0;
-}
-
-void CGUIControlGroupList::AddControl(CGUIControl *control, int position /*= -1*/)
-{
- // NOTE: We override control navigation here, but we don't override the <onleft> etc. builtins
- // if specified.
- if (position < 0 || position > (int)m_children.size()) // add at the end
- position = (int)m_children.size();
-
- if (control)
- { // set the navigation of items so that they form a list
- int beforeID = (m_orientation == VERTICAL) ? GetControlIdUp() : GetControlIdLeft();
- int afterID = (m_orientation == VERTICAL) ? GetControlIdDown() : GetControlIdRight();
- if (m_children.size())
- {
- // we're inserting at the given position, so grab the items above and below and alter
- // their navigation accordingly
- CGUIControl *before = NULL;
- CGUIControl *after = NULL;
- if (position == 0)
- { // inserting at the beginning
- after = m_children[0];
- if (afterID == GetID()) // we're wrapping around bottom->top, so we have to update the last item
- before = m_children[m_children.size() - 1];
- if (beforeID == GetID()) // we're wrapping around top->bottom
- beforeID = m_children[m_children.size() - 1]->GetID();
- afterID = after->GetID();
- }
- else if (position == (int)m_children.size())
- { // inserting at the end
- before = m_children[m_children.size() - 1];
- if (beforeID == GetID()) // we're wrapping around top->bottom, so we have to update the first item
- after = m_children[0];
- if (afterID == GetID()) // we're wrapping around bottom->top
- afterID = m_children[0]->GetID();
- beforeID = before->GetID();
- }
- else
- { // inserting somewhere in the middle
- before = m_children[position - 1];
- after = m_children[position];
- beforeID = before->GetID();
- afterID = after->GetID();
- }
- if (m_orientation == VERTICAL)
- {
- if (before) // update the DOWN action to point to us
- before->SetNavigation(before->GetControlIdUp(), control->GetID(), GetControlIdLeft(), GetControlIdRight());
- if (after) // update the UP action to point to us
- after->SetNavigation(control->GetID(), after->GetControlIdDown(), GetControlIdLeft(), GetControlIdRight());
- }
- else
- {
- if (before) // update the RIGHT action to point to us
- before->SetNavigation(GetControlIdUp(), GetControlIdDown(), before->GetControlIdLeft(), control->GetID());
- if (after) // update the LEFT action to point to us
- after->SetNavigation(GetControlIdUp(), GetControlIdDown(), control->GetID(), after->GetControlIdRight());
- }
- }
- // now the control's nav
- std::vector<CGUIActionDescriptor> empty;
- if (m_orientation == VERTICAL)
- {
- control->SetNavigation(beforeID, afterID, GetControlIdLeft(), GetControlIdRight());
- control->SetNavigationActions(empty, empty, m_leftActions, m_rightActions, false);
- }
- else
- {
- control->SetNavigation(GetControlIdUp(), GetControlIdDown(), beforeID, afterID);
- control->SetNavigationActions(m_upActions, m_downActions, empty, empty, false);
- }
-
- if (!m_useControlPositions)
- control->SetPosition(0,0);
- CGUIControlGroup::AddControl(control, position);
- }
-}
-
-void CGUIControlGroupList::ClearAll()
-{
- CGUIControlGroup::ClearAll();
- m_offset = 0;
-}
-
-inline float CGUIControlGroupList::Size(const CGUIControl *control) const
-{
- return (m_orientation == VERTICAL) ? control->GetYPosition() + control->GetHeight() : control->GetXPosition() + control->GetWidth();
-}
-
-inline float CGUIControlGroupList::Size() const
-{
- return (m_orientation == VERTICAL) ? m_height : m_width;
-}
-
-void CGUIControlGroupList::ScrollTo(float offset)
-{
- m_scrollOffset = offset;
- m_scrollSpeed = (m_scrollOffset - m_offset) / m_scrollTime;
-}
-
-EVENT_RESULT CGUIControlGroupList::SendMouseEvent(const CPoint &point, const CMouseEvent &event)
-{
- // transform our position into child coordinates
- CPoint childPoint(point);
- m_transform.InverseTransformPosition(childPoint.x, childPoint.y);
- if (CGUIControl::CanFocus())
- {
- float pos = 0;
- float alignOffset = GetAlignOffset();
- for (ciControls i = m_children.begin(); i != m_children.end(); ++i)
- {
- CGUIControl *child = *i;
- if (child->IsVisible())
- {
- if (pos + Size(child) > m_offset && pos < m_offset + Size())
- { // we're on screen
- float offsetX = m_orientation == VERTICAL ? m_posX : m_posX + alignOffset + pos - m_offset;
- float offsetY = m_orientation == VERTICAL ? m_posY + alignOffset + pos - m_offset : m_posY;
- EVENT_RESULT ret = child->SendMouseEvent(childPoint - CPoint(offsetX, offsetY), event);
- if (ret)
- { // we've handled the action, and/or have focused an item
- return ret;
- }
- }
- pos += Size(child) + m_itemGap;
- }
- }
- // none of our children want the event, but we may want it.
- EVENT_RESULT ret;
- if (HitTest(childPoint) && (ret = OnMouseEvent(childPoint, event)))
- return ret;
- }
- m_focusedControl = 0;
- return EVENT_RESULT_UNHANDLED;
-}
-
-void CGUIControlGroupList::UnfocusFromPoint(const CPoint &point)
-{
- float pos = 0;
- CPoint controlCoords(point);
- m_transform.InverseTransformPosition(controlCoords.x, controlCoords.y);
- float alignOffset = GetAlignOffset();
- for (iControls it = m_children.begin(); it != m_children.end(); ++it)
- {
- CGUIControl *child = *it;
- if (child->IsVisible())
- {
- if (pos + Size(child) > m_offset && pos < m_offset + Size())
- { // we're on screen
- CPoint offset = (m_orientation == VERTICAL) ? CPoint(m_posX, m_posY + alignOffset + pos - m_offset) : CPoint(m_posX + alignOffset + pos - m_offset, m_posY);
- child->UnfocusFromPoint(controlCoords - offset);
- }
- pos += Size(child) + m_itemGap;
- }
- }
- CGUIControl::UnfocusFromPoint(point);
-}
-
-bool CGUIControlGroupList::GetCondition(int condition, int data) const
-{
- switch (condition)
- {
- case CONTAINER_HAS_NEXT:
- return (m_totalSize >= Size() && m_offset < m_totalSize - Size());
- case CONTAINER_HAS_PREVIOUS:
- return (m_offset > 0);
- default:
- return false;
- }
-}
-
-bool CGUIControlGroupList::IsFirstFocusableControl(const CGUIControl *control) const
-{
- for (ciControls it = m_children.begin(); it != m_children.end(); ++it)
- {
- CGUIControl *child = *it;
- if (child->IsVisible() && child->CanFocus())
- { // found first focusable
- return child == control;
- }
- }
- return false;
-}
-
-bool CGUIControlGroupList::IsLastFocusableControl(const CGUIControl *control) const
-{
- for (crControls it = m_children.rbegin(); it != m_children.rend(); ++it)
- {
- CGUIControl *child = *it;
- if (child->IsVisible() && child->CanFocus())
- { // found first focusable
- return child == control;
- }
- }
- return false;
-}
-
-float CGUIControlGroupList::GetAlignOffset() const
-{
- if (m_totalSize < Size())
- {
- if (m_alignment & XBFONT_RIGHT)
- return Size() - m_totalSize;
- if (m_alignment & XBFONT_CENTER_X)
- return (Size() - m_totalSize)*0.5f;
- }
- return 0.0f;
-}
-
-EVENT_RESULT CGUIControlGroupList::OnMouseEvent(const CPoint &point, const CMouseEvent &event)
-{
- if (event.m_id == ACTION_MOUSE_WHEEL_UP || event.m_id == ACTION_MOUSE_WHEEL_DOWN)
- {
- // find the current control and move to the next or previous
- float offset = 0;
- for (ciControls it = m_children.begin(); it != m_children.end(); ++it)
- {
- CGUIControl *control = *it;
- if (!control->IsVisible()) continue;
- float nextOffset = offset + Size(control) + m_itemGap;
- if (event.m_id == ACTION_MOUSE_WHEEL_DOWN && nextOffset > m_offset) // past our current offset
- {
- ScrollTo(nextOffset);
- return EVENT_RESULT_HANDLED;
- }
- else if (event.m_id == ACTION_MOUSE_WHEEL_UP && nextOffset >= m_offset) // at least at our current offset
- {
- ScrollTo(offset);
- return EVENT_RESULT_HANDLED;
- }
- offset = nextOffset;
- }
- }
- return EVENT_RESULT_UNHANDLED;
-}