mirror of
https://github.com/ddnet/ddnet.git
synced 2024-11-09 17:48:19 +00:00
Merge pull request #8096 from Robyt3/UI-ScrollRegion-Popup-Handling
Support overlapping scroll regions, always allow mouse scrolling
This commit is contained in:
commit
e92f5e85ec
|
@ -15,7 +15,7 @@
|
||||||
enum class EInputPriority
|
enum class EInputPriority
|
||||||
{
|
{
|
||||||
NONE = 0,
|
NONE = 0,
|
||||||
Ui,
|
UI,
|
||||||
CHAT,
|
CHAT,
|
||||||
CONSOLE,
|
CONSOLE,
|
||||||
};
|
};
|
||||||
|
|
|
@ -113,11 +113,6 @@ CUi::CUi()
|
||||||
{
|
{
|
||||||
m_Enabled = true;
|
m_Enabled = true;
|
||||||
|
|
||||||
m_pHotItem = nullptr;
|
|
||||||
m_pActiveItem = nullptr;
|
|
||||||
m_pLastActiveItem = nullptr;
|
|
||||||
m_pBecomingHotItem = nullptr;
|
|
||||||
|
|
||||||
m_MouseX = 0;
|
m_MouseX = 0;
|
||||||
m_MouseY = 0;
|
m_MouseY = 0;
|
||||||
m_MouseWorldX = 0;
|
m_MouseWorldX = 0;
|
||||||
|
@ -220,6 +215,8 @@ void CUi::Update(float MouseX, float MouseY, float MouseDeltaX, float MouseDelta
|
||||||
if(m_pActiveItem)
|
if(m_pActiveItem)
|
||||||
m_pHotItem = m_pActiveItem;
|
m_pHotItem = m_pActiveItem;
|
||||||
m_pBecomingHotItem = nullptr;
|
m_pBecomingHotItem = nullptr;
|
||||||
|
m_pHotScrollRegion = m_pBecomingHotScrollRegion;
|
||||||
|
m_pBecomingHotScrollRegion = nullptr;
|
||||||
|
|
||||||
if(Enabled())
|
if(Enabled())
|
||||||
{
|
{
|
||||||
|
@ -231,6 +228,7 @@ void CUi::Update(float MouseX, float MouseY, float MouseDeltaX, float MouseDelta
|
||||||
{
|
{
|
||||||
m_pHotItem = nullptr;
|
m_pHotItem = nullptr;
|
||||||
m_pActiveItem = nullptr;
|
m_pActiveItem = nullptr;
|
||||||
|
m_pHotScrollRegion = nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -804,7 +802,7 @@ bool CUi::DoEditBox(CLineInput *pLineInput, const CUIRect *pRect, float FontSize
|
||||||
SetHotItem(pLineInput);
|
SetHotItem(pLineInput);
|
||||||
|
|
||||||
if(Enabled() && Active && !JustGotActive)
|
if(Enabled() && Active && !JustGotActive)
|
||||||
pLineInput->Activate(EInputPriority::Ui);
|
pLineInput->Activate(EInputPriority::UI);
|
||||||
else
|
else
|
||||||
pLineInput->Deactivate();
|
pLineInput->Deactivate();
|
||||||
|
|
||||||
|
@ -1416,7 +1414,10 @@ void CUi::RenderPopupMenus()
|
||||||
const bool Active = i == m_vPopupMenus.size() - 1;
|
const bool Active = i == m_vPopupMenus.size() - 1;
|
||||||
|
|
||||||
if(Active)
|
if(Active)
|
||||||
|
{
|
||||||
|
// Prevent UI elements below the popup menu from being activated.
|
||||||
SetHotItem(pId);
|
SetHotItem(pId);
|
||||||
|
}
|
||||||
|
|
||||||
if(CheckActiveItem(pId))
|
if(CheckActiveItem(pId))
|
||||||
{
|
{
|
||||||
|
@ -1437,6 +1438,12 @@ void CUi::RenderPopupMenus()
|
||||||
SetActiveItem(pId);
|
SetActiveItem(pId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(Inside)
|
||||||
|
{
|
||||||
|
// Prevent scroll regions directly behind popup menus from using the mouse scroll events.
|
||||||
|
SetHotScrollRegion(nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
CUIRect PopupRect = PopupMenu.m_Rect;
|
CUIRect PopupRect = PopupMenu.m_Rect;
|
||||||
PopupRect.Draw(PopupMenu.m_Props.m_BorderColor, PopupMenu.m_Props.m_Corners, 3.0f);
|
PopupRect.Draw(PopupMenu.m_Props.m_BorderColor, PopupMenu.m_Props.m_Corners, 3.0f);
|
||||||
PopupRect.Margin(SPopupMenu::POPUP_BORDER, &PopupRect);
|
PopupRect.Margin(SPopupMenu::POPUP_BORDER, &PopupRect);
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
class CScrollRegion;
|
||||||
class IClient;
|
class IClient;
|
||||||
class IGraphics;
|
class IGraphics;
|
||||||
class IKernel;
|
class IKernel;
|
||||||
|
@ -322,10 +323,12 @@ public:
|
||||||
private:
|
private:
|
||||||
bool m_Enabled;
|
bool m_Enabled;
|
||||||
|
|
||||||
const void *m_pHotItem;
|
const void *m_pHotItem = nullptr;
|
||||||
const void *m_pActiveItem;
|
const void *m_pActiveItem = nullptr;
|
||||||
const void *m_pLastActiveItem; // only used internally to track active CLineInput
|
const void *m_pLastActiveItem = nullptr; // only used internally to track active CLineInput
|
||||||
const void *m_pBecomingHotItem;
|
const void *m_pBecomingHotItem = nullptr;
|
||||||
|
const CScrollRegion *m_pHotScrollRegion = nullptr;
|
||||||
|
const CScrollRegion *m_pBecomingHotScrollRegion = nullptr;
|
||||||
bool m_ActiveItemValid = false;
|
bool m_ActiveItemValid = false;
|
||||||
|
|
||||||
vec2 m_UpdatedMousePos = vec2(0.0f, 0.0f);
|
vec2 m_UpdatedMousePos = vec2(0.0f, 0.0f);
|
||||||
|
@ -464,9 +467,11 @@ public:
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
void SetHotScrollRegion(const CScrollRegion *pId) { m_pBecomingHotScrollRegion = pId; }
|
||||||
const void *HotItem() const { return m_pHotItem; }
|
const void *HotItem() const { return m_pHotItem; }
|
||||||
const void *NextHotItem() const { return m_pBecomingHotItem; }
|
const void *NextHotItem() const { return m_pBecomingHotItem; }
|
||||||
const void *ActiveItem() const { return m_pActiveItem; }
|
const void *ActiveItem() const { return m_pActiveItem; }
|
||||||
|
const CScrollRegion *HotScrollRegion() const { return m_pHotScrollRegion; }
|
||||||
|
|
||||||
void StartCheck() { m_ActiveItemValid = false; }
|
void StartCheck() { m_ActiveItemValid = false; }
|
||||||
void FinishCheck()
|
void FinishCheck()
|
||||||
|
@ -629,7 +634,7 @@ public:
|
||||||
struct SSelectionPopupContext : public SPopupMenuId
|
struct SSelectionPopupContext : public SPopupMenuId
|
||||||
{
|
{
|
||||||
CUi *m_pUI; // set by CUi when popup is shown
|
CUi *m_pUI; // set by CUi when popup is shown
|
||||||
class CScrollRegion *m_pScrollRegion;
|
CScrollRegion *m_pScrollRegion;
|
||||||
SPopupMenuProperties m_Props;
|
SPopupMenuProperties m_Props;
|
||||||
char m_aMessage[256];
|
char m_aMessage[256];
|
||||||
std::vector<std::string> m_vEntries;
|
std::vector<std::string> m_vEntries;
|
||||||
|
|
|
@ -117,7 +117,6 @@ void CListBox::DoStart(float RowHeight, int NumItems, int ItemsPerRow, int RowsP
|
||||||
// setup the scrollbar
|
// setup the scrollbar
|
||||||
m_ScrollOffset = vec2(0.0f, 0.0f);
|
m_ScrollOffset = vec2(0.0f, 0.0f);
|
||||||
CScrollRegionParams ScrollParams;
|
CScrollRegionParams ScrollParams;
|
||||||
ScrollParams.m_Active = m_Active;
|
|
||||||
ScrollParams.m_ScrollbarWidth = ScrollbarWidthMax();
|
ScrollParams.m_ScrollbarWidth = ScrollbarWidthMax();
|
||||||
ScrollParams.m_ScrollbarMargin = ScrollbarMargin();
|
ScrollParams.m_ScrollbarMargin = ScrollbarMargin();
|
||||||
ScrollParams.m_ScrollUnit = (m_ListBoxRowHeight + m_AutoSpacing) * RowsPerScroll;
|
ScrollParams.m_ScrollUnit = (m_ListBoxRowHeight + m_AutoSpacing) * RowsPerScroll;
|
||||||
|
@ -208,7 +207,7 @@ CListboxItem CListBox::DoSubheader()
|
||||||
int CListBox::DoEnd()
|
int CListBox::DoEnd()
|
||||||
{
|
{
|
||||||
m_ScrollRegion.End();
|
m_ScrollRegion.End();
|
||||||
m_Active |= m_ScrollRegion.Params().m_Active;
|
m_Active |= m_ScrollRegion.Active();
|
||||||
|
|
||||||
m_ScrollbarShown = m_ScrollRegion.ScrollbarShown();
|
m_ScrollbarShown = m_ScrollRegion.ScrollbarShown();
|
||||||
if(m_ListBoxNewSelOffset != 0 && m_ListBoxNumItems > 0 && m_ListBoxSelectedIndex == m_ListBoxNewSelected)
|
if(m_ListBoxNewSelOffset != 0 && m_ListBoxNumItems > 0 && m_ListBoxSelectedIndex == m_ListBoxNewSelected)
|
||||||
|
|
|
@ -79,7 +79,7 @@ void CScrollRegion::End()
|
||||||
CUIRect RegionRect = m_ClipRect;
|
CUIRect RegionRect = m_ClipRect;
|
||||||
RegionRect.w += m_Params.m_ScrollbarWidth;
|
RegionRect.w += m_Params.m_ScrollbarWidth;
|
||||||
|
|
||||||
if(m_ScrollDirection != SCROLLRELATIVE_NONE || (Ui()->Enabled() && m_Params.m_Active && Ui()->MouseHovered(&RegionRect)))
|
if(m_ScrollDirection != SCROLLRELATIVE_NONE || Ui()->HotScrollRegion() == this)
|
||||||
{
|
{
|
||||||
bool ProgrammaticScroll = false;
|
bool ProgrammaticScroll = false;
|
||||||
if(Ui()->ConsumeHotkey(CUi::HOTKEY_SCROLL_UP))
|
if(Ui()->ConsumeHotkey(CUi::HOTKEY_SCROLL_UP))
|
||||||
|
@ -106,6 +106,11 @@ void CScrollRegion::End()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(Ui()->Enabled() && Ui()->MouseHovered(&RegionRect))
|
||||||
|
{
|
||||||
|
Ui()->SetHotScrollRegion(this);
|
||||||
|
}
|
||||||
|
|
||||||
const float SliderHeight = maximum(m_Params.m_SliderMinHeight, m_ClipRect.h / m_ContentH * m_RailRect.h);
|
const float SliderHeight = maximum(m_Params.m_SliderMinHeight, m_ClipRect.h / m_ContentH * m_RailRect.h);
|
||||||
|
|
||||||
CUIRect Slider = m_RailRect;
|
CUIRect Slider = m_RailRect;
|
||||||
|
@ -163,7 +168,6 @@ void CScrollRegion::End()
|
||||||
m_SliderGrabPos = Ui()->MouseY() - Slider.y;
|
m_SliderGrabPos = Ui()->MouseY() - Slider.y;
|
||||||
m_AnimTargetScrollY = m_ScrollY;
|
m_AnimTargetScrollY = m_ScrollY;
|
||||||
m_AnimTime = 0.0f;
|
m_AnimTime = 0.0f;
|
||||||
m_Params.m_Active = true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if(InsideRail && Ui()->MouseButtonClicked(0))
|
else if(InsideRail && Ui()->MouseButtonClicked(0))
|
||||||
|
@ -174,7 +178,6 @@ void CScrollRegion::End()
|
||||||
m_SliderGrabPos = Slider.h / 2.0f;
|
m_SliderGrabPos = Slider.h / 2.0f;
|
||||||
m_AnimTargetScrollY = m_ScrollY;
|
m_AnimTargetScrollY = m_ScrollY;
|
||||||
m_AnimTime = 0.0f;
|
m_AnimTime = 0.0f;
|
||||||
m_Params.m_Active = true;
|
|
||||||
}
|
}
|
||||||
else if(Ui()->CheckActiveItem(pId) && !Ui()->MouseButton(0))
|
else if(Ui()->CheckActiveItem(pId) && !Ui()->MouseButton(0))
|
||||||
{
|
{
|
||||||
|
@ -259,3 +262,8 @@ bool CScrollRegion::Animating() const
|
||||||
{
|
{
|
||||||
return m_AnimTime > 0.0f;
|
return m_AnimTime > 0.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool CScrollRegion::Active() const
|
||||||
|
{
|
||||||
|
return Ui()->ActiveItem() == &m_ScrollY;
|
||||||
|
}
|
||||||
|
|
|
@ -7,7 +7,6 @@
|
||||||
|
|
||||||
struct CScrollRegionParams
|
struct CScrollRegionParams
|
||||||
{
|
{
|
||||||
bool m_Active;
|
|
||||||
float m_ScrollbarWidth;
|
float m_ScrollbarWidth;
|
||||||
float m_ScrollbarMargin;
|
float m_ScrollbarMargin;
|
||||||
bool m_ScrollbarNoMarginRight;
|
bool m_ScrollbarNoMarginRight;
|
||||||
|
@ -28,7 +27,6 @@ struct CScrollRegionParams
|
||||||
|
|
||||||
CScrollRegionParams()
|
CScrollRegionParams()
|
||||||
{
|
{
|
||||||
m_Active = true;
|
|
||||||
m_ScrollbarWidth = 20.0f;
|
m_ScrollbarWidth = 20.0f;
|
||||||
m_ScrollbarMargin = 5.0f;
|
m_ScrollbarMargin = 5.0f;
|
||||||
m_ScrollbarNoMarginRight = false;
|
m_ScrollbarNoMarginRight = false;
|
||||||
|
@ -140,6 +138,7 @@ public:
|
||||||
bool RectClipped(const CUIRect &Rect) const;
|
bool RectClipped(const CUIRect &Rect) const;
|
||||||
bool ScrollbarShown() const;
|
bool ScrollbarShown() const;
|
||||||
bool Animating() const;
|
bool Animating() const;
|
||||||
|
bool Active() const;
|
||||||
const CScrollRegionParams &Params() const { return m_Params; }
|
const CScrollRegionParams &Params() const { return m_Params; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue