From e817a179da69683d4ef209b8b6e2650279bbde1d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=94=D1=8F=D0=B4=D1=8F=20=D0=96=D0=B5=D0=BD=D1=8F?= Date: Wed, 28 Oct 2020 05:59:50 +0300 Subject: [PATCH] Started making color picker --- src/game/client/components/menus.cpp | 144 ++++++++++++++++++ src/game/client/components/menus.h | 22 +++ src/game/client/components/menus_settings.cpp | 131 ++++++++++++---- src/game/client/render.cpp | 13 ++ src/game/client/render.h | 1 + 5 files changed, 279 insertions(+), 32 deletions(-) diff --git a/src/game/client/components/menus.cpp b/src/game/client/components/menus.cpp index 12dfaf728..5d68a2d75 100644 --- a/src/game/client/components/menus.cpp +++ b/src/game/client/components/menus.cpp @@ -53,6 +53,10 @@ ColorRGBA CMenus::ms_ColorTabbarInactiveIngame; ColorRGBA CMenus::ms_ColorTabbarActiveIngame; ColorRGBA CMenus::ms_ColorTabbarHoverIngame; +SColorPicker CMenus::ms_ColorPicker; +int CMenus::ms_ColorPickerID; +int CMenus::ms_HuePickerID; + float CMenus::ms_ButtonHeight = 25.0f; float CMenus::ms_ListheaderHeight = 17.0f; float CMenus::ms_FontmodHeight = 0.8f; @@ -1143,6 +1147,143 @@ bool CMenus::CanDisplayWarning() return m_Popup == POPUP_NONE; } +void CMenus::RenderColorPicker() +{ + if(!ms_ColorPicker.m_Active) + return; + + // First check if we should disable color picker + CUIRect PickerRect; + PickerRect.x = ms_ColorPicker.m_X; + PickerRect.y = ms_ColorPicker.m_Y; + PickerRect.w = ms_ColorPicker.ms_Width; + PickerRect.h = ms_ColorPicker.ms_Height; + + if(UI()->MouseButtonClicked(0) && !UI()->MouseInside(&PickerRect) && !UI()->MouseInside(&ms_ColorPicker.m_AttachedRect)) + { + ms_ColorPicker.m_Active = false; + return; + } + + // Render + ColorRGBA BackgroundColor(0.1f, 0.1f, 0.1f, 1.0f); + ColorRGBA OutlineColor(0.21f, 0.21f, 0.21f, 1); + RenderTools()->DrawUIRect(&PickerRect, BackgroundColor, 0, 0); + + CUIRect ColorsArea, HueArea, BottomArea, AlphaSliderArea, HexCodeArea; + PickerRect.Margin(3, &ColorsArea); + + ColorsArea.HSplitBottom(ms_ColorPicker.ms_Height - 140.0f, &ColorsArea, &BottomArea); + ColorsArea.VSplitRight(20, &ColorsArea, &HueArea); + + BottomArea.HSplitTop(3, 0x0, &BottomArea); + HueArea.VSplitLeft(3, 0x0, &HueArea); + + BottomArea.HSplitBottom(14, &AlphaSliderArea, &HexCodeArea); + AlphaSliderArea.HSplitBottom(3, &AlphaSliderArea, 0x0); + + RenderTools()->DrawUIRect(&HueArea, OutlineColor, 0, 0); + HueArea.Margin(1, &HueArea); + + RenderTools()->DrawUIRect(&ColorsArea, OutlineColor, 0, 0); + ColorsArea.Margin(1, &ColorsArea); + + ColorHSLA HSLColor(*ms_ColorPicker.m_pColor, false); + ColorHSVA PickerColor = color_cast(HSLColor); + + // Color Area + ColorRGBA rgb; + rgb = color_cast(ColorHSVA(PickerColor.x, 0.0f, 1.0f)); + vec4 TL(rgb.r, rgb.g, rgb.b, 1.0f); + rgb = color_cast(ColorHSVA(PickerColor.x, 1.0f, 1.0f)); + vec4 TR(rgb.r, rgb.g, rgb.b, 1.0f); + rgb = color_cast(ColorHSVA(PickerColor.x, 0.0f, 1.0f)); + vec4 BL(rgb.r, rgb.g, rgb.b, 1.0f); + rgb = color_cast(ColorHSVA(PickerColor.x, 1.0f, 1.0f)); + vec4 BR(rgb.r, rgb.g, rgb.b, 1.0f); + + RenderTools()->DrawUIRect4NoRounding(&ColorsArea, TL, TR, BL, BR); + + TL = vec4(0.0f, 0.0f, 0.0f, 0.0f); + TR = vec4(0.0f, 0.0f, 0.0f, 0.0f); + BL = vec4(0.0f, 0.0f, 0.0f, 1.0f); + BR = vec4(0.0f, 0.0f, 0.0f, 1.0f); + + RenderTools()->DrawUIRect4NoRounding(&ColorsArea, TL, TR, BL, BR); + + // Hue Area + static const float s_aColorIndices[7][3] = { + {1.0f, 0.0f, 0.0f}, // red + {1.0f, 0.0f, 1.0f}, // magenta + {0.0f, 0.0f, 1.0f}, // blue + {0.0f, 1.0f, 1.0f}, // cyan + {0.0f, 1.0f, 0.0f}, // green + {1.0f, 1.0f, 0.0f}, // yellow + {1.0f, 0.0f, 0.0f} // red + }; + + float HuePickerOffset = HueArea.h / 6.0f; + CUIRect HuePartialArea = HueArea; + HuePartialArea.h = HuePickerOffset; + + for(int j = 0; j < 6; j++) + { + TL = vec4(s_aColorIndices[j][0], s_aColorIndices[j][1], s_aColorIndices[j][2], 1.0f); + BL = vec4(s_aColorIndices[j + 1][0], s_aColorIndices[j + 1][1], s_aColorIndices[j + 1][2], 1.0f); + + HuePartialArea.y = HueArea.y + HuePickerOffset * j; + RenderTools()->DrawUIRect4NoRounding(&HuePartialArea, TL, TL, BL, BL); + } + + //Hex Code Area FIX <<<<<< + rgb = color_cast(PickerColor); + char Hex[16]; + + str_format(Hex, sizeof(Hex), "#%06X", rgb.Pack(false)); + + static float HexID = 0; + DoEditBox(&HexID, &HexCodeArea, Hex, sizeof(Hex), 12.0f, &HexID); + + // Logic + float PickerX, PickerY; + bool PickerClicked = false; + + if(UI()->HotItem() != &ms_HuePickerID) + { + if(UI()->DoPickerLogic(&ms_ColorPickerID, &ColorsArea, &PickerX, &PickerY)) + { + PickerColor.y = PickerX / ColorsArea.w; + PickerColor.z = 1.0f - PickerY / ColorsArea.h; + PickerClicked = true; + } + } + + if(UI()->HotItem() != &ms_ColorPickerID) + { + if(UI()->DoPickerLogic(&ms_HuePickerID, &HueArea, &PickerX, &PickerY)) + { + PickerColor.x = 1.0f - PickerY / HueArea.h; + PickerClicked = true; + } + } + + // Marker Color Area + float MarkerX = ColorsArea.x + ColorsArea.w * PickerColor.y; + float MarkerY = ColorsArea.y + ColorsArea.h * (1.0f - PickerColor.z); + + int MarkerOutlineInd = PickerColor.z > 0.5f ? 0.0f : 1.0f; + ColorRGBA MarkerOutline(MarkerOutlineInd, MarkerOutlineInd, MarkerOutlineInd, 1.0f); + + Graphics()->QuadsBegin(); + Graphics()->SetColor(MarkerOutline); + RenderTools()->DrawCircle(MarkerX, MarkerY, 5.0f, 32); + Graphics()->SetColor(rgb); + RenderTools()->DrawCircle(MarkerX, MarkerY, 4.0f, 32); + Graphics()->QuadsEnd(); + + *ms_ColorPicker.m_pColor = color_cast(PickerColor).Pack(false); +} + int CMenus::Render() { if(Client()->State() == IClient::STATE_DEMOPLAYBACK && m_Popup == POPUP_NONE) @@ -1288,6 +1429,9 @@ int CMenus::Render() else if(m_MenuPage == PAGE_SETTINGS) { RenderSettings(MainView); + + // Render Color Picker only on settings page and last + RenderColorPicker(); } // do tab bar diff --git a/src/game/client/components/menus.h b/src/game/client/components/menus.h index 797c4f8b7..ee6b9ae98 100644 --- a/src/game/client/components/menus.h +++ b/src/game/client/components/menus.h @@ -24,6 +24,21 @@ struct CServerProcess CLineReader LineReader; }; +struct SColorPicker +{ +public: + const float ms_Width = 160.0f; + const float ms_Height = 200.0f; + + float m_X; + float m_Y; + + bool m_Active; + + CUIRect m_AttachedRect; + unsigned int *m_pColor; +}; + // compnent to fetch keypresses, override all other input class CMenusKeyBinder : public CComponent { @@ -49,6 +64,10 @@ class CMenus : public CComponent static ColorRGBA ms_ColorTabbarActive; static ColorRGBA ms_ColorTabbarHover; + static SColorPicker ms_ColorPicker; + static int ms_ColorPickerID; + static int ms_HuePickerID; + char m_aLocalStringHelper[1024]; float ButtonColorMulActive() { return 0.5f; } @@ -94,6 +113,8 @@ class CMenus : public CComponent //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(); + // new gui with gui elements template int DoButtonMenu(CUIElement &UIElement, const void *pID, T &&GetTextLambda, int Checked, const CUIRect *pRect, bool HintRequiresStringCheck, bool HintCanChangePositionOrSize = false, int Corners = CUI::CORNER_ALL, float r = 5.0f, float FontFactor = 0.0f, vec4 ColorHot = vec4(1.0f, 1.0f, 1.0f, 0.75f), vec4 Color = vec4(1, 1, 1, 0.5f), int AlignVertically = 1) @@ -634,6 +655,7 @@ private: // found in menus_settings.cpp void RenderSettingsDDNet(CUIRect MainView); void RenderSettingsHUD(CUIRect MainView); + ColorHSLA RenderHSLColorPicker(CUIRect *pRect, unsigned int *pColor, bool Alpha); ColorHSLA RenderHSLScrollbars(CUIRect *pRect, unsigned int *pColor, bool Alpha = false); CServerProcess m_ServerProcess; diff --git a/src/game/client/components/menus_settings.cpp b/src/game/client/components/menus_settings.cpp index 35879ea27..daa07033c 100644 --- a/src/game/client/components/menus_settings.cpp +++ b/src/game/client/components/menus_settings.cpp @@ -1564,6 +1564,55 @@ void CMenus::RenderSettings(CUIRect MainView) UI()->DoLabelScaled(&RestartWarning, Localize("You must restart the game for all settings to take effect."), 14.0f, -1); } +ColorHSLA CMenus::RenderHSLColorPicker(CUIRect *pRect, unsigned int *pColor, bool Alpha) +{ + ColorHSLA HSLColor(*pColor, false); + ColorRGBA RGBColor = color_cast(HSLColor); + + float OutlineCol = UI()->MouseInside(pRect) ? 0.7f : 0.5f; + + ColorRGBA Outline(OutlineCol, OutlineCol, OutlineCol, 1); + + const float OutlineSize = 2.0f; + + CUIRect Rect; + pRect->Margin(OutlineSize, &Rect); + + RenderTools()->DrawUIRect(pRect, Outline, 0, 0); + RenderTools()->DrawUIRect(&Rect, RGBColor, 0, 0); + + if(UI()->DoButtonLogic(pColor, 0, pRect)) + { + if(ms_ColorPicker.m_Active) + { + CUIRect PickerRect; + PickerRect.x = ms_ColorPicker.m_X; + PickerRect.y = ms_ColorPicker.m_Y; + PickerRect.w = ms_ColorPicker.ms_Width; + PickerRect.h = ms_ColorPicker.ms_Height; + + if(ms_ColorPicker.m_pColor != pColor && !UI()->MouseInside(&PickerRect)) + { + ms_ColorPicker.m_X = UI()->MouseX(); + ms_ColorPicker.m_Y = UI()->MouseY(); + ms_ColorPicker.m_pColor = pColor; + ms_ColorPicker.m_Active = true; + ms_ColorPicker.m_AttachedRect = *pRect; + } + } + else + { + ms_ColorPicker.m_X = UI()->MouseX(); + ms_ColorPicker.m_Y = UI()->MouseY(); + ms_ColorPicker.m_pColor = pColor; + ms_ColorPicker.m_Active = true; + ms_ColorPicker.m_AttachedRect = *pRect; + } + } + + return HSLColor; +} + ColorHSLA CMenus::RenderHSLScrollbars(CUIRect *pRect, unsigned int *pColor, bool Alpha) { ColorHSLA Color(*pColor, Alpha); @@ -1591,9 +1640,12 @@ void CMenus::RenderSettingsHUD(CUIRect MainView) { static int pIDP1 = 0, pIDP2 = 0; static int Page = 1; - CUIRect Left, Right, HUD, Messages, Button, Label, Weapon, Laser, Page1Tab, Page2Tab, Enable, Heart; + CUIRect Left, Right, HUD, Chat, Button, Label, Weapon, Laser, Page1Tab, Page2Tab, Enable, Heart; - MainView.HSplitTop(150.0f, &HUD, &MainView); + MainView.VSplitMid(&HUD, &Chat); + + ColorRGBA test(1, 1, 1, 0.1f); + RenderTools()->DrawUIRect(&MainView, test, 0, 0); HUD.HSplitTop(30.0f, &Label, &HUD); float tw = TextRender()->TextWidth(0, 20.0f, Localize("HUD"), -1, -1.0f); @@ -1631,13 +1683,13 @@ void CMenus::RenderSettingsHUD(CUIRect MainView) g_Config.m_ClShowIDs ^= 1; } - Right.HSplitTop(20.0f, &Button, &Right); + Left.HSplitTop(20.0f, &Button, &Left); if(DoButton_CheckBox(&g_Config.m_ClShowhudScore, Localize("Show score"), g_Config.m_ClShowhudScore, &Button)) { g_Config.m_ClShowhudScore ^= 1; } - Right.HSplitTop(20.0f, &Button, &Right); + Left.HSplitTop(20.0f, &Button, &Left); if(DoButton_CheckBox(&g_Config.m_ClShowhudHealthAmmo, Localize("Show health + ammo"), g_Config.m_ClShowhudHealthAmmo, &Button)) { g_Config.m_ClShowhudHealthAmmo ^= 1; @@ -1649,9 +1701,32 @@ void CMenus::RenderSettingsHUD(CUIRect MainView) g_Config.m_ClShowChat ^= 1; } - bool IsOldChat = !(g_Config.m_ClChatTee || g_Config.m_ClChatBackground); + Left.HSplitTop(20.0f, &Button, &Left); + if(DoButton_CheckBox(&g_Config.m_ClChatTeamColors, Localize("Show names in chat in team colors"), g_Config.m_ClChatTeamColors, &Button)) + { + g_Config.m_ClChatTeamColors ^= 1; + } Left.HSplitTop(20.0f, &Button, &Left); + if(DoButton_CheckBox(&g_Config.m_ClShowKillMessages, Localize("Show kill messages"), g_Config.m_ClShowKillMessages, &Button)) + { + g_Config.m_ClShowKillMessages ^= 1; + } + + Left.HSplitTop(20.0f, &Button, &Left); + if(DoButton_CheckBox(&g_Config.m_ClShowVotesAfterVoting, Localize("Show votes window after voting"), g_Config.m_ClShowVotesAfterVoting, &Button)) + { + g_Config.m_ClShowVotesAfterVoting ^= 1; + } + + // Chat + + Chat.HSplitTop(30.0f, &Label, &Chat); + UI()->DoLabelScaled(&Label, Localize("Chat"), 20.0f, -1); + + bool IsOldChat = !(g_Config.m_ClChatTee || g_Config.m_ClChatBackground); + + Chat.HSplitTop(20.0f, &Button, &Chat); if(DoButton_CheckBox(&g_Config.m_ClChatTee, Localize("Use old chat style"), IsOldChat, &Button)) { if(IsOldChat) @@ -1666,32 +1741,18 @@ void CMenus::RenderSettingsHUD(CUIRect MainView) } GameClient()->m_pChat->RebuildChat(); } - - Right.HSplitTop(20.0f, &Button, &Right); - if(DoButton_CheckBox(&g_Config.m_ClChatTeamColors, Localize("Show names in chat in team colors"), g_Config.m_ClChatTeamColors, &Button)) - { - g_Config.m_ClChatTeamColors ^= 1; - } - - Right.HSplitTop(20.0f, &Button, &Right); - if(DoButton_CheckBox(&g_Config.m_ClShowKillMessages, Localize("Show kill messages"), g_Config.m_ClShowKillMessages, &Button)) - { - g_Config.m_ClShowKillMessages ^= 1; - } - - Right.HSplitTop(20.0f, &Button, &Right); - if(DoButton_CheckBox(&g_Config.m_ClShowVotesAfterVoting, Localize("Show votes window after voting"), g_Config.m_ClShowVotesAfterVoting, &Button)) - { - g_Config.m_ClShowVotesAfterVoting ^= 1; - } - MainView.HSplitTop(170.0f, &Messages, &MainView); - Messages.HSplitTop(30.0f, &Label, &Messages); - Label.VSplitMid(&Label, &Button); - UI()->DoLabelScaled(&Label, Localize("Messages"), 20.0f, -1); - Messages.Margin(5.0f, &Messages); - Messages.VSplitMid(&Left, &Right); + /* + Right.HSplitTop(170.0f, &Chat, &MainView); + Chat.HSplitTop(30.0f, &Label, &Chat); + UI()->DoLabelScaled(&Label, Localize("Chat"), 20.0f, -1); + Chat.Margin(5.0f, &Chat); + Chat.VSplitMid(&Left, &Right); + Left = Right; Left.VSplitRight(5.0f, &Left, 0); Right.VMargin(5.0f, &Right); + */ + /* + { char aBuf[64]; Left.HSplitTop(20.0f, &Label, &Left); @@ -1700,6 +1761,7 @@ void CMenus::RenderSettingsHUD(CUIRect MainView) if(DoButton_CheckBox(&g_Config.m_ClShowChatSystem, "", g_Config.m_ClShowChatSystem, &Enable)) g_Config.m_ClShowChatSystem ^= 1; + UI()->DoLabelScaled(&Label, Localize("System message"), 16.0f, -1); { static int s_DefaultButton = 0; @@ -1710,11 +1772,16 @@ void CMenus::RenderSettingsHUD(CUIRect MainView) } } - ColorHSLA SMColor = RenderHSLScrollbars(&Left, &g_Config.m_ClMessageSystemColor); + CUIRect PickerRect; + Left.HSplitTop(5.0f, 0x0, &Left); + Left.HSplitTop(25.0f, &PickerRect, &Left); + PickerRect.w = 25.0f; + + ColorHSLA SMColor = RenderHSLColorPicker(&PickerRect, &g_Config.m_ClMessageSystemColor, false); + ColorRGBA rgb = color_cast(SMColor); Left.HSplitTop(10.0f, &Label, &Left); - ColorRGBA rgb = color_cast(SMColor); TextRender()->TextColor(rgb); char aName[16]; @@ -1896,7 +1963,7 @@ void CMenus::RenderSettingsHUD(CUIRect MainView) UI()->DoLabelScaled(&Label, "*** Dynamic camera activated", 12.0f, -1); TextRender()->TextColor(1.0f, 1.0f, 1.0f, 1.0f); Right.HSplitTop(20.0f, 0, &Right); - } + }*/ } else if(Page == 2) { diff --git a/src/game/client/render.cpp b/src/game/client/render.cpp index 00ad48678..f01a8b3f0 100644 --- a/src/game/client/render.cpp +++ b/src/game/client/render.cpp @@ -508,6 +508,19 @@ void CRenderTools::DrawUIRect4(const CUIRect *r, vec4 ColorTopLeft, vec4 ColorTo Graphics()->QuadsEnd(); } +void CRenderTools::DrawUIRect4NoRounding(const CUIRect *r, vec4 ColorTopLeft, vec4 ColorTopRight, vec4 ColorBottomLeft, vec4 ColorBottomRight) +{ + Graphics()->TextureClear(); + + Graphics()->QuadsBegin(); + + Graphics()->SetColor4(ColorTopLeft, ColorTopRight, ColorBottomLeft, ColorBottomRight); + IGraphics::CQuadItem ItemQ = IGraphics::CQuadItem(r->x, r->y, r->w, r->h); + Graphics()->QuadsDrawTL(&ItemQ, 1); + + Graphics()->QuadsEnd(); +} + void CRenderTools::DrawCircle(float x, float y, float r, int Segments) { IGraphics::CFreeformItem Array[32]; diff --git a/src/game/client/render.h b/src/game/client/render.h index d88ee34b6..7a18e4cb0 100644 --- a/src/game/client/render.h +++ b/src/game/client/render.h @@ -89,6 +89,7 @@ public: void DrawUIRect(const CUIRect *pRect, ColorRGBA Color, int Corners, float Rounding); void DrawUIRect4(const CUIRect *pRect, vec4 ColorTopLeft, vec4 ColorTopRight, vec4 ColorBottomLeft, vec4 ColorBottomRight, int Corners, float Rounding); + void DrawUIRect4NoRounding(const CUIRect *pRect, vec4 ColorTopLeft, vec4 ColorTopRight, vec4 ColorBottomLeft, vec4 ColorBottomRight); void DrawCircle(float x, float y, float r, int Segments);