From 053981ee4c2d5c9df81eb1471cb9d04ca9e06772 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20M=C3=BCller?= Date: Fri, 26 Nov 2021 21:55:31 +0100 Subject: [PATCH] refactor UI scrollbars --- src/game/client/components/menus.cpp | 172 +---------------- src/game/client/components/menus.h | 31 +-- src/game/client/components/menus_browser.cpp | 5 +- src/game/client/components/menus_demo.cpp | 14 +- src/game/client/components/menus_ingame.cpp | 5 +- src/game/client/components/menus_settings.cpp | 77 +++----- src/game/client/ui.cpp | 20 +- src/game/client/ui.h | 9 +- src/game/client/ui_ex.cpp | 177 ++++++++++++++++++ src/game/client/ui_ex.h | 18 +- src/game/editor/editor.cpp | 128 +++---------- src/game/editor/editor.h | 4 +- src/game/editor/popups.cpp | 21 +-- 13 files changed, 294 insertions(+), 387 deletions(-) diff --git a/src/game/client/components/menus.cpp b/src/game/client/components/menus.cpp index 1a5de6744..f4d093791 100644 --- a/src/game/client/components/menus.cpp +++ b/src/game/client/components/menus.cpp @@ -79,7 +79,6 @@ CMenus::CMenus() m_MenuActive = true; m_ShowStart = true; m_UseMouseButtons = true; - m_MouseSlow = false; m_EscapePressed = false; m_EnterPressed = false; @@ -119,15 +118,6 @@ CMenus::CMenus() } } -float CMenus::ButtonColorMul(const void *pID) -{ - if(UI()->ActiveItem() == pID) - return ButtonColorMulActive(); - else if(UI()->HotItem() == pID) - return ButtonColorMulHot(); - return ButtonColorMulDefault(); -} - int CMenus::DoButton_Icon(int ImageId, int SpriteId, const CUIRect *pRect) { int x = pRect->x; @@ -199,7 +189,7 @@ int CMenus::DoButton_Menu(const void *pID, const char *pText, int Checked, const } if(!MouseInsideColorPicker) - Color.a *= ButtonColorMul(pID); + Color.a *= UI()->ButtonColorMul(pID); RenderTools()->DrawUIRect(pRect, Color, Corners, r); if(pImageName) @@ -234,7 +224,7 @@ int CMenus::DoButton_Menu(const void *pID, const char *pText, int Checked, const void CMenus::DoButton_KeySelect(const void *pID, const char *pText, int Checked, const CUIRect *pRect) { - RenderTools()->DrawUIRect(pRect, ColorRGBA(1, 1, 1, 0.5f * ButtonColorMul(pID)), CUI::CORNER_ALL, 5.0f); + RenderTools()->DrawUIRect(pRect, ColorRGBA(1, 1, 1, 0.5f * UI()->ButtonColorMul(pID)), CUI::CORNER_ALL, 5.0f); CUIRect Temp; pRect->HMargin(1.0f, &Temp); UI()->DoLabel(&Temp, pText, Temp.h * ms_FontmodHeight, 0); @@ -343,7 +333,7 @@ int CMenus::DoButton_CheckBox_Common(const void *pID, const char *pText, const c t.VSplitLeft(5.0f, 0, &t); c.Margin(2.0f, &c); - RenderTools()->DrawUIRect(&c, ColorRGBA(1, 1, 1, 0.25f * ButtonColorMul(pID)), CUI::CORNER_ALL, 3.0f); + RenderTools()->DrawUIRect(&c, ColorRGBA(1, 1, 1, 0.25f * UI()->ButtonColorMul(pID)), CUI::CORNER_ALL, 3.0f); bool CheckAble = *pBoxText == 'X'; if(CheckAble) @@ -623,7 +613,7 @@ int CMenus::DoClearableEditBox(void *pID, void *pClearID, const CUIRect *pRect, } TextRender()->SetRenderFlags(ETextRenderFlags::TEXT_RENDER_FLAG_ONLY_ADVANCE_WIDTH | ETextRenderFlags::TEXT_RENDER_FLAG_NO_X_BEARING | ETextRenderFlags::TEXT_RENDER_FLAG_NO_Y_BEARING | ETextRenderFlags::TEXT_RENDER_FLAG_NO_PIXEL_ALIGMENT); - RenderTools()->DrawUIRect(&ClearButton, ColorRGBA(1, 1, 1, 0.33f * ButtonColorMul(pClearID)), Corners & ~CUI::CORNER_L, 3.0f); + RenderTools()->DrawUIRect(&ClearButton, ColorRGBA(1, 1, 1, 0.33f * UI()->ButtonColorMul(pClearID)), Corners & ~CUI::CORNER_L, 3.0f); UI()->DoLabel(&ClearButton, "×", ClearButton.h * ms_FontmodHeight, 0, -1, 0); TextRender()->SetRenderFlags(0); if(UI()->DoButtonLogic(pClearID, "×", 0, &ClearButton)) @@ -635,140 +625,6 @@ int CMenus::DoClearableEditBox(void *pID, void *pClearID, const CUIRect *pRect, return ReturnValue; } -float CMenus::DoScrollbarV(const void *pID, const CUIRect *pRect, float Current) -{ - CUIRect Handle; - static float OffsetY; - pRect->HSplitTop(33, &Handle, 0); - - Current = clamp(Current, 0.0f, 1.0f); - Handle.y = pRect->y + (pRect->h - Handle.h) * Current; - - // logic - float ReturnValue = Current; - int Inside = UI()->MouseInside(&Handle); - - if(UI()->ActiveItem() == pID) - { - if(!UI()->MouseButton(0)) - UI()->SetActiveItem(0); - - if(Input()->KeyIsPressed(KEY_LSHIFT) || Input()->KeyIsPressed(KEY_RSHIFT)) - m_MouseSlow = true; - - float Min = pRect->y; - float Max = pRect->h - Handle.h; - float Cur = UI()->MouseY() - OffsetY; - ReturnValue = (Cur - Min) / Max; - if(ReturnValue < 0.0f) - ReturnValue = 0.0f; - if(ReturnValue > 1.0f) - ReturnValue = 1.0f; - } - else if(UI()->HotItem() == pID) - { - if(UI()->MouseButton(0)) - { - UI()->SetActiveItem(pID); - OffsetY = UI()->MouseY() - Handle.y; - } - } - - if(Inside) - UI()->SetHotItem(pID); - - // render - RenderTools()->DrawUIRect(pRect, ColorRGBA(0, 0, 0, 0.25f), CUI::CORNER_ALL, 5.0f); - - float ColorSlider = 0; - - if(UI()->ActiveItem() == pID) - ColorSlider = 1.0f; - else if(UI()->HotItem() == pID) - ColorSlider = 0.9f; - else - ColorSlider = 0.75f; - - RenderTools()->DrawUIRect(&Handle, ColorRGBA(ColorSlider, ColorSlider, ColorSlider, 0.75f), CUI::CORNER_ALL, 5.0f); - - return ReturnValue; -} - -float CMenus::DoScrollbarH(const void *pID, const CUIRect *pRect, float Current, bool ColorPickerSlider, ColorRGBA *pColorInner) -{ - CUIRect Handle; - static float OffsetX; - pRect->VSplitLeft(ColorPickerSlider ? 8 : 33, &Handle, 0); - - Handle.x += (pRect->w - Handle.w) * Current; - - // logic - float ReturnValue = Current; - int Inside = UI()->MouseInside(&Handle); - - if(UI()->ActiveItem() == pID) - { - if(!UI()->MouseButton(0)) - UI()->SetActiveItem(0); - - if(Input()->KeyIsPressed(KEY_LSHIFT) || Input()->KeyIsPressed(KEY_RSHIFT)) - m_MouseSlow = true; - - float Min = pRect->x; - float Max = pRect->w - Handle.w; - float Cur = UI()->MouseX() - OffsetX; - ReturnValue = (Cur - Min) / Max; - if(ReturnValue < 0.0f) - ReturnValue = 0.0f; - if(ReturnValue > 1.0f) - ReturnValue = 1.0f; - } - else if(UI()->HotItem() == pID) - { - if(UI()->MouseButton(0)) - { - UI()->SetActiveItem(pID); - OffsetX = UI()->MouseX() - Handle.x; - } - } - - if(Inside) - UI()->SetHotItem(pID); - - // render - if(!ColorPickerSlider) - { - CUIRect Rail; - pRect->HMargin(5.0f, &Rail); - RenderTools()->DrawUIRect(&Rail, ColorRGBA(1, 1, 1, 0.25f), 0, 0.0f); - - CUIRect Slider = Handle; - Slider.h = Rail.y - Slider.y; - RenderTools()->DrawUIRect(&Slider, ColorRGBA(1, 1, 1, 0.25f), CUI::CORNER_T, 2.5f); - Slider.y = Rail.y + Rail.h; - RenderTools()->DrawUIRect(&Slider, ColorRGBA(1, 1, 1, 0.25f), CUI::CORNER_B, 2.5f); - - Slider = Handle; - Slider.Margin(5.0f, &Slider); - RenderTools()->DrawUIRect(&Slider, ColorRGBA(1, 1, 1, 0.25f * ButtonColorMul(pID)), CUI::CORNER_ALL, 2.5f); - } - else - { - CUIRect Slider = Handle; - float MarginW = 4.0f; - float MarginH = 9.0f; - Slider.x -= MarginW / 2; - Slider.y -= MarginH / 2; - Slider.w += MarginW; - Slider.h += MarginH; - RenderTools()->DrawUIRect(&Slider, ColorRGBA(0.15f, 0.15f, 0.15f, 1.0f), CUI::CORNER_ALL, 5.0f); - Slider.Margin(2, &Slider); - RenderTools()->DrawUIRect(&Slider, *pColorInner, CUI::CORNER_ALL, 3.0f); - } - - return ReturnValue; -} - int CMenus::DoKeyReader(void *pID, const CUIRect *pRect, int Key, int Modifier, int *NewModifier) { // process @@ -1452,8 +1308,7 @@ int CMenus::Render() CUIRect Screen = *UI()->Screen(); UI()->MapScreen(); - - m_MouseSlow = false; + m_UIEx.ResetMouseSlow(); static int s_Frame = 0; if(s_Frame == 0) @@ -2555,19 +2410,10 @@ bool CMenus::OnMouseMove(float x, float y) if(!m_MenuActive) return false; - UI()->ConvertMouseMove(&x, &y); - if(m_MouseSlow) - { - m_MousePos.x += x * 0.05f; - m_MousePos.y += y * 0.05f; - } - else - { - m_MousePos.x += x; - m_MousePos.y += y; - } - m_MousePos.x = clamp(m_MousePos.x, 0.f, (float)Graphics()->WindowWidth()); - m_MousePos.y = clamp(m_MousePos.y, 0.f, (float)Graphics()->WindowHeight()); + m_UIEx.ConvertMouseMove(&x, &y); + + m_MousePos.x = clamp(m_MousePos.x + x, 0.f, (float)Graphics()->WindowWidth()); + m_MousePos.y = clamp(m_MousePos.y + y, 0.f, (float)Graphics()->WindowHeight()); return true; } diff --git a/src/game/client/components/menus.h b/src/game/client/components/menus.h index bb760cedf..2a6a30957 100644 --- a/src/game/client/components/menus.h +++ b/src/game/client/components/menus.h @@ -75,11 +75,6 @@ class CMenus : public CComponent CUIEx m_UIEx; - float ButtonColorMulActive() { return 0.5f; } - float ButtonColorMulHot() { return 1.5f; } - float ButtonColorMulDefault() { return 1.0f; } - float ButtonColorMul(const void *pID); - int DoButton_DemoPlayer(const void *pID, const char *pText, int Checked, const CUIRect *pRect); int DoButton_Sprite(const void *pID, int ImageID, int SpriteID, int Checked, const CUIRect *pRect, int Corners); int DoButton_Toggle(const void *pID, int Checked, const CUIRect *pRect, bool Active); @@ -92,32 +87,16 @@ class CMenus : public CComponent int DoButton_CheckBox_Number(const void *pID, const char *pText, int Checked, const CUIRect *pRect); ColorHSLA DoLine_ColorPicker(int *pResetID, const float LineSize, const float WantedPickerPosition, const float LabelSize, const float BottomMargin, CUIRect *pMainRect, const char *pText, unsigned int *pColorValue, const ColorRGBA DefaultColor, bool CheckBoxSpacing = true, bool UseCheckBox = false, int *pCheckBoxValue = NULL); void DoLaserPreview(const CUIRect *pRect, const ColorHSLA OutlineColor, const ColorHSLA InnerColor); - /*static void ui_draw_menu_button(const void *id, const char *text, int checked, const CUIRect *r, const void *extra); - static void ui_draw_keyselect_button(const void *id, const char *text, int checked, const CUIRect *r, const void *extra); - static void ui_draw_menu_tab_button(const void *id, const char *text, int checked, const CUIRect *r, const void *extra); - static void ui_draw_settings_tab_button(const void *id, const char *text, int checked, const CUIRect *r, const void *extra); - */ int DoValueSelector(void *pID, CUIRect *pRect, const char *pLabel, bool UseScroll, int Current, int Min, int Max, int Step, float Scale, bool IsHex, float Round, ColorRGBA *Color); int DoButton_Icon(int ImageId, int SpriteId, const CUIRect *pRect); int DoButton_GridHeader(const void *pID, const char *pText, int Checked, const CUIRect *pRect); - //static void ui_draw_browse_icon(int what, const CUIRect *r); - //static void ui_draw_grid_header(const void *id, const char *text, int checked, const CUIRect *r, const void *extra); - - /*static void ui_draw_checkbox_common(const void *id, const char *text, const char *boxtext, const CUIRect *r, const void *extra); - static void ui_draw_checkbox(const void *id, const char *text, int checked, const CUIRect *r, const void *extra); - static void ui_draw_checkbox_number(const void *id, const char *text, int checked, const CUIRect *r, const void *extra); - */ int DoEditBox(void *pID, const CUIRect *pRect, char *pStr, unsigned StrSize, float FontSize, float *Offset, bool Hidden = false, int Corners = CUI::CORNER_ALL, const char *pEmptyText = ""); int DoClearableEditBox(void *pID, void *pClearID, const CUIRect *pRect, char *pStr, unsigned StrSize, float FontSize, float *Offset, bool Hidden = false, int Corners = CUI::CORNER_ALL, const char *pEmptyText = ""); - //static int ui_do_edit_box(void *id, const CUIRect *rect, char *str, unsigned str_size, float font_size, bool hidden=false); - float DoScrollbarV(const void *pID, const CUIRect *pRect, float Current); - float DoScrollbarH(const void *pID, const CUIRect *pRect, float Current, bool ColorPickerSlider = false, ColorRGBA *pColorInner = NULL); void DoButton_KeySelect(const void *pID, const char *pText, int Checked, const CUIRect *pRect); int DoKeyReader(void *pID, const CUIRect *pRect, int Key, int Modifier, int *NewModifier); - //static int ui_do_key_reader(void *id, const CUIRect *rect, int key); void UiDoGetButtons(int Start, int Stop, CUIRect View, CUIRect ScopeView); void RenderColorPicker(); @@ -168,11 +147,11 @@ class CMenus : public CComponent { Color.a = RealColor.a; if(i == 0) - Color.a *= ButtonColorMulActive(); + Color.a *= UI()->ButtonColorMulActive(); else if(i == 1) - Color.a *= ButtonColorMulHot(); + Color.a *= UI()->ButtonColorMulHot(); else if(i == 2) - Color.a *= ButtonColorMulDefault(); + Color.a *= UI()->ButtonColorMulDefault(); Graphics()->SetColor(Color); CUIElement::SUIElementRect &NewRect = *UIElement.Get(i); @@ -224,9 +203,6 @@ class CMenus : public CComponent int UiLogicGetCurrentClickedItem(); - //static void demolist_listdir_callback(const char *name, int is_dir, void *user); - //static void demolist_list_callback(const CUIRect *rect, int index, void *user); - // menus_settings_assets.cpp public: struct SCustomItem @@ -287,7 +263,6 @@ protected: bool m_MenuActive; bool m_UseMouseButtons; vec2 m_MousePos; - bool m_MouseSlow; char m_aNextServer[256]; diff --git a/src/game/client/components/menus_browser.cpp b/src/game/client/components/menus_browser.cpp index abebe1419..c6e25adc5 100644 --- a/src/game/client/components/menus_browser.cpp +++ b/src/game/client/components/menus_browser.cpp @@ -171,7 +171,7 @@ void CMenus::RenderServerbrowserServerList(CUIRect View) RenderTools()->DrawUIRect(&View, ColorRGBA(0, 0, 0, 0.15f), 0, 0); CUIRect Scroll; - View.VSplitRight(10, &View, &Scroll); + View.VSplitRight(20.0f, &View, &Scroll); int NumServers = ServerBrowser()->NumSortedServers(); @@ -188,10 +188,9 @@ void CMenus::RenderServerbrowserServerList(CUIRect View) UI()->DoLabelScaled(&MsgBox, Localize("No servers match your filter criteria"), 16.0f, 0); } - static int s_ScrollBar = 0; static float s_ScrollValue = 0; - s_ScrollValue = DoScrollbarV(&s_ScrollBar, &Scroll, s_ScrollValue); + s_ScrollValue = m_UIEx.DoScrollbarV(&s_ScrollValue, &Scroll, s_ScrollValue); if(Input()->KeyPress(KEY_TAB) && m_pClient->m_GameConsole.IsClosed()) { diff --git a/src/game/client/components/menus_demo.cpp b/src/game/client/components/menus_demo.cpp index da7bc0e4a..871afeecf 100644 --- a/src/game/client/components/menus_demo.cpp +++ b/src/game/client/components/menus_demo.cpp @@ -26,14 +26,14 @@ int CMenus::DoButton_DemoPlayer(const void *pID, const char *pText, int Checked, const CUIRect *pRect) { - RenderTools()->DrawUIRect(pRect, ColorRGBA(1, 1, 1, (Checked ? 0.10f : 0.5f) * ButtonColorMul(pID)), CUI::CORNER_ALL, 5.0f); + RenderTools()->DrawUIRect(pRect, ColorRGBA(1, 1, 1, (Checked ? 0.10f : 0.5f) * UI()->ButtonColorMul(pID)), CUI::CORNER_ALL, 5.0f); UI()->DoLabel(pRect, pText, 14.0f, 0); return UI()->DoButtonLogic(pID, pText, Checked, pRect); } int CMenus::DoButton_Sprite(const void *pID, int ImageID, int SpriteID, int Checked, const CUIRect *pRect, int Corners) { - RenderTools()->DrawUIRect(pRect, ColorRGBA(1.0f, 1.0f, 1.0f, (Checked ? 0.10f : 0.5f) * ButtonColorMul(pID)), Corners, 5.0f); + RenderTools()->DrawUIRect(pRect, ColorRGBA(1.0f, 1.0f, 1.0f, (Checked ? 0.10f : 0.5f) * UI()->ButtonColorMul(pID)), Corners, 5.0f); Graphics()->TextureSet(g_pData->m_aImages[ImageID].m_Id); Graphics()->QuadsBegin(); if(!Checked) @@ -527,7 +527,7 @@ void CMenus::UiDoListboxStart(const void *pID, const CUIRect *pRect, float RowHe RenderTools()->DrawUIRect(&View, ColorRGBA(0, 0, 0, 0.15f), CUI::CORNER_ALL, 5.0f); } - View.VSplitRight(10, &View, &Scroll); + View.VSplitRight(20.0f, &View, &Scroll); // setup the variables gs_ListBoxOriginalView = View; @@ -563,7 +563,7 @@ void CMenus::UiDoListboxStart(const void *pID, const CUIRect *pRect, float RowHe if(Num == 0) gs_ListBoxScrollValue = 0; else - gs_ListBoxScrollValue = clamp(DoScrollbarV(pID, &Scroll, gs_ListBoxScrollValue), 0.0f, 1.0f); + gs_ListBoxScrollValue = m_UIEx.DoScrollbarV(pID, &Scroll, gs_ListBoxScrollValue); // the list gs_ListBoxView = gs_ListBoxOriginalView; @@ -1069,13 +1069,11 @@ void CMenus::RenderDemoList(CUIRect MainView) // scrollbar CUIRect Scroll; - ListBox.VSplitRight(15, &ListBox, &Scroll); + ListBox.VSplitRight(20.0f, &ListBox, &Scroll); - static int s_ScrollBar = 0; static float s_ScrollValue = 0; - Scroll.HMargin(5.0f, &Scroll); - s_ScrollValue = DoScrollbarV(&s_ScrollBar, &Scroll, s_ScrollValue); + s_ScrollValue = m_UIEx.DoScrollbarV(&s_ScrollValue, &Scroll, s_ScrollValue); int PreviousIndex = m_DemolistSelectedIndex; HandleListInputs(ListBox, s_ScrollValue, 3.0f, &m_ScrollOffset, s_aCols[0].m_Rect.h, m_DemolistSelectedIndex, m_lDemos.size()); diff --git a/src/game/client/components/menus_ingame.cpp b/src/game/client/components/menus_ingame.cpp index 2334db80f..ab647f649 100644 --- a/src/game/client/components/menus_ingame.cpp +++ b/src/game/client/components/menus_ingame.cpp @@ -1033,14 +1033,13 @@ void CMenus::RenderGhost(CUIRect MainView) RenderTools()->DrawUIRect(&View, ColorRGBA(0, 0, 0, 0.15f), 0, 0); CUIRect Scroll; - View.VSplitRight(10, &View, &Scroll); + View.VSplitRight(20.0f, &View, &Scroll); int NumGhosts = m_lGhosts.size(); - static int s_ScrollBar = 0; static float s_ScrollValue = 0; static int s_SelectedIndex = 0; - s_ScrollValue = DoScrollbarV(&s_ScrollBar, &Scroll, s_ScrollValue); + s_ScrollValue = m_UIEx.DoScrollbarV(&s_ScrollValue, &Scroll, s_ScrollValue); HandleListInputs(View, s_ScrollValue, 1.0f, nullptr, s_aCols[0].m_Rect.h, s_SelectedIndex, NumGhosts); diff --git a/src/game/client/components/menus_settings.cpp b/src/game/client/components/menus_settings.cpp index c6ed87fa9..4eda7dbd9 100644 --- a/src/game/client/components/menus_settings.cpp +++ b/src/game/client/components/menus_settings.cpp @@ -161,8 +161,7 @@ void CMenus::RenderSettingsGeneral(CUIRect MainView) Right.HSplitTop(20.0f, &Button, &Right); str_format(aBuf, sizeof(aBuf), "%s: %i", Localize("Name plates size"), g_Config.m_ClNameplatesSize); UI()->DoLabelScaled(&Label, aBuf, 13.0f, -1); - Button.HMargin(2.0f, &Button); - g_Config.m_ClNameplatesSize = (int)(DoScrollbarH(&g_Config.m_ClNameplatesSize, &Button, g_Config.m_ClNameplatesSize / 100.0f) * 100.0f + 0.1f); + g_Config.m_ClNameplatesSize = (int)(m_UIEx.DoScrollbarH(&g_Config.m_ClNameplatesSize, &Button, g_Config.m_ClNameplatesSize / 100.0f) * 100.0f + 0.1f); Right.HSplitTop(20.0f, &Button, &Right); if(DoButton_CheckBox(&g_Config.m_ClNameplatesTeamcolors, Localize("Use team colors for name plates"), g_Config.m_ClNameplatesTeamcolors, &Button)) @@ -180,8 +179,7 @@ void CMenus::RenderSettingsGeneral(CUIRect MainView) Right.HSplitTop(20.0f, &Button, &Right); str_format(aBuf, sizeof(aBuf), "%s: %i", Localize("Clan plates size"), g_Config.m_ClNameplatesClanSize); UI()->DoLabelScaled(&Label, aBuf, 13.0f, -1); - Button.HMargin(2.0f, &Button); - g_Config.m_ClNameplatesClanSize = (int)(DoScrollbarH(&g_Config.m_ClNameplatesClanSize, &Button, g_Config.m_ClNameplatesClanSize / 100.0f) * 100.0f + 0.1f); + g_Config.m_ClNameplatesClanSize = (int)(m_UIEx.DoScrollbarH(&g_Config.m_ClNameplatesClanSize, &Button, g_Config.m_ClNameplatesClanSize / 100.0f) * 100.0f + 0.1f); } } } @@ -219,8 +217,7 @@ void CMenus::RenderSettingsGeneral(CUIRect MainView) str_format(aBuf, sizeof(aBuf), "%s: %s", Localize("Max demos"), "∞"); UI()->DoLabelScaled(&Label, aBuf, 13.0f, -1); Right.HSplitTop(20.0f, &Button, &Right); - Button.HMargin(2.0f, &Button); - g_Config.m_ClAutoDemoMax = static_cast(DoScrollbarH(&g_Config.m_ClAutoDemoMax, &Button, g_Config.m_ClAutoDemoMax / 1000.0f) * 1000.0f + 0.1f); + g_Config.m_ClAutoDemoMax = static_cast(m_UIEx.DoScrollbarH(&g_Config.m_ClAutoDemoMax, &Button, g_Config.m_ClAutoDemoMax / 1000.0f) * 1000.0f + 0.1f); Right.HSplitTop(SliderGroupMargin, 0, &Right); Right.HSplitTop(20.0f, &Button, &Right); @@ -234,8 +231,7 @@ void CMenus::RenderSettingsGeneral(CUIRect MainView) str_format(aBuf, sizeof(aBuf), "%s: %s", Localize("Max Screenshots"), "∞"); UI()->DoLabelScaled(&Label, aBuf, 13.0f, -1); Right.HSplitTop(20.0f, &Button, &Right); - Button.HMargin(2.0f, &Button); - g_Config.m_ClAutoScreenshotMax = static_cast(DoScrollbarH(&g_Config.m_ClAutoScreenshotMax, &Button, g_Config.m_ClAutoScreenshotMax / 1000.0f) * 1000.0f + 0.1f); + g_Config.m_ClAutoScreenshotMax = static_cast(m_UIEx.DoScrollbarH(&g_Config.m_ClAutoScreenshotMax, &Button, g_Config.m_ClAutoScreenshotMax / 1000.0f) * 1000.0f + 0.1f); } Left.HSplitTop(10.0f, 0, &Left); @@ -247,8 +243,7 @@ void CMenus::RenderSettingsGeneral(CUIRect MainView) str_format(aBuf, sizeof(aBuf), "%s: %s", Localize("Refresh Rate"), "∞"); UI()->DoLabelScaled(&Label, aBuf, 13.0f, -1); Left.HSplitTop(20.0f, &Button, &Left); - Button.HMargin(2.0f, &Button); - g_Config.m_ClRefreshRate = static_cast(DoScrollbarH(&g_Config.m_ClRefreshRate, &Button, g_Config.m_ClRefreshRate / 10000.0f) * 10000.0f + 0.1f); + g_Config.m_ClRefreshRate = static_cast(m_UIEx.DoScrollbarH(&g_Config.m_ClRefreshRate, &Button, g_Config.m_ClRefreshRate / 10000.0f) * 10000.0f + 0.1f); #if defined(CONF_FAMILY_WINDOWS) Left.HSplitTop(10.0f, 0, &Left); @@ -301,9 +296,8 @@ void CMenus::RenderSettingsGeneral(CUIRect MainView) str_format(aBuf, sizeof(aBuf), "%s: %s", Localize("Max Screenshots"), "∞"); UI()->DoLabelScaled(&Label, aBuf, 13.0f, -1); Right.HSplitTop(20.0f, &Button, &Right); - Button.HMargin(2.0f, &Button); g_Config.m_ClAutoStatboardScreenshotMax = - static_cast(DoScrollbarH(&g_Config.m_ClAutoStatboardScreenshotMax, + static_cast(m_UIEx.DoScrollbarH(&g_Config.m_ClAutoStatboardScreenshotMax, &Button, g_Config.m_ClAutoStatboardScreenshotMax / 1000.0f) * 1000.0f + @@ -328,9 +322,8 @@ void CMenus::RenderSettingsGeneral(CUIRect MainView) str_format(aBuf, sizeof(aBuf), "%s: %s", Localize("Max CSVs"), "∞"); UI()->DoLabelScaled(&Label, aBuf, 13.0f, -1); Right.HSplitTop(20.0f, &Button, &Right); - Button.HMargin(2.0f, &Button); g_Config.m_ClAutoCSVMax = - static_cast(DoScrollbarH(&g_Config.m_ClAutoCSVMax, + static_cast(m_UIEx.DoScrollbarH(&g_Config.m_ClAutoCSVMax, &Button, g_Config.m_ClAutoCSVMax / 1000.0f) * 1000.0f + @@ -928,8 +921,7 @@ void CMenus::RenderSettingsControls(CUIRect MainView) Button.VSplitLeft(160.0f, &Label, &Button); str_format(aBuf, sizeof(aBuf), "%s: %i", Localize("Mouse sens."), g_Config.m_InpMousesens); UI()->DoLabel(&Label, aBuf, 14.0f * UI()->Scale(), -1); - Button.HMargin(2.0f, &Button); - int NewValue = (int)(DoScrollbarH(&g_Config.m_InpMousesens, &Button, (minimum(g_Config.m_InpMousesens, 500) - 1) / 500.0f) * 500.0f) + 1; + int NewValue = (int)(m_UIEx.DoScrollbarH(&g_Config.m_InpMousesens, &Button, (minimum(g_Config.m_InpMousesens, 500) - 1) / 500.0f) * 500.0f) + 1; if(g_Config.m_InpMousesens < 500 || NewValue < 500) g_Config.m_InpMousesens = minimum(NewValue, 500); MovementSettings.HSplitTop(20.0f, 0, &MovementSettings); @@ -941,8 +933,7 @@ void CMenus::RenderSettingsControls(CUIRect MainView) Button.VSplitLeft(160.0f, &Label, &Button); str_format(aBuf, sizeof(aBuf), "%s: %i", Localize("UI mouse s."), g_Config.m_UiMousesens); UI()->DoLabel(&Label, aBuf, 14.0f * UI()->Scale(), -1); - Button.HMargin(2.0f, &Button); - int NewValue = (int)(DoScrollbarH(&g_Config.m_UiMousesens, &Button, (minimum(g_Config.m_UiMousesens, 500) - 1) / 500.0f) * 500.0f) + 1; + int NewValue = (int)(m_UIEx.DoScrollbarH(&g_Config.m_UiMousesens, &Button, (minimum(g_Config.m_UiMousesens, 500) - 1) / 500.0f) * 500.0f) + 1; if(g_Config.m_UiMousesens < 500 || NewValue < 500) g_Config.m_UiMousesens = minimum(NewValue, 500); MovementSettings.HSplitTop(20.0f, 0, &MovementSettings); @@ -1286,8 +1277,7 @@ void CMenus::RenderSettingsGraphics(CUIRect MainView) else str_format(aBuf, sizeof(aBuf), "%s: %s", Localize("Refresh Rate"), "∞"); UI()->DoLabelScaled(&Label, aBuf, 14.0f, -1); - Button.HMargin(2.0f, &Button); - int NewRefreshRate = static_cast(DoScrollbarH(&g_Config.m_GfxRefreshRate, &Button, (minimum(g_Config.m_GfxRefreshRate, 1000)) / 1000.0f) * 1000.0f + 0.1f); + int NewRefreshRate = static_cast(m_UIEx.DoScrollbarH(&g_Config.m_GfxRefreshRate, &Button, (minimum(g_Config.m_GfxRefreshRate, 1000)) / 1000.0f) * 1000.0f + 0.1f); if(g_Config.m_GfxRefreshRate <= 1000 || NewRefreshRate < 1000) g_Config.m_GfxRefreshRate = NewRefreshRate; @@ -1391,9 +1381,8 @@ void CMenus::RenderSettingsSound(CUIRect MainView) MainView.HSplitTop(5.0f, &Button, &MainView); MainView.HSplitTop(20.0f, &Button, &MainView); Button.VSplitLeft(190.0f, &Label, &Button); - Button.HMargin(2.0f, &Button); UI()->DoLabelScaled(&Label, Localize("Sound volume"), 14.0f, -1); - g_Config.m_SndVolume = (int)(DoScrollbarH(&g_Config.m_SndVolume, &Button, g_Config.m_SndVolume / 100.0f) * 100.0f); + g_Config.m_SndVolume = (int)(m_UIEx.DoScrollbarH(&g_Config.m_SndVolume, &Button, g_Config.m_SndVolume / 100.0f) * 100.0f); } // volume slider game sounds @@ -1402,9 +1391,8 @@ void CMenus::RenderSettingsSound(CUIRect MainView) MainView.HSplitTop(5.0f, &Button, &MainView); MainView.HSplitTop(20.0f, &Button, &MainView); Button.VSplitLeft(190.0f, &Label, &Button); - Button.HMargin(2.0f, &Button); UI()->DoLabelScaled(&Label, Localize("Game sound volume"), 14.0f, -1); - g_Config.m_SndGameSoundVolume = (int)(DoScrollbarH(&g_Config.m_SndGameSoundVolume, &Button, g_Config.m_SndGameSoundVolume / 100.0f) * 100.0f); + g_Config.m_SndGameSoundVolume = (int)(m_UIEx.DoScrollbarH(&g_Config.m_SndGameSoundVolume, &Button, g_Config.m_SndGameSoundVolume / 100.0f) * 100.0f); } // volume slider gui sounds @@ -1413,9 +1401,8 @@ void CMenus::RenderSettingsSound(CUIRect MainView) MainView.HSplitTop(5.0f, &Button, &MainView); MainView.HSplitTop(20.0f, &Button, &MainView); Button.VSplitLeft(190.0f, &Label, &Button); - Button.HMargin(2.0f, &Button); UI()->DoLabelScaled(&Label, Localize("Chat sound volume"), 14.0f, -1); - g_Config.m_SndChatSoundVolume = (int)(DoScrollbarH(&g_Config.m_SndChatSoundVolume, &Button, g_Config.m_SndChatSoundVolume / 100.0f) * 100.0f); + g_Config.m_SndChatSoundVolume = (int)(m_UIEx.DoScrollbarH(&g_Config.m_SndChatSoundVolume, &Button, g_Config.m_SndChatSoundVolume / 100.0f) * 100.0f); } // volume slider map sounds @@ -1424,9 +1411,8 @@ void CMenus::RenderSettingsSound(CUIRect MainView) MainView.HSplitTop(5.0f, &Button, &MainView); MainView.HSplitTop(20.0f, &Button, &MainView); Button.VSplitLeft(190.0f, &Label, &Button); - Button.HMargin(2.0f, &Button); UI()->DoLabelScaled(&Label, Localize("Map sound volume"), 14.0f, -1); - g_Config.m_SndMapSoundVolume = (int)(DoScrollbarH(&g_Config.m_SndMapSoundVolume, &Button, g_Config.m_SndMapSoundVolume / 100.0f) * 100.0f); + g_Config.m_SndMapSoundVolume = (int)(m_UIEx.DoScrollbarH(&g_Config.m_SndMapSoundVolume, &Button, g_Config.m_SndMapSoundVolume / 100.0f) * 100.0f); } // volume slider background music @@ -1435,9 +1421,8 @@ void CMenus::RenderSettingsSound(CUIRect MainView) MainView.HSplitTop(5.0f, &Button, &MainView); MainView.HSplitTop(20.0f, &Button, &MainView); Button.VSplitLeft(190.0f, &Label, &Button); - Button.HMargin(2.0f, &Button); UI()->DoLabelScaled(&Label, Localize("Background music volume"), 14.0f, -1); - g_Config.m_SndBackgroundMusicVolume = (int)(DoScrollbarH(&g_Config.m_SndBackgroundMusicVolume, &Button, g_Config.m_SndBackgroundMusicVolume / 100.0f) * 100.0f); + g_Config.m_SndBackgroundMusicVolume = (int)(m_UIEx.DoScrollbarH(&g_Config.m_SndBackgroundMusicVolume, &Button, g_Config.m_SndBackgroundMusicVolume / 100.0f) * 100.0f); } } @@ -1678,7 +1663,7 @@ ColorHSLA CMenus::RenderHSLColorPicker(const CUIRect *pRect, unsigned int *pColo ColorRGBA Outline(1, 1, 1, 0.25f); const float OutlineSize = 3.0f; - Outline.a *= ButtonColorMul(pColor); + Outline.a *= UI()->ButtonColorMul(pColor); CUIRect Rect; pRect->Margin(OutlineSize, &Rect); @@ -2005,7 +1990,9 @@ ColorHSLA CMenus::RenderHSLScrollbars(CUIRect *pRect, unsigned int *pColor, bool RenderTools()->DrawUIRect(&Button, ColorRGBA(0.15f, 0.15f, 0.15f, 1.0f), CUI::CORNER_ALL, 1.0f); - Button.Margin(2.0f, &Button); + CUIRect Rail; + Button.Margin(2.0f, &Rail); + str_format(aBuf, sizeof(aBuf), "%s: %03d", aLabels[i], (int)(*paComponent[i] * 255)); UI()->DoLabelScaled(&Label, aBuf, 14.0f, -1); @@ -2016,17 +2003,17 @@ ColorHSLA CMenus::RenderHSLScrollbars(CUIRect *pRect, unsigned int *pColor, bool if(i == 0) { ColorInner = CurColorPure; - RenderHSLColorsRect(&Button); + RenderHSLColorsRect(&Rail); } else if(i == 1) { - RenderHSLSatRect(&Button, CurColorPure); + RenderHSLSatRect(&Rail, CurColorPure); ColorInner = color_cast(ColorHSLA(CurColorPureHSLA.r, *paComponent[1], CurColorPureHSLA.b, 1)); } else if(i == 2) { ColorRGBA CurColorSat = color_cast(ColorHSLA(CurColorPureHSLA.r, *paComponent[1], 0.5f, 1)); - RenderHSLLightRect(&Button, CurColorSat); + RenderHSLLightRect(&Rail, CurColorSat); float LightVal = *paComponent[2]; if(ClampedLight) LightVal = ColorHSLA::DARKEST_LGT + LightVal * (1.0f - ColorHSLA::DARKEST_LGT); @@ -2035,14 +2022,14 @@ ColorHSLA CMenus::RenderHSLScrollbars(CUIRect *pRect, unsigned int *pColor, bool else if(i == 3) { ColorRGBA CurColorFull = color_cast(ColorHSLA(CurColorPureHSLA.r, *paComponent[1], *paComponent[2], 1)); - RenderHSLAlphaRect(&Button, CurColorFull); + RenderHSLAlphaRect(&Rail, CurColorFull); float LightVal = *paComponent[2]; if(ClampedLight) LightVal = ColorHSLA::DARKEST_LGT + LightVal * (1.0f - ColorHSLA::DARKEST_LGT); ColorInner = color_cast(ColorHSLA(CurColorPureHSLA.r, *paComponent[1], LightVal, *paComponent[3])); } - *paComponent[i] = DoScrollbarH(&((char *)pColor)[i], &Button, *paComponent[i], true, &ColorInner); + *paComponent[i] = m_UIEx.DoScrollbarH(&((char *)pColor)[i], &Button, *paComponent[i], &ColorInner); } *pColor = Color.Pack(Alpha); @@ -2402,12 +2389,11 @@ void CMenus::RenderSettingsDDNet(CUIRect MainView) Button.VSplitLeft(160.0f, &LeftLeft, &Button); Button.VSplitLeft(140.0f, &Label, &Button); - Button.HMargin(2.0f, &Button); char aBuf[256]; str_format(aBuf, sizeof(aBuf), Localize("Default length: %d"), g_Config.m_ClReplayLength); UI()->DoLabelScaled(&Label, aBuf, 14.0f, -1); - int NewValue = (int)(DoScrollbarH(&g_Config.m_ClReplayLength, &Button, (minimum(g_Config.m_ClReplayLength, 600) - 10) / 590.0f) * 590.0f) + 10; + int NewValue = (int)(m_UIEx.DoScrollbarH(&g_Config.m_ClReplayLength, &Button, (minimum(g_Config.m_ClReplayLength, 600) - 10) / 590.0f) * 590.0f) + 10; if(g_Config.m_ClReplayLength < 600 || NewValue < 600) g_Config.m_ClReplayLength = minimum(NewValue, 600); @@ -2461,9 +2447,8 @@ void CMenus::RenderSettingsDDNet(CUIRect MainView) CUIRect Button, Label; Left.HSplitTop(20.0f, &Button, &Left); Button.VSplitLeft(120.0f, &Label, &Button); - Button.HMargin(2.0f, &Button); UI()->DoLabelScaled(&Label, Localize("Overlay entities"), 14.0f, -1); - g_Config.m_ClOverlayEntities = (int)(DoScrollbarH(&g_Config.m_ClOverlayEntities, &Button, g_Config.m_ClOverlayEntities / 100.0f) * 100.0f); + g_Config.m_ClOverlayEntities = (int)(m_UIEx.DoScrollbarH(&g_Config.m_ClOverlayEntities, &Button, g_Config.m_ClOverlayEntities / 100.0f) * 100.0f); } { @@ -2472,9 +2457,8 @@ void CMenus::RenderSettingsDDNet(CUIRect MainView) Button.VSplitMid(&LeftLeft, &Button); Button.VSplitLeft(50.0f, &Label, &Button); - Button.HMargin(2.0f, &Button); UI()->DoLabelScaled(&Label, Localize("Size"), 14.0f, -1); - g_Config.m_ClTextEntitiesSize = (int)(DoScrollbarH(&g_Config.m_ClTextEntitiesSize, &Button, g_Config.m_ClTextEntitiesSize / 100.0f) * 100.0f); + g_Config.m_ClTextEntitiesSize = (int)(m_UIEx.DoScrollbarH(&g_Config.m_ClTextEntitiesSize, &Button, g_Config.m_ClTextEntitiesSize / 100.0f) * 100.0f); if(DoButton_CheckBox(&g_Config.m_ClTextEntities, Localize("Show text entities"), g_Config.m_ClTextEntities, &LeftLeft)) { @@ -2488,9 +2472,8 @@ void CMenus::RenderSettingsDDNet(CUIRect MainView) Button.VSplitMid(&LeftLeft, &Button); Button.VSplitLeft(50.0f, &Label, &Button); - Button.HMargin(2.0f, &Button); UI()->DoLabelScaled(&Label, Localize("Alpha"), 14.0f, -1); - g_Config.m_ClShowOthersAlpha = (int)(DoScrollbarH(&g_Config.m_ClShowOthersAlpha, &Button, g_Config.m_ClShowOthersAlpha / 100.0f) * 100.0f); + g_Config.m_ClShowOthersAlpha = (int)(m_UIEx.DoScrollbarH(&g_Config.m_ClShowOthersAlpha, &Button, g_Config.m_ClShowOthersAlpha / 100.0f) * 100.0f); if(DoButton_CheckBox(&g_Config.m_ClShowOthers, Localize("Show others"), g_Config.m_ClShowOthers == 1, &LeftLeft)) { @@ -2517,9 +2500,7 @@ void CMenus::RenderSettingsDDNet(CUIRect MainView) char aBuf[64]; str_format(aBuf, sizeof(aBuf), "%s: %i", Localize("Default zoom"), g_Config.m_ClDefaultZoom); UI()->DoLabelScaled(&Label, aBuf, 14.0f, -1); - //Right.HSplitTop(20.0f, &Button, 0); - Button.HMargin(2.0f, &Button); - g_Config.m_ClDefaultZoom = static_cast(DoScrollbarH(&g_Config.m_ClDefaultZoom, &Button, g_Config.m_ClDefaultZoom / 20.0f) * 20.0f + 0.1f); + g_Config.m_ClDefaultZoom = static_cast(m_UIEx.DoScrollbarH(&g_Config.m_ClDefaultZoom, &Button, g_Config.m_ClDefaultZoom / 20.0f) * 20.0f + 0.1f); Right.HSplitTop(20.0f, &Button, &Right); if(DoButton_CheckBox(&g_Config.m_ClAntiPing, Localize("AntiPing"), g_Config.m_ClAntiPing, &Button)) diff --git a/src/game/client/ui.cpp b/src/game/client/ui.cpp index 1a011ed0b..b57dddc27 100644 --- a/src/game/client/ui.cpp +++ b/src/game/client/ui.cpp @@ -135,11 +135,9 @@ int CUI::Update(float Mx, float My, float Mwx, float Mwy, int Buttons) return 0; } -int CUI::MouseInside(const CUIRect *r) const +bool CUI::MouseInside(const CUIRect *pRect) const { - if(m_MouseX >= r->x && m_MouseX < r->x + r->w && m_MouseY >= r->y && m_MouseY < r->y + r->h) - return 1; - return 0; + return pRect->Inside(m_MouseX, m_MouseY); } void CUI::ConvertMouseMove(float *x, float *y) const @@ -149,6 +147,15 @@ void CUI::ConvertMouseMove(float *x, float *y) const *y = *y * Fac; } +float CUI::ButtonColorMul(const void *pID) +{ + if(ActiveItem() == pID) + return ButtonColorMulActive(); + else if(HotItem() == pID) + return ButtonColorMulHot(); + return ButtonColorMulDefault(); +} + CUIRect *CUI::Screen() { float Aspect = Graphics()->ScreenAspect(); @@ -367,6 +374,11 @@ void CUIRect::HMargin(float Cut, CUIRect *pOtherRect) const pOtherRect->h = r.h - 2 * Cut; } +bool CUIRect::Inside(float x, float y) const +{ + return x >= this->x && x < this->x + this->w && y >= this->y && y < this->y + this->h; +} + int CUI::DoButtonLogic(const void *pID, const char *pText, int Checked, const CUIRect *pRect) { return DoButtonLogic(pID, Checked, pRect); diff --git a/src/game/client/ui.h b/src/game/client/ui.h index 5b9589814..cf3253ce8 100644 --- a/src/game/client/ui.h +++ b/src/game/client/ui.h @@ -100,6 +100,8 @@ public: * @param pOtherRect The CUIRect to place inside *this* CUIRect */ void HMargin(float Cut, CUIRect *pOtherRect) const; + + bool Inside(float x, float y) const; }; struct SUIAnimator @@ -256,9 +258,14 @@ public: const void *ActiveItem() const { return m_pActiveItem; } const void *LastActiveItem() const { return m_pLastActiveItem; } - int MouseInside(const CUIRect *pRect) const; + bool MouseInside(const CUIRect *pRect) const; void ConvertMouseMove(float *x, float *y) const; + float ButtonColorMulActive() { return 0.5f; } + float ButtonColorMulHot() { return 1.5f; } + float ButtonColorMulDefault() { return 1.0f; } + float ButtonColorMul(const void *pID); + CUIRect *Screen(); void MapScreen(); float PixelSize(); diff --git a/src/game/client/ui_ex.cpp b/src/game/client/ui_ex.cpp index 377444fc6..bd131f084 100644 --- a/src/game/client/ui_ex.cpp +++ b/src/game/client/ui_ex.cpp @@ -16,6 +16,8 @@ CUIEx::CUIEx(CUI *pUI, IKernel *pKernel, CRenderTools *pRenderTools, IInput::CEvent *pInputEventsArray, int *pInputEventCount) { Init(pUI, pKernel, pRenderTools, pInputEventsArray, pInputEventCount); + + m_MouseSlow = false; } void CUIEx::Init(CUI *pUI, IKernel *pKernel, CRenderTools *pRenderTools, IInput::CEvent *pInputEventsArray, int *pInputEventCount) @@ -31,6 +33,181 @@ void CUIEx::Init(CUI *pUI, IKernel *pKernel, CRenderTools *pRenderTools, IInput: m_pTextRender = Kernel()->RequestInterface(); } +void CUIEx::ConvertMouseMove(float *pX, float *pY) const +{ + UI()->ConvertMouseMove(pX, pY); + + if(m_MouseSlow) + { + const float SlowMouseFactor = 0.05f; + *pX *= SlowMouseFactor; + *pY *= SlowMouseFactor; + } +} + +float CUIEx::DoScrollbarV(const void *pID, const CUIRect *pRect, float Current) +{ + static float s_OffsetY; + + CUIRect Rail; + pRect->Margin(5.0f, &Rail); + + CUIRect Handle; + Rail.HSplitTop(clamp(33.0f, Rail.h / 8.0f, Rail.h), &Handle, 0); + Current = clamp(Current, 0.0f, 1.0f); + Handle.y = Rail.y + (Rail.h - Handle.h) * Current; + + // logic + const bool InsideRail = UI()->MouseInside(&Rail); + const bool InsideHandle = UI()->MouseInside(&Handle); + bool Grabbed = false; // whether to apply the offset + + if(UI()->ActiveItem() == pID) + { + if(UI()->MouseButton(0)) + { + Grabbed = true; + if(Input()->KeyIsPressed(KEY_LSHIFT) || Input()->KeyIsPressed(KEY_RSHIFT)) + m_MouseSlow = true; + } + else + { + UI()->SetActiveItem(0); + } + } + else if(UI()->HotItem() == pID) + { + if(UI()->MouseButton(0)) + { + UI()->SetActiveItem(pID); + s_OffsetY = UI()->MouseY() - Handle.y; + Grabbed = true; + } + } + else if(UI()->MouseButtonClicked(0) && !InsideHandle && InsideRail) + { + UI()->SetActiveItem(pID); + s_OffsetY = Handle.h * 0.5f; + Grabbed = true; + } + + if(InsideHandle) + UI()->SetHotItem(pID); + + float ReturnValue = Current; + if(Grabbed) + { + const float Min = Rail.y; + const float Max = Rail.h - Handle.h; + const float Cur = UI()->MouseY() - s_OffsetY; + ReturnValue = clamp((Cur - Min) / Max, 0.0f, 1.0f); + } + + // render + RenderTools()->DrawUIRect(&Rail, ColorRGBA(0, 0, 0, 0.25f), CUI::CORNER_ALL, Rail.w / 2.0f); + + float ColorSlider; + if(UI()->ActiveItem() == pID) + ColorSlider = 1.0f; + else if(UI()->HotItem() == pID) + ColorSlider = 0.9f; + else + ColorSlider = 0.75f; + + RenderTools()->DrawUIRect(&Handle, ColorRGBA(ColorSlider, ColorSlider, ColorSlider, 0.75f), CUI::CORNER_ALL, Handle.w / 2.0f); + + return ReturnValue; +} + +float CUIEx::DoScrollbarH(const void *pID, const CUIRect *pRect, float Current, const ColorRGBA *pColorInner) +{ + static float s_OffsetX; + + CUIRect Rail; + if(pColorInner) + Rail = *pRect; + else + pRect->HMargin(5.0f, &Rail); + + CUIRect Handle; + Rail.VSplitLeft(pColorInner ? 8.0f : clamp(33.0f, Rail.w / 8.0f, Rail.w), &Handle, 0); + Current = clamp(Current, 0.0f, 1.0f); + Handle.x += (Rail.w - Handle.w) * Current; + + // logic + const bool InsideRail = UI()->MouseInside(&Rail); + const bool InsideHandle = UI()->MouseInside(&Handle); + bool Grabbed = false; // whether to apply the offset + + if(UI()->ActiveItem() == pID) + { + if(UI()->MouseButton(0)) + { + Grabbed = true; + if(Input()->KeyIsPressed(KEY_LSHIFT) || Input()->KeyIsPressed(KEY_RSHIFT)) + m_MouseSlow = true; + } + else + { + UI()->SetActiveItem(0); + } + } + else if(UI()->HotItem() == pID) + { + if(UI()->MouseButton(0)) + { + UI()->SetActiveItem(pID); + s_OffsetX = UI()->MouseX() - Handle.x; + Grabbed = true; + } + } + else if(UI()->MouseButtonClicked(0) && !InsideHandle && InsideRail) + { + UI()->SetActiveItem(pID); + s_OffsetX = Handle.w * 0.5f; + Grabbed = true; + } + + if(InsideHandle) + UI()->SetHotItem(pID); + + float ReturnValue = Current; + if(Grabbed) + { + const float Min = Rail.x; + const float Max = Rail.w - Handle.w; + const float Cur = UI()->MouseX() - s_OffsetX; + ReturnValue = clamp((Cur - Min) / Max, 0.0f, 1.0f); + } + + // render + if(pColorInner) + { + CUIRect Slider; + Handle.VMargin(-2.0f, &Slider); + Slider.HMargin(-3.0f, &Slider); + RenderTools()->DrawUIRect(&Slider, ColorRGBA(0.15f, 0.15f, 0.15f, 1.0f), CUI::CORNER_ALL, 5.0f); + Slider.Margin(2.0f, &Slider); + RenderTools()->DrawUIRect(&Slider, *pColorInner, CUI::CORNER_ALL, 3.0f); + } + else + { + RenderTools()->DrawUIRect(&Rail, ColorRGBA(0, 0, 0, 0.25f), CUI::CORNER_ALL, Rail.h / 2.0f); + + float ColorSlider; + if(UI()->ActiveItem() == pID) + ColorSlider = 1.0f; + else if(UI()->HotItem() == pID) + ColorSlider = 0.9f; + else + ColorSlider = 0.75f; + + RenderTools()->DrawUIRect(&Handle, ColorRGBA(ColorSlider, ColorSlider, ColorSlider, 0.75f), CUI::CORNER_ALL, Handle.h / 2.0f); + } + + return ReturnValue; +} + int CUIEx::DoEditBox(void *pID, const CUIRect *pRect, char *pStr, unsigned StrSize, float FontSize, float *Offset, bool Hidden, int Corners, const char *pEmptyText) { int Inside = UI()->MouseInside(pRect); diff --git a/src/game/client/ui_ex.h b/src/game/client/ui_ex.h index e5d1d42e4..c9ffeefc8 100644 --- a/src/game/client/ui_ex.h +++ b/src/game/client/ui_ex.h @@ -32,6 +32,7 @@ class CUIEx int m_MousePressY = 0; int m_MouseCurX = 0; int m_MouseCurY = 0; + bool m_MouseSlow; int m_CurSelStart = 0; int m_CurSelEnd = 0; void *m_pSelItem = nullptr; @@ -39,12 +40,12 @@ class CUIEx int m_CurCursor = 0; protected: - CUI *UI() { return m_pUI; } - IInput *Input() { return m_pInput; } - ITextRender *TextRender() { return m_pTextRender; } - IKernel *Kernel() { return m_pKernel; } - IGraphics *Graphics() { return m_pGraphics; } - CRenderTools *RenderTools() { return m_pRenderTools; } + CUI *UI() const { return m_pUI; } + IInput *Input() const { return m_pInput; } + ITextRender *TextRender() const { return m_pTextRender; } + IKernel *Kernel() const { return m_pKernel; } + IGraphics *Graphics() const { return m_pGraphics; } + CRenderTools *RenderTools() const { return m_pRenderTools; } public: CUIEx(CUI *pUI, IKernel *pKernel, CRenderTools *pRenderTools, IInput::CEvent *pInputEventsArray, int *pInputEventCount); @@ -52,6 +53,11 @@ public: void Init(CUI *pUI, IKernel *pKernel, CRenderTools *pRenderTools, IInput::CEvent *pInputEventsArray, int *pInputEventCount); + void ConvertMouseMove(float *pX, float *pY) const; + void ResetMouseSlow() { m_MouseSlow = false; } + + float DoScrollbarV(const void *pID, const CUIRect *pRect, float Current); + float DoScrollbarH(const void *pID, const CUIRect *pRect, float Current, const ColorRGBA *pColorInner = NULL); int DoEditBox(void *pID, const CUIRect *pRect, char *pStr, unsigned StrSize, float FontSize, float *Offset, bool Hidden = false, int Corners = CUI::CORNER_ALL, const char *pEmptyText = ""); }; diff --git a/src/game/editor/editor.cpp b/src/game/editor/editor.cpp index 6205261c0..b403cb5f1 100644 --- a/src/game/editor/editor.cpp +++ b/src/game/editor/editor.cpp @@ -315,7 +315,7 @@ int CEditor::DoClearableEditBox(void *pID, void *pClearID, const CUIRect *pRect, ReturnValue = true; } - RenderTools()->DrawUIRect(&ClearButton, ColorRGBA(1, 1, 1, 0.33f * ButtonColorMul(pClearID)), Corners & ~CUI::CORNER_L, 3.0f); + RenderTools()->DrawUIRect(&ClearButton, ColorRGBA(1, 1, 1, 0.33f * UI()->ButtonColorMul(pClearID)), Corners & ~CUI::CORNER_L, 3.0f); UI()->DoLabel(&ClearButton, "×", ClearButton.h * 0.8f, 0); if(UI()->DoButtonLogic(pClearID, "×", 0, &ClearButton)) { @@ -333,71 +333,6 @@ int CEditor::DoEditBox(void *pID, const CUIRect *pRect, char *pStr, unsigned Str return m_UIEx.DoEditBox(pID, pRect, pStr, StrSize, FontSize, Offset, Hidden, Corners); } -float CEditor::ButtonColorMul(const void *pID) -{ - if(UI()->ActiveItem() == pID) - return 0.5f; - else if(UI()->HotItem() == pID) - return 1.5f; - return 1.0f; -} - -float CEditor::UiDoScrollbarV(const void *pID, const CUIRect *pRect, float Current) -{ - CUIRect Handle; - static float s_OffsetY; - pRect->HSplitTop(33, &Handle, 0); - - Handle.y += (pRect->h - Handle.h) * Current; - - // logic - float Ret = Current; - int Inside = UI()->MouseInside(&Handle); - - if(UI()->ActiveItem() == pID) - { - if(!UI()->MouseButton(0)) - UI()->SetActiveItem(0); - - float Min = pRect->y; - float Max = pRect->h - Handle.h; - float Cur = UI()->MouseY() - s_OffsetY; - Ret = (Cur - Min) / Max; - if(Ret < 0.0f) - Ret = 0.0f; - if(Ret > 1.0f) - Ret = 1.0f; - } - else if(UI()->HotItem() == pID) - { - if(UI()->MouseButton(0)) - { - UI()->SetActiveItem(pID); - s_OffsetY = UI()->MouseY() - Handle.y; - } - } - - if(Inside) - UI()->SetHotItem(pID); - - // render - CUIRect Rail; - pRect->VMargin(5.0f, &Rail); - RenderTools()->DrawUIRect(&Rail, ColorRGBA(1, 1, 1, 0.25f), 0, 0.0f); - - CUIRect Slider = Handle; - Slider.w = Rail.x - Slider.x; - RenderTools()->DrawUIRect(&Slider, ColorRGBA(1, 1, 1, 0.25f), CUI::CORNER_L, 2.5f); - Slider.x = Rail.x + Rail.w; - RenderTools()->DrawUIRect(&Slider, ColorRGBA(1, 1, 1, 0.25f), CUI::CORNER_R, 2.5f); - - Slider = Handle; - Slider.Margin(5.0f, &Slider); - RenderTools()->DrawUIRect(&Slider, ColorRGBA(1, 1, 1, 0.25f * ButtonColorMul(pID)), CUI::CORNER_ALL, 2.5f); - - return Ret; -} - ColorRGBA CEditor::GetButtonColor(const void *pID, int Checked) { if(Checked < 0) @@ -3127,16 +3062,14 @@ int CEditor::DoProperties(CUIRect *pToolBox, CProperty *pProps, int *pIDs, int * void CEditor::RenderLayers(CUIRect ToolBox, CUIRect View) { - CUIRect LayersBox = ToolBox; - if(!m_GuiActive) return; + CUIRect LayersBox = ToolBox; CUIRect Slot, Button; char aBuf[64]; float LayersHeight = 12.0f; // Height of AddGroup button - static int s_ScrollBar = 0; static float s_ScrollValue = 0; for(int g = 0; g < m_Map.m_lGroups.size(); g++) @@ -3153,10 +3086,8 @@ void CEditor::RenderLayers(CUIRect ToolBox, CUIRect View) if(LayersHeight > LayersBox.h) // Do we even need a scrollbar? { CUIRect Scroll; - LayersBox.VSplitRight(15.0f, &LayersBox, &Scroll); - LayersBox.VSplitRight(3.0f, &LayersBox, 0); // extra spacing - Scroll.HMargin(5.0f, &Scroll); - s_ScrollValue = UiDoScrollbarV(&s_ScrollBar, &Scroll, s_ScrollValue); + LayersBox.VSplitRight(20.0f, &LayersBox, &Scroll); + s_ScrollValue = UIEx()->DoScrollbarV(&s_ScrollValue, &Scroll, s_ScrollValue); if(UI()->MouseInside(&Scroll) || UI()->MouseInside(&LayersBox)) { @@ -3791,21 +3722,18 @@ void CEditor::SortImages() void CEditor::RenderImages(CUIRect ToolBox, CUIRect View) { - static int s_ScrollBar = 0; + if(!m_GuiActive) + return; + static float s_ScrollValue = 0; float ImagesHeight = 30.0f + 14.0f * m_Map.m_lImages.size() + 27.0f; float ScrollDifference = ImagesHeight - ToolBox.h; - if(!m_GuiActive) - return; - if(ImagesHeight > ToolBox.h) // Do we even need a scrollbar? { CUIRect Scroll; - ToolBox.VSplitRight(15.0f, &ToolBox, &Scroll); - ToolBox.VSplitRight(3.0f, &ToolBox, 0); // extra spacing - Scroll.HMargin(5.0f, &Scroll); - s_ScrollValue = UiDoScrollbarV(&s_ScrollBar, &Scroll, s_ScrollValue); + ToolBox.VSplitRight(20.0f, &ToolBox, &Scroll); + s_ScrollValue = UIEx()->DoScrollbarV(&s_ScrollValue, &Scroll, s_ScrollValue); if(UI()->MouseInside(&Scroll) || UI()->MouseInside(&ToolBox)) { @@ -4012,21 +3940,18 @@ void CEditor::RenderImages(CUIRect ToolBox, CUIRect View) void CEditor::RenderSounds(CUIRect ToolBox, CUIRect View) { - static int s_ScrollBar = 0; + if(!m_GuiActive) + return; + static float s_ScrollValue = 0; float SoundsHeight = 30.0f + 14.0f * m_Map.m_lSounds.size() + 27.0f; float ScrollDifference = SoundsHeight - ToolBox.h; - if(!m_GuiActive) - return; - if(SoundsHeight > ToolBox.h) // Do we even need a scrollbar? { CUIRect Scroll; - ToolBox.VSplitRight(15.0f, &ToolBox, &Scroll); - ToolBox.VSplitRight(3.0f, &ToolBox, 0); // extra spacing - Scroll.HMargin(5.0f, &Scroll); - s_ScrollValue = UiDoScrollbarV(&s_ScrollBar, &Scroll, s_ScrollValue); + ToolBox.VSplitRight(20.0f, &ToolBox, &Scroll); + s_ScrollValue = UIEx()->DoScrollbarV(&s_ScrollValue, &Scroll, s_ScrollValue); if(UI()->MouseInside(&Scroll) || UI()->MouseInside(&ToolBox)) { @@ -4219,7 +4144,7 @@ void CEditor::RenderFileDialog() View.HSplitBottom(10.0f, &View, 0); // some spacing if(m_FileDialogFileType == CEditor::FILETYPE_IMG) View.VSplitMid(&View, &Preview); - View.VSplitRight(15.0f, &View, &Scroll); + View.VSplitRight(20.0f, &View, &Scroll); // title RenderTools()->DrawUIRect(&Title, ColorRGBA(1, 1, 1, 0.25f), CUI::CORNER_ALL, 4.0f); @@ -4269,7 +4194,7 @@ void CEditor::RenderFileDialog() // clearSearchbox button { static int s_ClearButton = 0; - RenderTools()->DrawUIRect(&ClearBox, ColorRGBA(1, 1, 1, 0.33f * ButtonColorMul(&s_ClearButton)), CUI::CORNER_R, 3.0f); + RenderTools()->DrawUIRect(&ClearBox, ColorRGBA(1, 1, 1, 0.33f * UI()->ButtonColorMul(&s_ClearButton)), CUI::CORNER_R, 3.0f); UI()->DoLabel(&ClearBox, "×", 10.0f, 0); if(UI()->DoButtonLogic(&s_ClearButton, "×", 0, &ClearBox)) { @@ -4285,9 +4210,7 @@ void CEditor::RenderFileDialog() m_FileDialogOpening = false; int Num = (int)(View.h / 17.0f) + 1; - static int ScrollBar = 0; - Scroll.HMargin(5.0f, &Scroll); - m_FileDialogScrollValue = UiDoScrollbarV(&ScrollBar, &Scroll, m_FileDialogScrollValue); + m_FileDialogScrollValue = UIEx()->DoScrollbarV(&m_FileDialogScrollValue, &Scroll, m_FileDialogScrollValue); int ScrollNum = 0; for(int i = 0; i < m_FileList.size(); i++) @@ -4674,11 +4597,8 @@ void CEditor::RenderUndoList(CUIRect View) { CUIRect List, Preview, Scroll, Button; View.VSplitMid(&List, &Preview); - List.VSplitRight(15.0f, &List, &Scroll); - //int Num = (int)(List.h/17.0f)+1; - static int ScrollBar = 0; - Scroll.HMargin(5.0f, &Scroll); - m_UndoScrollValue = UiDoScrollbarV(&ScrollBar, &Scroll, m_UndoScrollValue); + List.VSplitRight(20.0f, &List, &Scroll); + m_UndoScrollValue = UIEx()->DoScrollbarV(&m_UndoScrollValue, &Scroll, m_UndoScrollValue); float TopY = List.y; float Height = List.h; @@ -5428,7 +5348,6 @@ void CEditor::RenderServerSettingsEditor(CUIRect View, bool ShowServerSettingsEd View.Margin(1.0f, &ListBox); float ListHeight = 17.0f * m_Map.m_lSettings.size(); - static int s_ScrollBar = 0; static float s_ScrollValue = 0; float ScrollDifference = ListHeight - ListBox.h; @@ -5436,10 +5355,8 @@ void CEditor::RenderServerSettingsEditor(CUIRect View, bool ShowServerSettingsEd if(ListHeight > ListBox.h) // Do we even need a scrollbar? { CUIRect Scroll; - ListBox.VSplitRight(15.0f, &ListBox, &Scroll); - ListBox.VSplitRight(3.0f, &ListBox, 0); // extra spacing - Scroll.HMargin(5.0f, &Scroll); - s_ScrollValue = UiDoScrollbarV(&s_ScrollBar, &Scroll, s_ScrollValue); + ListBox.VSplitRight(20.0f, &ListBox, &Scroll); + s_ScrollValue = UIEx()->DoScrollbarV(&s_ScrollValue, &Scroll, s_ScrollValue); if(UI()->MouseInside(&Scroll) || UI()->MouseInside(&ListBox)) { @@ -6325,7 +6242,8 @@ void CEditor::UpdateAndRender() float rx = 0, ry = 0; { Input()->MouseRelative(&rx, &ry); - UI()->ConvertMouseMove(&rx, &ry); + m_UIEx.ConvertMouseMove(&rx, &ry); + m_UIEx.ResetMouseSlow(); m_MouseDeltaX = rx; m_MouseDeltaY = ry; diff --git a/src/game/editor/editor.h b/src/game/editor/editor.h index 20fd1fcf2..2e8e37d8c 100644 --- a/src/game/editor/editor.h +++ b/src/game/editor/editor.h @@ -652,6 +652,7 @@ public: class ITextRender *TextRender() { return m_pTextRender; }; class IStorage *Storage() { return m_pStorage; }; CUI *UI() { return &m_UI; } + CUIEx *UIEx() { return &m_UIEx; } CRenderTools *RenderTools() { return &m_RenderTools; } CEditor() : @@ -1024,8 +1025,6 @@ public: void PopupSelectSoundInvoke(int Current, float x, float y); int PopupSelectSoundResult(); - float ButtonColorMul(const void *pID); - void DoQuadEnvelopes(const array &m_lQuads, IGraphics::CTextureHandle Texture = IGraphics::CTextureHandle()); void DoQuadEnvPoint(const CQuad *pQuad, int QIndex, int pIndex); void DoQuadPoint(CQuad *pQuad, int QuadIndex, int v); @@ -1035,7 +1034,6 @@ public: void DoMapEditor(CUIRect View); void DoToolbar(CUIRect Toolbar); void DoQuad(CQuad *pQuad, int Index); - float UiDoScrollbarV(const void *pID, const CUIRect *pRect, float Current); ColorRGBA GetButtonColor(const void *pID, int Checked); static void ReplaceImage(const char *pFilename, int StorageType, void *pUser); diff --git a/src/game/editor/popups.cpp b/src/game/editor/popups.cpp index 36676d18f..3101608fd 100644 --- a/src/game/editor/popups.cpp +++ b/src/game/editor/popups.cpp @@ -1207,7 +1207,6 @@ int CEditor::PopupSelectImage(CEditor *pEditor, CUIRect View, void *pContext) int ShowImage = g_SelectImageCurrent; - static int s_ScrollBar = 0; static float s_ScrollValue = 0; float ImagesHeight = pEditor->m_Map.m_lImages.size() * 14; float ScrollDifference = ImagesHeight - ButtonBar.h; @@ -1215,10 +1214,8 @@ int CEditor::PopupSelectImage(CEditor *pEditor, CUIRect View, void *pContext) if(pEditor->m_Map.m_lImages.size() > 20) // Do we need a scrollbar? { CUIRect Scroll; - ButtonBar.VSplitRight(15.0f, &ButtonBar, &Scroll); - ButtonBar.VSplitRight(3.0f, &ButtonBar, 0); // extra spacing - Scroll.HMargin(5.0f, &Scroll); - s_ScrollValue = pEditor->UiDoScrollbarV(&s_ScrollBar, &Scroll, s_ScrollValue); + ButtonBar.VSplitRight(20.0f, &ButtonBar, &Scroll); + s_ScrollValue = pEditor->UIEx()->DoScrollbarV(&s_ScrollValue, &Scroll, s_ScrollValue); if(pEditor->UI()->MouseInside(&Scroll) || pEditor->UI()->MouseInside(&ButtonBar)) { @@ -1317,7 +1314,6 @@ int CEditor::PopupSelectSound(CEditor *pEditor, CUIRect View, void *pContext) View.VSplitLeft(80.0f, &ButtonBar, &View); View.Margin(10.0f, &SoundView); - static int s_ScrollBar = 0; static float s_ScrollValue = 0; float SoundsHeight = pEditor->m_Map.m_lSounds.size() * 14; float ScrollDifference = SoundsHeight - ButtonBar.h; @@ -1325,10 +1321,8 @@ int CEditor::PopupSelectSound(CEditor *pEditor, CUIRect View, void *pContext) if(pEditor->m_Map.m_lSounds.size() > 20) // Do we need a scrollbar? { CUIRect Scroll; - ButtonBar.VSplitRight(15.0f, &ButtonBar, &Scroll); - ButtonBar.VSplitRight(3.0f, &ButtonBar, 0); // extra spacing - Scroll.HMargin(5.0f, &Scroll); - s_ScrollValue = pEditor->UiDoScrollbarV(&s_ScrollBar, &Scroll, s_ScrollValue); + ButtonBar.VSplitRight(20.0f, &ButtonBar, &Scroll); + s_ScrollValue = pEditor->UIEx()->DoScrollbarV(&s_ScrollValue, &Scroll, s_ScrollValue); if(pEditor->UI()->MouseInside(&Scroll) || pEditor->UI()->MouseInside(&ButtonBar)) { @@ -1448,7 +1442,6 @@ int CEditor::PopupSelectConfigAutoMap(CEditor *pEditor, CUIRect View, void *pCon const float ButtonHeight = 12.0f; const float ButtonMargin = 2.0f; - static int s_ScrollBar = 0; static float s_ScrollValue = 0; // Add 1 more for the "None" option. @@ -1459,10 +1452,8 @@ int CEditor::PopupSelectConfigAutoMap(CEditor *pEditor, CUIRect View, void *pCon if(ListHeight > View.h) { CUIRect Scroll; - View.VSplitRight(15.f, &View, &Scroll); - - Scroll.HMargin(5.f, &Scroll); - s_ScrollValue = pEditor->UiDoScrollbarV(&s_ScrollBar, &Scroll, s_ScrollValue); + View.VSplitRight(20.0f, &View, &Scroll); + s_ScrollValue = pEditor->UIEx()->DoScrollbarV(&s_ScrollValue, &Scroll, s_ScrollValue); if(pEditor->UI()->MouseInside(&View) || pEditor->UI()->MouseInside(&Scroll)) {