aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--guilib/GUIControl.h24
-rw-r--r--guilib/GUIMessage.h4
-rw-r--r--guilib/GUIMoverControl.cpp30
-rw-r--r--guilib/GUIMoverControl.h3
-rw-r--r--guilib/GUIResizeControl.cpp30
-rw-r--r--guilib/GUIResizeControl.h3
-rw-r--r--guilib/GUIScrollBarControl.cpp46
-rw-r--r--guilib/GUIScrollBarControl.h6
-rw-r--r--guilib/GUISliderControl.cpp46
-rw-r--r--guilib/GUISliderControl.h6
-rw-r--r--guilib/GUIWindow.cpp43
-rw-r--r--guilib/GUIWindow.h2
-rw-r--r--xbmc/MouseStat.cpp11
-rw-r--r--xbmc/MouseStat.h6
14 files changed, 143 insertions, 117 deletions
diff --git a/guilib/GUIControl.h b/guilib/GUIControl.h
index 5a5d9f5107..67cdc51208 100644
--- a/guilib/GUIControl.h
+++ b/guilib/GUIControl.h
@@ -144,6 +144,18 @@ public:
*/
virtual bool SendMouseEvent(const CPoint &point, const CMouseEvent &event);
+ /*! \brief Perform a mouse action
+
+ Mouse actions are sent from the window to all controls, and each control can react based on the event
+ and location of the actions.
+
+ \param point the location in transformed skin coordinates from the upper left corner of the parent control.
+ \param event the mouse event to perform
+ \return true if the control has handled this event, false otherwise
+ \sa SendMouseEvent, HitTest, CanFocusFromPoint, CMouseEvent
+ */
+ virtual bool OnMouseEvent(const CPoint &point, const CMouseEvent &event);
+
/*! \brief Unfocus the control if the given point on screen is not within it's boundary
\param point the location in transformed skin coordinates from the upper left corner of the parent control.
\sa CanFocusFromPoint
@@ -287,18 +299,6 @@ public:
virtual void DumpTextureUse() {};
#endif
protected:
- /*! \brief Perform a mouse action
-
- Mouse actions are sent from the window to all controls, and each control can react based on the event
- and location of the actions.
-
- \param point the location in transformed skin coordinates from the upper left corner of the parent control.
- \param event the mouse event to perform
- \return true if the control has handled this event, false otherwise
- \sa SendMouseEvent, HitTest, CanFocusFromPoint, CMouseEvent
- */
- virtual bool OnMouseEvent(const CPoint &point, const CMouseEvent &event);
-
/*! \brief Test whether we can focus a control from a point on screen
\param point the location in vanilla skin coordinates from the upper left corner of the parent control.
\return true if the control can be focused from this location
diff --git a/guilib/GUIMessage.h b/guilib/GUIMessage.h
index 79242a5fca..7efca3ec93 100644
--- a/guilib/GUIMessage.h
+++ b/guilib/GUIMessage.h
@@ -107,6 +107,10 @@
*/
#define GUI_MSG_RENDERER_RESET 36
+/*!
+ \brief A control wishes to have (or release) exclusive access to mouse actions
+ */
+#define GUI_MSG_EXCLUSIVE_MOUSE 37
#define GUI_MSG_USER 1000
diff --git a/guilib/GUIMoverControl.cpp b/guilib/GUIMoverControl.cpp
index 7df5d1b8c0..8d305c316b 100644
--- a/guilib/GUIMoverControl.cpp
+++ b/guilib/GUIMoverControl.cpp
@@ -21,7 +21,6 @@
#include "GUIMoverControl.h"
#include "GUIWindowManager.h"
-#include "MouseStat.h"
#include "Key.h"
#include "utils/TimeUtils.h"
@@ -135,19 +134,24 @@ void CGUIMoverControl::OnRight()
Move((int)m_fSpeed, 0);
}
-bool CGUIMoverControl::OnMouseDrag(const CPoint &offset, const CPoint &point)
+bool CGUIMoverControl::OnMouseEvent(const CPoint &point, const CMouseEvent &event)
{
- g_Mouse.SetState(MOUSE_STATE_DRAG);
- g_Mouse.SetExclusiveAccess(this, GetParentID(), point);
- Move((int)offset.x, (int)offset.y);
- return true;
-}
-
-bool CGUIMoverControl::OnMouseClick(int button, const CPoint &point)
-{
- if (button != MOUSE_LEFT_BUTTON) return false;
- g_Mouse.EndExclusiveAccess(this, GetParentID());
- return true;
+ if (event.m_id == ACTION_MOUSE_DRAG)
+ {
+ if (event.m_state == 1)
+ { // grab exclusive access
+ CGUIMessage msg(GUI_MSG_EXCLUSIVE_MOUSE, GetID(), GetParentID());
+ SendWindowMessage(msg);
+ }
+ else if (event.m_state == 3)
+ { // release exclusive access
+ CGUIMessage msg(GUI_MSG_EXCLUSIVE_MOUSE, 0, GetParentID());
+ SendWindowMessage(msg);
+ }
+ Move((int)event.m_offsetX, (int)event.m_offsetY);
+ return true;
+ }
+ return false;
}
void CGUIMoverControl::UpdateSpeed(int nDirection)
diff --git a/guilib/GUIMoverControl.h b/guilib/GUIMoverControl.h
index 8c9b274f8e..562304c236 100644
--- a/guilib/GUIMoverControl.h
+++ b/guilib/GUIMoverControl.h
@@ -66,8 +66,6 @@ public:
virtual void OnDown();
virtual void OnLeft();
virtual void OnRight();
- virtual bool OnMouseDrag(const CPoint &offset, const CPoint &point);
- virtual bool OnMouseClick(int button, const CPoint &point);
virtual void AllocResources();
virtual void FreeResources();
virtual void DynamicResourceAlloc(bool bOnOff);
@@ -79,6 +77,7 @@ public:
int GetYLocation() const { return m_iLocationY;};
protected:
+ virtual bool OnMouseEvent(const CPoint &point, const CMouseEvent &event);
virtual void UpdateColors();
void SetAlpha(unsigned char alpha);
void UpdateSpeed(int nDirection);
diff --git a/guilib/GUIResizeControl.cpp b/guilib/GUIResizeControl.cpp
index 9849d92ef3..11de2b70be 100644
--- a/guilib/GUIResizeControl.cpp
+++ b/guilib/GUIResizeControl.cpp
@@ -21,7 +21,6 @@
#include "GUIResizeControl.h"
#include "GUIWindowManager.h"
-#include "MouseStat.h"
#include "Key.h"
#include "utils/TimeUtils.h"
@@ -124,19 +123,24 @@ void CGUIResizeControl::OnRight()
Resize(m_fSpeed, 0);
}
-bool CGUIResizeControl::OnMouseDrag(const CPoint &offset, const CPoint &point)
+bool CGUIResizeControl::OnMouseEvent(const CPoint &point, const CMouseEvent &event)
{
- g_Mouse.SetState(MOUSE_STATE_DRAG);
- g_Mouse.SetExclusiveAccess(this, GetParentID(), point);
- Resize(offset.x, offset.y);
- return true;
-}
-
-bool CGUIResizeControl::OnMouseClick(int button, const CPoint &point)
-{
- if (button != MOUSE_LEFT_BUTTON) return false;
- g_Mouse.EndExclusiveAccess(this, GetParentID());
- return true;
+ if (event.m_id == ACTION_MOUSE_DRAG)
+ {
+ if (event.m_state == 1)
+ { // grab exclusive access
+ CGUIMessage msg(GUI_MSG_EXCLUSIVE_MOUSE, GetID(), GetParentID());
+ SendWindowMessage(msg);
+ }
+ else if (event.m_state == 3)
+ { // release exclusive access
+ CGUIMessage msg(GUI_MSG_EXCLUSIVE_MOUSE, 0, GetParentID());
+ SendWindowMessage(msg);
+ }
+ Resize(event.m_offsetX, event.m_offsetY);
+ return true;
+ }
+ return false;
}
void CGUIResizeControl::UpdateSpeed(int nDirection)
diff --git a/guilib/GUIResizeControl.h b/guilib/GUIResizeControl.h
index 35a75fea6e..dfd78e5435 100644
--- a/guilib/GUIResizeControl.h
+++ b/guilib/GUIResizeControl.h
@@ -58,8 +58,6 @@ public:
virtual void OnDown();
virtual void OnLeft();
virtual void OnRight();
- virtual bool OnMouseDrag(const CPoint &offset, const CPoint &point);
- virtual bool OnMouseClick(int button, const CPoint &point);
virtual void AllocResources();
virtual void FreeResources();
virtual void DynamicResourceAlloc(bool bOnOff);
@@ -68,6 +66,7 @@ public:
void SetLimits(float x1, float y1, float x2, float y2);
protected:
+ virtual bool OnMouseEvent(const CPoint &point, const CMouseEvent &event);
virtual void UpdateColors();
void SetAlpha(unsigned char alpha);
void UpdateSpeed(int nDirection);
diff --git a/guilib/GUIScrollBarControl.cpp b/guilib/GUIScrollBarControl.cpp
index 36f866c362..7bab89df70 100644
--- a/guilib/GUIScrollBarControl.cpp
+++ b/guilib/GUIScrollBarControl.cpp
@@ -20,7 +20,6 @@
*/
#include "GUIScrollBarControl.h"
-#include "MouseStat.h"
#include "Key.h"
#define MIN_NIB_SIZE 4.0f
@@ -265,35 +264,36 @@ void CGUIScrollBar::SetFromPosition(const CPoint &point)
SetInvalid();
}
-bool CGUIScrollBar::OnMouseClick(int button, const CPoint &point)
+bool CGUIScrollBar::OnMouseEvent(const CPoint &point, const CMouseEvent &event)
{
- g_Mouse.SetState(MOUSE_STATE_CLICK);
- // turn off any exclusive access, if it's on...
- g_Mouse.EndExclusiveAccess(this, GetParentID());
- if (m_guiBackground.HitTest(point))
- { // set the position
+ if (event.m_id == ACTION_MOUSE_DRAG)
+ {
+ if (event.m_state == 1)
+ { // we want exclusive access
+ CGUIMessage msg(GUI_MSG_EXCLUSIVE_MOUSE, GetID(), GetParentID());
+ SendWindowMessage(msg);
+ }
+ else if (event.m_state == 3)
+ { // we're done with exclusive access
+ CGUIMessage msg(GUI_MSG_EXCLUSIVE_MOUSE, 0, GetParentID());
+ SendWindowMessage(msg);
+ }
+ SetFromPosition(point);
+ return true;
+ }
+ else if (event.m_id == ACTION_MOUSE_CLICK && m_guiBackground.HitTest(point))
+ {
SetFromPosition(point);
return true;
}
+ else if (event.m_id == ACTION_MOUSE_WHEEL)
+ {
+ Move(-event.m_wheel);
+ return true;
+ }
return false;
}
-bool CGUIScrollBar::OnMouseDrag(const CPoint &offset, const CPoint &point)
-{
- g_Mouse.SetState(MOUSE_STATE_DRAG);
- // get exclusive access to the mouse
- g_Mouse.SetExclusiveAccess(this, GetParentID(), point);
- // get the position of the mouse
- SetFromPosition(point);
- return true;
-}
-
-bool CGUIScrollBar::OnMouseWheel(char wheel, const CPoint &point)
-{
- Move(-wheel);
- return true;
-}
-
CStdString CGUIScrollBar::GetDescription() const
{
CStdString description;
diff --git a/guilib/GUIScrollBarControl.h b/guilib/GUIScrollBarControl.h
index 4ade26d3e1..562006949e 100644
--- a/guilib/GUIScrollBarControl.h
+++ b/guilib/GUIScrollBarControl.h
@@ -59,13 +59,11 @@ public:
virtual bool OnMessage(CGUIMessage& message);
void SetValue(int value);
int GetValue() const;
- virtual bool HitTest(const CPoint &point) const;
- virtual bool OnMouseClick(int button, const CPoint &point);
- virtual bool OnMouseDrag(const CPoint &offset, const CPoint &point);
- virtual bool OnMouseWheel(char wheel, const CPoint &point);
virtual CStdString GetDescription() const;
virtual bool IsVisible() const;
protected:
+ virtual bool HitTest(const CPoint &point) const;
+ virtual bool OnMouseEvent(const CPoint &point, const CMouseEvent &event);
virtual void UpdateColors();
void UpdateBarSize();
virtual void Move(int iNumSteps);
diff --git a/guilib/GUISliderControl.cpp b/guilib/GUISliderControl.cpp
index a3a3a7a5e1..d4f2cb8938 100644
--- a/guilib/GUISliderControl.cpp
+++ b/guilib/GUISliderControl.cpp
@@ -21,7 +21,6 @@
#include "GUISliderControl.h"
#include "utils/GUIInfoManager.h"
-#include "MouseStat.h"
#include "Key.h"
CGUISliderControl::CGUISliderControl(int parentID, int controlID, float posX, float posY, float width, float height, const CTextureInfo& backGroundTexture, const CTextureInfo& nibTexture, const CTextureInfo& nibTextureFocus, int iType)
@@ -312,35 +311,36 @@ void CGUISliderControl::SetFromPosition(const CPoint &point)
SEND_CLICK_MESSAGE(GetID(), GetParentID(), 0);
}
-bool CGUISliderControl::OnMouseClick(int button, const CPoint &point)
+bool CGUISliderControl::OnMouseEvent(const CPoint &point, const CMouseEvent &event)
{
- g_Mouse.SetState(MOUSE_STATE_CLICK);
- // turn off any exclusive access, if it's on...
- g_Mouse.EndExclusiveAccess(this, GetParentID());
- if (m_guiBackground.HitTest(point))
- { // set the position
+ if (event.m_id == ACTION_MOUSE_DRAG)
+ {
+ if (event.m_state == 1)
+ { // grab exclusive access
+ CGUIMessage msg(GUI_MSG_EXCLUSIVE_MOUSE, GetID(), GetParentID());
+ SendWindowMessage(msg);
+ }
+ else if (event.m_state == 3)
+ { // release exclusive access
+ CGUIMessage msg(GUI_MSG_EXCLUSIVE_MOUSE, 0, GetParentID());
+ SendWindowMessage(msg);
+ }
+ SetFromPosition(point);
+ return true;
+ }
+ else if (event.m_id == ACTION_MOUSE_CLICK && m_guiBackground.HitTest(point))
+ {
SetFromPosition(point);
return true;
}
+ else if (event.m_id == ACTION_MOUSE_WHEEL)
+ {
+ Move(event.m_wheel*10);
+ return true;
+ }
return false;
}
-bool CGUISliderControl::OnMouseDrag(const CPoint &offset, const CPoint &point)
-{
- g_Mouse.SetState(MOUSE_STATE_DRAG);
- // get exclusive access to the mouse
- g_Mouse.SetExclusiveAccess(this, GetParentID(), point);
- // get the position of the mouse
- SetFromPosition(point);
- return true;
-}
-
-bool CGUISliderControl::OnMouseWheel(char wheel, const CPoint &point)
-{ // move the slider 10 steps in the appropriate direction
- Move(wheel*10);
- return true;
-}
-
void CGUISliderControl::SetInfo(int iInfo)
{
m_iInfoCode = iInfo;
diff --git a/guilib/GUISliderControl.h b/guilib/GUISliderControl.h
index 3008cbf977..7a90475c53 100644
--- a/guilib/GUISliderControl.h
+++ b/guilib/GUISliderControl.h
@@ -66,13 +66,11 @@ public:
float GetFloatValue() const;
void SetFloatInterval(float fInterval);
void SetType(int iType) { m_iType = iType; };
- virtual bool HitTest(const CPoint &point) const;
- virtual bool OnMouseClick(int button, const CPoint &point);
- virtual bool OnMouseDrag(const CPoint &offset, const CPoint &point);
- virtual bool OnMouseWheel(char wheel, const CPoint &point);
virtual CStdString GetDescription() const;
void SetTextValue(const CStdString &textValue) { m_textValue = textValue; };
protected:
+ virtual bool HitTest(const CPoint &point) const;
+ virtual bool OnMouseEvent(const CPoint &point, const CMouseEvent &event);
virtual void UpdateColors();
virtual void Move(int iNumSteps);
virtual void SetFromPosition(const CPoint &point);
diff --git a/guilib/GUIWindow.cpp b/guilib/GUIWindow.cpp
index 1b152a7ea2..df643f540e 100644
--- a/guilib/GUIWindow.cpp
+++ b/guilib/GUIWindow.cpp
@@ -65,6 +65,7 @@ CGUIWindow::CGUIWindow(int id, const CStdString &xmlFile)
m_previousWindow = WINDOW_INVALID;
m_animationsEnabled = true;
m_manualRunActions = false;
+ m_exclusiveMouseControl = 0;
}
CGUIWindow::~CGUIWindow(void)
@@ -368,28 +369,34 @@ bool CGUIWindow::OnMouseAction()
CPoint mousePoint(g_Mouse.GetLocation());
g_graphicsContext.InvertFinalCoords(mousePoint.x, mousePoint.y);
- UnfocusFromPoint(mousePoint);
-
// create the mouse event
- CMouseEvent *event = NULL;
+ CMouseEvent event(0); // mouse move only
if (g_Mouse.bClick[MOUSE_LEFT_BUTTON])
- event = new CMouseEvent(ACTION_MOUSE_LEFT_CLICK);
+ event = CMouseEvent(ACTION_MOUSE_LEFT_CLICK);
else if (g_Mouse.bClick[MOUSE_RIGHT_BUTTON])
- event = new CMouseEvent(ACTION_MOUSE_RIGHT_CLICK);
+ event = CMouseEvent(ACTION_MOUSE_RIGHT_CLICK);
else if (g_Mouse.bClick[MOUSE_MIDDLE_BUTTON])
- event = new CMouseEvent(ACTION_MOUSE_MIDDLE_CLICK);
+ event = CMouseEvent(ACTION_MOUSE_MIDDLE_CLICK);
else if (g_Mouse.bDoubleClick[MOUSE_LEFT_BUTTON])
- event = new CMouseEvent(ACTION_MOUSE_DOUBLE_CLICK);
- else if (g_Mouse.bHold[MOUSE_LEFT_BUTTON] && g_Mouse.HasMoved(true))
- event = new CMouseEvent(ACTION_MOUSE_DRAG, 0, g_Mouse.GetLastMove().x, g_Mouse.GetLastMove().y);
+ event = CMouseEvent(ACTION_MOUSE_DOUBLE_CLICK);
+ else if (g_Mouse.bHold[MOUSE_LEFT_BUTTON])
+ event = CMouseEvent(ACTION_MOUSE_DRAG, g_Mouse.bHold[MOUSE_LEFT_BUTTON], 0, g_Mouse.GetLastMove().x, g_Mouse.GetLastMove().y);
else if (g_Mouse.GetWheel())
- event = new CMouseEvent(ACTION_MOUSE_WHEEL, g_Mouse.GetWheel());
- else
- event = new CMouseEvent(0); // mouse move only
+ event = CMouseEvent(ACTION_MOUSE_WHEEL, 0, g_Mouse.GetWheel());
+
+ if (m_exclusiveMouseControl)
+ {
+ CGUIControl *child = (CGUIControl *)GetControl(m_exclusiveMouseControl);
+ if (child)
+ {
+ CPoint renderPos = child->GetRenderPosition() - CPoint(child->GetXPosition(), child->GetYPosition());
+ return child->OnMouseEvent(mousePoint - renderPos, event);
+ }
+ }
+
+ UnfocusFromPoint(mousePoint);
- bool handled = SendMouseEvent(mousePoint, *event);
- delete event;
- return handled;
+ return SendMouseEvent(mousePoint, event);
}
bool CGUIWindow::OnMouseEvent(const CPoint &point, const CMouseEvent &event)
@@ -556,6 +563,12 @@ bool CGUIWindow::OnMessage(CGUIMessage& message)
return true;
}
break;
+ case GUI_MSG_EXCLUSIVE_MOUSE:
+ {
+ m_exclusiveMouseControl = message.GetSenderId();
+ return true;
+ }
+ break;
case GUI_MSG_NOTIFY_ALL:
{
// only process those notifications that come from this window, or those intended for every window
diff --git a/guilib/GUIWindow.h b/guilib/GUIWindow.h
index 44edb64e7d..db5b275ffb 100644
--- a/guilib/GUIWindow.h
+++ b/guilib/GUIWindow.h
@@ -244,6 +244,8 @@ protected:
std::vector<CGUIActionDescriptor> m_unloadActions;
bool m_manualRunActions;
+
+ int m_exclusiveMouseControl; ///< \brief id of child control that wishes to receive all mouse events \sa GUI_MSG_EXCLUSIVE_MOUSE
};
#endif
diff --git a/xbmc/MouseStat.cpp b/xbmc/MouseStat.cpp
index 92b4315290..617d23b015 100644
--- a/xbmc/MouseStat.cpp
+++ b/xbmc/MouseStat.cpp
@@ -48,8 +48,9 @@ CMouseStat::CButtonState::BUTTON_ACTION CMouseStat::CButtonState::Update(unsigne
if (m_state == STATE_IN_DRAG)
{
if (down)
- return MB_DRAG;
+ return MB_DRAG;
m_state = STATE_RELEASED;
+ return MB_DRAG_END;
}
else if (m_state == STATE_RELEASED)
{
@@ -68,7 +69,7 @@ CMouseStat::CButtonState::BUTTON_ACTION CMouseStat::CButtonState::Update(unsigne
if (!InClickRange(x,y))
{ // beginning a drag
m_state = STATE_IN_DRAG;
- return MB_DRAG;
+ return MB_DRAG_START;
}
}
else
@@ -184,7 +185,7 @@ void CMouseStat::UpdateInternal()
{
bClick[i] = false;
bDoubleClick[i] = false;
- bHold[i] = false;
+ bHold[i] = 0;
CButtonState::BUTTON_ACTION action = m_buttonState[i].Update(now, m_mouseState.x, m_mouseState.y, m_mouseState.button[i]);
switch (action)
@@ -198,8 +199,10 @@ void CMouseStat::UpdateInternal()
bDoubleClick[i] = true;
bNothingDown = false;
break;
+ case CButtonState::MB_DRAG_START:
case CButtonState::MB_DRAG:
- bHold[i] = true;
+ case CButtonState::MB_DRAG_END:
+ bHold[i] = action - CButtonState::MB_DRAG_START + 1;
bNothingDown = false;
break;
default:
diff --git a/xbmc/MouseStat.h b/xbmc/MouseStat.h
index 45c04da775..4007e3aace 100644
--- a/xbmc/MouseStat.h
+++ b/xbmc/MouseStat.h
@@ -115,7 +115,9 @@ private:
MB_SHORT_CLICK, ///< a short click has occurred (a double click may be in process)
MB_LONG_CLICK, ///< a long click has occurred
MB_DOUBLE_CLICK, ///< a double click has occurred
- MB_DRAG }; ///< a drag action has occurred
+ MB_DRAG_START, ///< a drag action has started
+ MB_DRAG, ///< a drag action is in progress
+ MB_DRAG_END }; ///< a drag action has finished
CButtonState();
@@ -177,7 +179,7 @@ public:
// public access variables to button clicks etc.
bool bClick[5];
bool bDoubleClick[5];
- bool bHold[5];
+ int bHold[5];
};
extern CMouseStat g_Mouse;