Support mouse position locking in menus UI

Support locking mouse position when dragging value selectors also in menus (color pickers), which improves usability of value selectors.

Previously this was only supported in the editor.

When enabling locked mouse a UI element ID must be specified. The mouse lock is stopped when this element is no longer active. This ensures that the mouse doesn't gets stuck in this state when the value selector isn't active anymore.
This commit is contained in:
Robert Müller 2023-06-04 12:46:07 +02:00
parent ef217b69c9
commit 938c57e03a
4 changed files with 42 additions and 28 deletions

View file

@ -181,8 +181,12 @@ void CUI::OnLanguageChange()
void CUI::OnCursorMove(float X, float Y)
{
m_UpdatedMousePos.x = clamp(m_UpdatedMousePos.x + X, 0.0f, (float)Graphics()->WindowWidth());
m_UpdatedMousePos.y = clamp(m_UpdatedMousePos.y + Y, 0.0f, (float)Graphics()->WindowHeight());
if(!CheckMouseLock())
{
m_UpdatedMousePos.x = clamp(m_UpdatedMousePos.x + X, 0.0f, (float)Graphics()->WindowWidth());
m_UpdatedMousePos.y = clamp(m_UpdatedMousePos.y + Y, 0.0f, (float)Graphics()->WindowHeight());
}
m_UpdatedMouseDelta += vec2(X, Y);
}
@ -957,8 +961,6 @@ int CUI::DoButton_PopupMenu(CButtonContainer *pButtonContainer, const char *pTex
int64_t CUI::DoValueSelector(const void *pID, const CUIRect *pRect, const char *pLabel, int64_t Current, int64_t Min, int64_t Max, const SValueSelectorProperties &Props)
{
// TODO: reimplement m_LockMouse
// logic
static float s_Value;
static CLineInputNumber s_NumberInput;
@ -982,7 +984,7 @@ int64_t CUI::DoValueSelector(const void *pID, const CUIRect *pRect, const char *
{
if(!MouseButton(0))
{
//m_LockMouse = false;
DisableMouseLock();
SetActiveItem(nullptr);
m_ValueSelectorTextMode = false;
}
@ -996,14 +998,14 @@ int64_t CUI::DoValueSelector(const void *pID, const CUIRect *pRect, const char *
if(ConsumeHotkey(HOTKEY_ENTER) || ((MouseButtonClicked(1) || MouseButtonClicked(0)) && !Inside))
{
Current = clamp(s_NumberInput.GetInteger64(Base), Min, Max);
//m_LockMouse = false;
DisableMouseLock();
SetActiveItem(nullptr);
m_ValueSelectorTextMode = false;
}
if(ConsumeHotkey(HOTKEY_ESCAPE))
{
//m_LockMouse = false;
DisableMouseLock();
SetActiveItem(nullptr);
m_ValueSelectorTextMode = false;
}
@ -1038,9 +1040,10 @@ int64_t CUI::DoValueSelector(const void *pID, const CUIRect *pRect, const char *
{
if(MouseButtonClicked(0))
{
//m_LockMouse = true;
s_Value = 0;
SetActiveItem(pID);
if(Props.m_UseScroll)
EnableMouseLock(pID);
}
}

View file

@ -303,6 +303,8 @@ private:
unsigned m_MouseButtons;
unsigned m_LastMouseButtons;
bool m_MouseSlow = false;
bool m_MouseLock = false;
const void *m_pMouseLockID = nullptr;
unsigned m_HotkeysPressed = 0;
@ -399,6 +401,18 @@ public:
int MouseButton(int Index) const { return (m_MouseButtons >> Index) & 1; }
int MouseButtonClicked(int Index) const { return MouseButton(Index) && !((m_LastMouseButtons >> Index) & 1); }
int MouseButtonReleased(int Index) const { return ((m_LastMouseButtons >> Index) & 1) && !MouseButton(Index); }
bool CheckMouseLock()
{
if(m_MouseLock && ActiveItem() != m_pMouseLockID)
DisableMouseLock();
return m_MouseLock;
}
void EnableMouseLock(const void *pID)
{
m_MouseLock = true;
m_pMouseLockID = pID;
}
void DisableMouseLock() { m_MouseLock = false; }
void SetHotItem(const void *pID) { m_pBecomingHotItem = pID; }
void SetActiveItem(const void *pID)

View file

@ -586,7 +586,7 @@ int CEditor::UiDoValueSelector(void *pID, CUIRect *pRect, const char *pLabel, in
{
s_pLastTextID = pID;
s_TextMode = true;
m_LockMouse = false;
UI()->DisableMouseLock();
s_NumberInput.SetInteger(Current, Base);
}
@ -594,7 +594,7 @@ int CEditor::UiDoValueSelector(void *pID, CUIRect *pRect, const char *pLabel, in
{
if(!UI()->MouseButton(0))
{
m_LockMouse = false;
UI()->DisableMouseLock();
UI()->SetActiveItem(nullptr);
s_TextMode = false;
}
@ -612,14 +612,14 @@ int CEditor::UiDoValueSelector(void *pID, CUIRect *pRect, const char *pLabel, in
((UI()->MouseButton(1) || UI()->MouseButton(0)) && !Inside))
{
Current = clamp(s_NumberInput.GetInteger(Base), Min, Max);
m_LockMouse = false;
UI()->DisableMouseLock();
UI()->SetActiveItem(nullptr);
s_TextMode = false;
}
if(Input()->KeyIsPressed(KEY_ESCAPE))
{
m_LockMouse = false;
UI()->DisableMouseLock();
UI()->SetActiveItem(nullptr);
s_TextMode = false;
}
@ -656,9 +656,9 @@ int CEditor::UiDoValueSelector(void *pID, CUIRect *pRect, const char *pLabel, in
{
if(UI()->MouseButton(0))
{
m_LockMouse = true;
s_Value = 0;
UI()->SetActiveItem(pID);
UI()->EnableMouseLock(pID);
s_Value = 0;
}
if(pToolTip && !s_TextMode)
m_pTooltip = pToolTip;
@ -1331,7 +1331,7 @@ void CEditor::DoSoundSource(CSoundSource *pSource, int Index)
{
static SPopupMenuId s_PopupSourceId;
UI()->DoPopupMenu(&s_PopupSourceId, UI()->MouseX(), UI()->MouseY(), 120, 200, this, PopupSource);
m_LockMouse = false;
UI()->DisableMouseLock();
}
s_Operation = OP_NONE;
UI()->SetActiveItem(nullptr);
@ -1341,7 +1341,7 @@ void CEditor::DoSoundSource(CSoundSource *pSource, int Index)
{
if(!UI()->MouseButton(0))
{
m_LockMouse = false;
UI()->DisableMouseLock();
s_Operation = OP_NONE;
UI()->SetActiveItem(nullptr);
}
@ -1482,7 +1482,7 @@ void CEditor::DoQuad(CQuad *pQuad, int Index)
static SPopupMenuId s_PopupQuadId;
UI()->DoPopupMenu(&s_PopupQuadId, UI()->MouseX(), UI()->MouseY(), 120, 198, this, PopupQuad);
m_LockMouse = false;
UI()->DisableMouseLock();
}
s_Operation = OP_NONE;
UI()->SetActiveItem(nullptr);
@ -1494,7 +1494,7 @@ void CEditor::DoQuad(CQuad *pQuad, int Index)
{
if(m_vSelectedLayers.size() == 1)
{
m_LockMouse = false;
UI()->DisableMouseLock();
m_Map.m_Modified = true;
DeleteSelectedQuads();
}
@ -1506,7 +1506,7 @@ void CEditor::DoQuad(CQuad *pQuad, int Index)
{
if(!UI()->MouseButton(0))
{
m_LockMouse = false;
UI()->DisableMouseLock();
s_Operation = OP_NONE;
UI()->SetActiveItem(nullptr);
}
@ -1531,7 +1531,7 @@ void CEditor::DoQuad(CQuad *pQuad, int Index)
}
else if(Input()->ModifierIsPressed())
{
m_LockMouse = true;
UI()->EnableMouseLock(pID);
s_Operation = OP_ROTATE;
s_RotateAngle = 0;
@ -1711,7 +1711,7 @@ void CEditor::DoQuadPoint(CQuad *pQuad, int QuadIndex, int V)
m_SelectedPoints = 1 << V;
}
m_LockMouse = false;
UI()->DisableMouseLock();
UI()->SetActiveItem(nullptr);
}
}
@ -1732,7 +1732,7 @@ void CEditor::DoQuadPoint(CQuad *pQuad, int QuadIndex, int V)
if(Input()->ShiftIsPressed())
{
s_Operation = OP_MOVEUV;
m_LockMouse = true;
UI()->EnableMouseLock(pID);
}
else
s_Operation = OP_MOVEPOINT;
@ -2197,7 +2197,7 @@ void CEditor::DoQuadEnvPoint(const CQuad *pQuad, int QIndex, int PIndex)
if(!UI()->MouseButton(0))
{
m_LockMouse = false;
UI()->DisableMouseLock();
s_Operation = OP_NONE;
UI()->SetActiveItem(nullptr);
}
@ -2215,7 +2215,7 @@ void CEditor::DoQuadEnvPoint(const CQuad *pQuad, int QIndex, int PIndex)
{
if(Input()->ModifierIsPressed())
{
m_LockMouse = true;
UI()->EnableMouseLock(pID);
s_Operation = OP_ROTATE;
SelectQuad(QIndex);
@ -6728,7 +6728,6 @@ void CEditor::Init()
m_pSound = Kernel()->RequestInterface<ISound>();
m_UI.Init(Kernel());
m_UI.SetPopupMenuClosedCallback([this]() {
m_LockMouse = false;
m_PopupEventWasActivated = false;
});
m_RenderTools.Init(m_pGraphics, m_pTextRender);
@ -6822,7 +6821,7 @@ void CEditor::OnUpdate()
m_MouseDeltaX += MouseRelX;
m_MouseDeltaY += MouseRelY;
if(!m_LockMouse)
if(!UI()->CheckMouseLock())
{
s_MouseX = clamp<float>(s_MouseX + MouseRelX, 0.0f, Graphics()->WindowWidth());
s_MouseY = clamp<float>(s_MouseY + MouseRelY, 0.0f, Graphics()->WindowHeight());

View file

@ -788,7 +788,6 @@ public:
m_Zooming = false;
m_WorldZoom = 1.0f;
m_LockMouse = false;
m_ShowMousePointer = true;
m_MouseDeltaX = 0;
m_MouseDeltaY = 0;
@ -1029,7 +1028,6 @@ public:
float m_ZoomSmoothingTarget;
float m_WorldZoom;
bool m_LockMouse;
bool m_ShowMousePointer;
bool m_GuiActive;