aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjmarshallnz <jmarshallnz@svn>2010-01-08 04:51:50 +0000
committerjmarshallnz <jmarshallnz@svn>2010-01-08 04:51:50 +0000
commit91d92b85b573359c2ba6e99f5e0c3203e41431b5 (patch)
treefd3bec6eff026209937ecd1c7cfd42cf8899656d
parent04f2f7f645644e7816b326833a7b2f0f2c5d82e6 (diff)
cleanup: Changed the way controls are selected for focus under the mouse pointer. Fixes potential issues with control groups ignoring anything other than the first possibly focusable control when passing mouse actions.
git-svn-id: https://xbmc.svn.sourceforge.net/svnroot/xbmc/trunk@26534 568bbfeb-2a22-0410-94d2-cc84cf5bfa90
-rw-r--r--guilib/GUIControl.cpp8
-rw-r--r--guilib/GUIControl.h16
-rw-r--r--guilib/GUIControlGroup.cpp15
-rw-r--r--guilib/GUIControlGroup.h2
-rw-r--r--guilib/GUIControlGroupList.cpp15
-rw-r--r--guilib/GUIControlGroupList.h2
-rw-r--r--guilib/GUIVideoControl.cpp12
-rw-r--r--guilib/GUIVideoControl.h2
-rw-r--r--guilib/GUIVisualisationControl.cpp12
-rw-r--r--guilib/GUIVisualisationControl.h2
-rw-r--r--guilib/GUIWindow.cpp23
11 files changed, 51 insertions, 58 deletions
diff --git a/guilib/GUIControl.cpp b/guilib/GUIControl.cpp
index b573201568..e9611a2764 100644
--- a/guilib/GUIControl.cpp
+++ b/guilib/GUIControl.cpp
@@ -812,18 +812,12 @@ int CGUIControl::GetNextControl(int direction) const
}
}
-// input the point with respect to this control to hit, and return
-// the control and the point with respect to his control if we have a hit
-bool CGUIControl::CanFocusFromPoint(const CPoint &point, CGUIControl **control, CPoint &controlPoint) const
+bool CGUIControl::CanFocusFromPoint(const CPoint &point, CPoint &controlPoint) const
{
controlPoint = point;
m_transform.InverseTransformPosition(controlPoint.x, controlPoint.y);
if (CanFocus() && HitTest(controlPoint))
- {
- *control = (CGUIControl *)this;
return true;
- }
- *control = NULL;
return false;
}
diff --git a/guilib/GUIControl.h b/guilib/GUIControl.h
index 6873da8971..6cc6783be4 100644
--- a/guilib/GUIControl.h
+++ b/guilib/GUIControl.h
@@ -132,9 +132,19 @@ public:
virtual bool OnMouseWheel(char wheel, const CPoint &point) { return false; };
/// \brief Used to test whether the pointer location (fPosX, fPosY) is inside the control. For mouse events.
virtual bool HitTest(const CPoint &point) const;
- /// \brief Focus a control from a screen location. Returns the coordinates of the screen location relative to the control and a pointer to the control.
- virtual bool CanFocusFromPoint(const CPoint &point, CGUIControl **control, CPoint &controlPoint) const;
- /// \brief Unfocus a control if it's not in a screen location.
+
+ /*! \brief Test whether we can focus a control from a point on screen
+ \param point the location in skin coordinates from the upper left corner of the parent control.
+ \param controlPoint [OUT] the location in skin coordinates that will yield the given point on screen under this controls transformation
+ \return true if the control can be focused from this location
+ \sa UnfocusFromPoint
+ */
+ virtual bool CanFocusFromPoint(const CPoint &point, CPoint &controlPoint) const;
+
+ /*! \brief Unfocus the control if the given point on screen is not within it's boundary
+ \param point the location in skin coordinates from the upper left corner of the parent control.
+ \sa CanFocusFromPoint
+ */
virtual void UnfocusFromPoint(const CPoint &point);
virtual bool OnMessage(CGUIMessage& message);
diff --git a/guilib/GUIControlGroup.cpp b/guilib/GUIControlGroup.cpp
index 3ddb3517d8..a87700169d 100644
--- a/guilib/GUIControlGroup.cpp
+++ b/guilib/GUIControlGroup.cpp
@@ -367,19 +367,22 @@ bool CGUIControlGroup::HitTest(const CPoint &point) const
return false;
}
-bool CGUIControlGroup::CanFocusFromPoint(const CPoint &point, CGUIControl **control, CPoint &controlPoint) const
+void CGUIControlGroup::GetControlsFromPoint(const CPoint &point, vector< std::pair<CGUIControl *, CPoint> > &controls) const
{
- if (!CGUIControl::CanFocus()) return false;
+ if (!CGUIControl::CanFocus())
+ return;
CPoint controlCoords(point);
m_transform.InverseTransformPosition(controlCoords.x, controlCoords.y);
+ controlCoords -= CPoint(m_posX, m_posY);
for (crControls it = m_children.rbegin(); it != m_children.rend(); ++it)
{
CGUIControl *child = *it;
- if (child->CanFocusFromPoint(controlCoords - CPoint(m_posX, m_posY), control, controlPoint))
- return true;
+ CPoint childCoords;
+ if (child->IsGroup())
+ ((CGUIControlGroup *)child)->GetControlsFromPoint(controlCoords, controls);
+ else if (child->CanFocusFromPoint(controlCoords, childCoords))
+ controls.push_back(make_pair(child, childCoords));
}
- *control = NULL;
- return false;
}
void CGUIControlGroup::UnfocusFromPoint(const CPoint &point)
diff --git a/guilib/GUIControlGroup.h b/guilib/GUIControlGroup.h
index 1567fe4b33..8fd14fcb8f 100644
--- a/guilib/GUIControlGroup.h
+++ b/guilib/GUIControlGroup.h
@@ -52,7 +52,7 @@ public:
virtual bool CanFocus() const;
virtual bool HitTest(const CPoint &point) const;
- virtual bool CanFocusFromPoint(const CPoint &point, CGUIControl **control, CPoint &controlPoint) const;
+ virtual void GetControlsFromPoint(const CPoint &point, std::vector< std::pair<CGUIControl *, CPoint> > &controls) const;
virtual void UnfocusFromPoint(const CPoint &point);
virtual void SetInitialVisibility();
diff --git a/guilib/GUIControlGroupList.cpp b/guilib/GUIControlGroupList.cpp
index b339fa5da6..4670af2afc 100644
--- a/guilib/GUIControlGroupList.cpp
+++ b/guilib/GUIControlGroupList.cpp
@@ -311,30 +311,31 @@ void CGUIControlGroupList::ScrollTo(float offset)
m_scrollSpeed = (m_scrollOffset - m_offset) / m_scrollTime;
}
-bool CGUIControlGroupList::CanFocusFromPoint(const CPoint &point, CGUIControl **control, CPoint &controlPoint) const
+void CGUIControlGroupList::GetControlsFromPoint(const CPoint &point, std::vector< std::pair<CGUIControl *, CPoint> > &controls) const
{
- if (!CGUIControl::CanFocus()) return false;
+ if (!CGUIControl::CanFocus()) return;
float pos = 0;
CPoint controlCoords(point);
m_transform.InverseTransformPosition(controlCoords.x, controlCoords.y);
float alignOffset = GetAlignOffset();
for (ciControls it = m_children.begin(); it != m_children.end(); ++it)
{
- const CGUIControl *child = *it;
+ CGUIControl *child = *it;
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;
- if (child->CanFocusFromPoint(controlCoords - CPoint(offsetX, offsetY), control, controlPoint))
- return true;
+ CPoint childCoords;
+ if (child->IsGroup())
+ ((CGUIControlGroup *)child)->GetControlsFromPoint(controlCoords - CPoint(offsetX, offsetY), controls);
+ else if (child->CanFocusFromPoint(controlCoords - CPoint(offsetX, offsetY), childCoords))
+ controls.push_back(std::make_pair(child, childCoords));
}
pos += Size(child) + m_itemGap;
}
}
- *control = NULL;
- return false;
}
void CGUIControlGroupList::UnfocusFromPoint(const CPoint &point)
diff --git a/guilib/GUIControlGroupList.h b/guilib/GUIControlGroupList.h
index 90ccc45569..bb34960ae8 100644
--- a/guilib/GUIControlGroupList.h
+++ b/guilib/GUIControlGroupList.h
@@ -41,7 +41,7 @@ public:
virtual void Render();
virtual bool OnMessage(CGUIMessage& message);
- virtual bool CanFocusFromPoint(const CPoint &point, CGUIControl **control, CPoint &controlPoint) const;
+ virtual void GetControlsFromPoint(const CPoint &point, std::vector< std::pair<CGUIControl *, CPoint> > &controls) const;
virtual void UnfocusFromPoint(const CPoint &point);
virtual void AddControl(CGUIControl *control, int position = -1);
diff --git a/guilib/GUIVideoControl.cpp b/guilib/GUIVideoControl.cpp
index ff4616910c..f9e8c57818 100644
--- a/guilib/GUIVideoControl.cpp
+++ b/guilib/GUIVideoControl.cpp
@@ -92,7 +92,7 @@ bool CGUIVideoControl::OnMouseClick(int button, const CPoint &point)
bool CGUIVideoControl::OnMouseOver(const CPoint &point)
{
- // unfocusable, so return true
+ // unfocusable, so return false
CGUIControl::OnMouseOver(point);
return false;
}
@@ -102,15 +102,9 @@ bool CGUIVideoControl::CanFocus() const
return false;
}
-bool CGUIVideoControl::CanFocusFromPoint(const CPoint &point, CGUIControl **control, CPoint &controlPoint) const
+bool CGUIVideoControl::CanFocusFromPoint(const CPoint &point, CPoint &controlPoint) const
{ // mouse is allowed to focus this control, but it doesn't actually receive focus
controlPoint = point;
m_transform.InverseTransformPosition(controlPoint.x, controlPoint.y);
- if (HitTest(controlPoint))
- {
- *control = (CGUIControl *)this;
- return true;
- }
- *control = NULL;
- return false;
+ return HitTest(controlPoint);
}
diff --git a/guilib/GUIVideoControl.h b/guilib/GUIVideoControl.h
index ef82527b66..0fffcb77e2 100644
--- a/guilib/GUIVideoControl.h
+++ b/guilib/GUIVideoControl.h
@@ -47,6 +47,6 @@ public:
virtual bool OnMouseClick(int button, const CPoint &point);
virtual bool OnMouseOver(const CPoint &point);
virtual bool CanFocus() const;
- virtual bool CanFocusFromPoint(const CPoint &point, CGUIControl **control, CPoint &controlPoint) const;
+ virtual bool CanFocusFromPoint(const CPoint &point, CPoint &controlPoint) const;
};
#endif
diff --git a/guilib/GUIVisualisationControl.cpp b/guilib/GUIVisualisationControl.cpp
index 3e388519a7..1ea4a4a1ab 100644
--- a/guilib/GUIVisualisationControl.cpp
+++ b/guilib/GUIVisualisationControl.cpp
@@ -466,7 +466,7 @@ CVisualisation *CGUIVisualisationControl::GetVisualisation()
bool CGUIVisualisationControl::OnMouseOver(const CPoint &point)
{
- // unfocusable, so return true
+ // unfocusable, so return false
CGUIControl::OnMouseOver(point);
return false;
}
@@ -476,15 +476,9 @@ bool CGUIVisualisationControl::CanFocus() const
return false;
}
-bool CGUIVisualisationControl::CanFocusFromPoint(const CPoint &point, CGUIControl **control, CPoint &controlPoint) const
+bool CGUIVisualisationControl::CanFocusFromPoint(const CPoint &point, CPoint &controlPoint) const
{ // mouse is allowed to focus this control, but it doesn't actually receive focus
controlPoint = point;
m_transform.InverseTransformPosition(controlPoint.x, controlPoint.y);
- if (HitTest(controlPoint))
- {
- *control = (CGUIControl *)this;
- return true;
- }
- *control = NULL;
- return false;
+ return HitTest(controlPoint);
}
diff --git a/guilib/GUIVisualisationControl.h b/guilib/GUIVisualisationControl.h
index e9454a1225..b76ea5426f 100644
--- a/guilib/GUIVisualisationControl.h
+++ b/guilib/GUIVisualisationControl.h
@@ -64,7 +64,7 @@ public:
virtual bool OnMessage(CGUIMessage& message);
virtual bool OnMouseOver(const CPoint &point);
virtual bool CanFocus() const;
- virtual bool CanFocusFromPoint(const CPoint &point, CGUIControl **control, CPoint &controlPoint) const;
+ virtual bool CanFocusFromPoint(const CPoint &point, CPoint &controlPoint) const;
CVisualisation *GetVisualisation();
private:
diff --git a/guilib/GUIWindow.cpp b/guilib/GUIWindow.cpp
index 9f84197c50..fb6830178b 100644
--- a/guilib/GUIWindow.cpp
+++ b/guilib/GUIWindow.cpp
@@ -397,21 +397,18 @@ bool CGUIWindow::OnMouseAction()
CGUIControl *pControl = *i;
pControl->UnfocusFromPoint(mousePoint);
}
- // and find which one is under the pointer
- // go through in reverse order to make sure we start with the ones on top
+ // and find which ones are under the pointer
+ vector< pair<CGUIControl *, CPoint> > controls;
+ GetControlsFromPoint(mousePoint, controls);
+
bool controlUnderPointer(false);
- for (vector<CGUIControl *>::reverse_iterator i = m_children.rbegin(); i != m_children.rend(); ++i)
+ for (vector< pair<CGUIControl *, CPoint> >::iterator i = controls.begin(); i != controls.end(); ++i)
{
- CGUIControl *pControl = *i;
- CGUIControl *focusableControl = NULL;
- CPoint controlPoint;
- if (pControl->CanFocusFromPoint(mousePoint, &focusableControl, controlPoint))
- {
- controlUnderPointer = focusableControl->OnMouseOver(controlPoint);
- bHandled = HandleMouse(focusableControl, controlPoint);
- if (bHandled || controlUnderPointer)
- break;
- }
+ CGUIControl *child = i->first;
+ controlUnderPointer = child->OnMouseOver(i->second);
+ bHandled = HandleMouse(child, i->second);
+ if (bHandled || controlUnderPointer)
+ break;
}
if (!bHandled)
{ // haven't handled this action - call the window message handlers