From 7ce9fd99494f9839bad4ed0569620ad9e4e78748 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20M=C3=BCller?= Date: Wed, 14 Jun 2023 20:05:00 +0200 Subject: [PATCH 1/2] Refactor UI color picker - Improve variable names. - Use `ColorHSVA` instead of `unsigned int`. - Allow `m_pHslaColor` to be `nullptr` when HSLA color unused. --- src/game/client/components/menus.cpp | 20 ++++++++++---------- src/game/client/components/menus.h | 2 +- src/game/client/ui.cpp | 7 ++++--- src/game/client/ui.h | 4 ++-- 4 files changed, 17 insertions(+), 16 deletions(-) diff --git a/src/game/client/components/menus.cpp b/src/game/client/components/menus.cpp index 24d50a397..c87418078 100644 --- a/src/game/client/components/menus.cpp +++ b/src/game/client/components/menus.cpp @@ -393,33 +393,33 @@ ColorHSLA CMenus::DoLine_ColorPicker(CButtonContainer *pResetID, const float Lin return PickedColor; } -ColorHSLA CMenus::DoButton_ColorPicker(const CUIRect *pRect, unsigned int *pColor, bool Alpha) +ColorHSLA CMenus::DoButton_ColorPicker(const CUIRect *pRect, unsigned int *pHslaColor, bool Alpha) { - ColorHSLA HSLColor = ColorHSLA(*pColor, Alpha); + ColorHSLA HslaColor = ColorHSLA(*pHslaColor, Alpha); ColorRGBA Outline = ColorRGBA(1.0f, 1.0f, 1.0f, 0.25f); - Outline.a *= UI()->ButtonColorMul(pColor); + Outline.a *= UI()->ButtonColorMul(pHslaColor); CUIRect Rect; pRect->Margin(3.0f, &Rect); pRect->Draw(Outline, IGraphics::CORNER_ALL, 4.0f); - Rect.Draw(color_cast(HSLColor), IGraphics::CORNER_ALL, 4.0f); + Rect.Draw(color_cast(HslaColor), IGraphics::CORNER_ALL, 4.0f); static CUI::SColorPickerPopupContext s_ColorPickerPopupContext; - if(UI()->DoButtonLogic(pColor, 0, pRect)) + if(UI()->DoButtonLogic(pHslaColor, 0, pRect)) { - s_ColorPickerPopupContext.m_pColor = pColor; - s_ColorPickerPopupContext.m_HSVColor = color_cast(HSLColor).Pack(Alpha); + s_ColorPickerPopupContext.m_pHslaColor = pHslaColor; + s_ColorPickerPopupContext.m_HsvaColor = color_cast(HslaColor); s_ColorPickerPopupContext.m_Alpha = Alpha; UI()->ShowPopupColorPicker(UI()->MouseX(), UI()->MouseY(), &s_ColorPickerPopupContext); } - else if(UI()->IsPopupOpen(&s_ColorPickerPopupContext) && s_ColorPickerPopupContext.m_pColor == pColor) + else if(UI()->IsPopupOpen(&s_ColorPickerPopupContext) && s_ColorPickerPopupContext.m_pHslaColor == pHslaColor) { - HSLColor = color_cast(ColorHSVA(s_ColorPickerPopupContext.m_HSVColor, Alpha)); + HslaColor = color_cast(s_ColorPickerPopupContext.m_HsvaColor); } - return HSLColor; + return HslaColor; } int CMenus::DoButton_CheckBoxAutoVMarginAndSet(const void *pID, const char *pText, int *pValue, CUIRect *pRect, float VMargin) diff --git a/src/game/client/components/menus.h b/src/game/client/components/menus.h index e9660fca8..7cbada28e 100644 --- a/src/game/client/components/menus.h +++ b/src/game/client/components/menus.h @@ -66,7 +66,7 @@ class CMenus : public CComponent int DoButton_CheckBox_Number(const void *pID, const char *pText, int Checked, const CUIRect *pRect); ColorHSLA DoLine_ColorPicker(CButtonContainer *pResetID, float LineSize, float LabelSize, float BottomMargin, CUIRect *pMainRect, const char *pText, unsigned int *pColorValue, ColorRGBA DefaultColor, bool CheckBoxSpacing = true, int *pCheckBoxValue = nullptr, bool Alpha = false); - ColorHSLA DoButton_ColorPicker(const CUIRect *pRect, unsigned int *pColor, bool Alpha); + ColorHSLA DoButton_ColorPicker(const CUIRect *pRect, unsigned int *pHslaColor, bool Alpha); void DoLaserPreview(const CUIRect *pRect, ColorHSLA OutlineColor, ColorHSLA InnerColor, const int LaserType); int DoButton_GridHeader(const void *pID, const char *pText, int Checked, const CUIRect *pRect); diff --git a/src/game/client/ui.cpp b/src/game/client/ui.cpp index 9ca639d7b..df1626ccd 100644 --- a/src/game/client/ui.cpp +++ b/src/game/client/ui.cpp @@ -1653,7 +1653,7 @@ CUI::EPopupMenuFunctionResult CUI::PopupColorPicker(void *pContext, CUIRect View ColorsArea.Draw(BlackColor, IGraphics::CORNER_NONE, 0.0f); ColorsArea.Margin(1.0f, &ColorsArea); - ColorHSVA PickerColorHSV = ColorHSVA(pColorPicker->m_HSVColor, pColorPicker->m_Alpha); + ColorHSVA PickerColorHSV = pColorPicker->m_HsvaColor; unsigned H = (unsigned)(PickerColorHSV.x * 255.0f); unsigned S = (unsigned)(PickerColorHSV.y * 255.0f); unsigned V = (unsigned)(PickerColorHSV.z * 255.0f); @@ -1781,8 +1781,9 @@ CUI::EPopupMenuFunctionResult CUI::PopupColorPicker(void *pContext, CUIRect View HueMarker.Margin(1.2f, &HueMarker); HueMarker.Draw(HueMarkerColor, IGraphics::CORNER_ALL, 1.2f); - pColorPicker->m_HSVColor = PickerColorHSV.Pack(pColorPicker->m_Alpha); - *pColorPicker->m_pColor = color_cast(PickerColorHSV).Pack(pColorPicker->m_Alpha); + pColorPicker->m_HsvaColor = PickerColorHSV; + if(pColorPicker->m_pHslaColor != nullptr) + *pColorPicker->m_pHslaColor = color_cast(PickerColorHSV).Pack(pColorPicker->m_Alpha); return CUI::POPUP_KEEP_OPEN; } diff --git a/src/game/client/ui.h b/src/game/client/ui.h index 76404639a..bf20f900c 100644 --- a/src/game/client/ui.h +++ b/src/game/client/ui.h @@ -589,8 +589,8 @@ public: { CUI *m_pUI; // set by CUI when popup is shown bool m_Alpha = false; - unsigned int *m_pColor; - unsigned int m_HSVColor; + unsigned int *m_pHslaColor = nullptr; // may be nullptr + ColorHSVA m_HsvaColor; const char m_HuePickerId = 0; const char m_ColorPickerId = 0; const char m_aValueSelectorIds[5] = {0}; From 34c2e5649b54ce80eaac118be6c99f6d9608502c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20M=C3=BCller?= Date: Wed, 14 Jun 2023 19:54:21 +0200 Subject: [PATCH 2/2] Improve editor color picker popup By replacing the editor specific color picker popup with the generic UI color picker popup. Improve layout of the editor color picker button. Improve spacing and ensure that the button is square. Slightly enlarge button on mouse hover. --- src/game/editor/editor.cpp | 38 ++++++-------- src/game/editor/editor.h | 7 --- src/game/editor/popups.cpp | 103 ------------------------------------- 3 files changed, 15 insertions(+), 133 deletions(-) diff --git a/src/game/editor/editor.cpp b/src/game/editor/editor.cpp index b26ef2f56..7fe51a66c 100644 --- a/src/game/editor/editor.cpp +++ b/src/game/editor/editor.cpp @@ -75,10 +75,6 @@ bool CEditor::IsVanillaImage(const char *pImage) const void *CEditor::ms_pUiGotContext; -ColorHSVA CEditor::ms_PickerColor; -int CEditor::ms_SVPicker; -int CEditor::ms_HuePicker; - enum { BUTTON_CONTEXT = 1, @@ -488,12 +484,6 @@ int CEditor::DoButton_ButtonDec(const void *pID, const char *pText, int Checked, return DoButton_Editor_Common(pID, pText, Checked, pRect, Flags, pToolTip); } -int CEditor::DoButton_ColorPicker(const void *pID, const CUIRect *pRect, ColorRGBA *pColor, const char *pToolTip) -{ - pRect->Draw(*pColor, 0, 0.0f); - return DoButton_Editor_Common(pID, nullptr, 0, pRect, 0, pToolTip); -} - int CEditor::DoButton_DraggableEx(const void *pID, const char *pText, int Checked, const CUIRect *pRect, bool *pClicked, bool *pAbrupted, int Flags, const char *pToolTip, int Corners, float FontSize) { pRect->Draw(GetButtonColor(pID, Checked), Corners, 3.0f); @@ -3148,8 +3138,9 @@ int CEditor::DoProperties(CUIRect *pToolBox, CProperty *pProps, int *pIDs, int * pToolBox->HSplitTop(3.0f * 13.0f, &Slot, pToolBox); Slot.VSplitMid(&ColorBox, &ColorSlots); - ColorBox.HMargin(1.0f, &ColorBox); - ColorBox.VMargin(6.0f, &ColorBox); + ColorBox.HSplitTop(8.0f, nullptr, &ColorBox); + ColorBox.VMargin(12.0f, &ColorBox); + ColorBox.HMargin((ColorBox.h - ColorBox.w) / 2.0f, &ColorBox); for(int c = 0; c < 4; c++) { @@ -3179,20 +3170,23 @@ int CEditor::DoProperties(CUIRect *pToolBox, CProperty *pProps, int *pIDs, int * 1.0f); static int s_ColorPicker; - if(DoButton_ColorPicker(&s_ColorPicker, &ColorBox, &ColorPick)) - { - ms_PickerColor = color_cast(ColorPick); - static SPopupMenuId s_PopupColorPickerId; - UI()->DoPopupMenu(&s_PopupColorPickerId, UI()->MouseX(), UI()->MouseY(), 180, 150, this, PopupColorPicker); - } + if(UI()->HotItem() == &s_ColorPicker) + ColorBox.Margin(-2.0f, &ColorBox); + ColorBox.Draw(ColorPick, IGraphics::CORNER_ALL, 3.0f); - if(UI()->HotItem() == &ms_SVPicker || UI()->HotItem() == &ms_HuePicker) + static CUI::SColorPickerPopupContext s_ColorPickerPopupContext; + if(DoButton_Editor_Common(&s_ColorPicker, nullptr, 0, &ColorBox, 0, "Click to show the color picker.")) { - ColorRGBA c = color_cast(ms_PickerColor); + s_ColorPickerPopupContext.m_HsvaColor = color_cast(ColorPick); + s_ColorPickerPopupContext.m_Alpha = true; + UI()->ShowPopupColorPicker(UI()->MouseX(), UI()->MouseY(), &s_ColorPickerPopupContext); + } + else if(UI()->IsPopupOpen(&s_ColorPickerPopupContext)) + { + ColorRGBA c = color_cast(s_ColorPickerPopupContext.m_HsvaColor); NewColor = ((int)(c.r * 255.0f) & 0xff) << 24 | ((int)(c.g * 255.0f) & 0xff) << 16 | ((int)(c.b * 255.0f) & 0xff) << 8 | (pProps[i].m_Value & 0xff); } - // if(NewColor != pProps[i].m_Value) { *pNewVal = NewColor; @@ -6755,8 +6749,6 @@ void CEditor::Init() Reset(false); m_Map.m_Modified = false; - ms_PickerColor = ColorHSVA(1.0f, 0.0f, 0.0f); - ResetMenuBackgroundPositions(); m_vpMenuBackgroundPositionNames.resize(CMenuBackground::NUM_POS); m_vpMenuBackgroundPositionNames[CMenuBackground::POS_START] = "start"; diff --git a/src/game/editor/editor.h b/src/game/editor/editor.h index dfdd5efa1..ec70ca7b3 100644 --- a/src/game/editor/editor.h +++ b/src/game/editor/editor.h @@ -1138,8 +1138,6 @@ public: int DoButton_Menu(const void *pID, const char *pText, int Checked, const CUIRect *pRect, int Flags, const char *pToolTip); int DoButton_MenuItem(const void *pID, const char *pText, int Checked, const CUIRect *pRect, int Flags = 0, const char *pToolTip = nullptr); - int DoButton_ColorPicker(const void *pID, const CUIRect *pRect, ColorRGBA *pColor, const char *pToolTip = nullptr); - int DoButton_DraggableEx(const void *pID, const char *pText, int Checked, const CUIRect *pRect, bool *pClicked, bool *pAbrupted, int Flags, const char *pToolTip = nullptr, int Corners = IGraphics::CORNER_ALL, float FontSize = 10.0f); bool DoEditBox(CLineInput *pLineInput, const CUIRect *pRect, float FontSize, int Corners = IGraphics::CORNER_ALL, const char *pToolTip = nullptr); @@ -1180,7 +1178,6 @@ public: static CUI::EPopupMenuFunctionResult PopupSwitch(void *pContext, CUIRect View, bool Active); static CUI::EPopupMenuFunctionResult PopupTune(void *pContext, CUIRect View, bool Active); static CUI::EPopupMenuFunctionResult PopupGoto(void *pContext, CUIRect View, bool Active); - static CUI::EPopupMenuFunctionResult PopupColorPicker(void *pContext, CUIRect View, bool Active); static CUI::EPopupMenuFunctionResult PopupEntities(void *pContext, CUIRect View, bool Active); static CUI::EPopupMenuFunctionResult PopupProofMode(void *pContext, CUIRect View, bool Active); @@ -1333,10 +1330,6 @@ public: float MinZoomLevel() const; float MaxZoomLevel() const; - static ColorHSVA ms_PickerColor; - static int ms_SVPicker; - static int ms_HuePicker; - // DDRace IGraphics::CTextureHandle GetFrontTexture(); diff --git a/src/game/editor/popups.cpp b/src/game/editor/popups.cpp index a0816fc75..67d514c4f 100644 --- a/src/game/editor/popups.cpp +++ b/src/game/editor/popups.cpp @@ -2193,109 +2193,6 @@ CUI::EPopupMenuFunctionResult CEditor::PopupGoto(void *pContext, CUIRect View, b return CUI::POPUP_KEEP_OPEN; } -CUI::EPopupMenuFunctionResult CEditor::PopupColorPicker(void *pContext, CUIRect View, bool Active) -{ - CEditor *pEditor = static_cast(pContext); - - CUIRect SVPicker, HuePicker; - View.VSplitRight(20.0f, &SVPicker, &HuePicker); - HuePicker.VSplitLeft(4.0f, nullptr, &HuePicker); - - pEditor->Graphics()->TextureClear(); - pEditor->Graphics()->QuadsBegin(); - - // base: white - hue - ColorHSVA Hsv = CEditor::ms_PickerColor; - IGraphics::CColorVertex aColors[4]; - - ColorRGBA Color = color_cast(ColorHSVA(Hsv.x, 0.0f, 1.0f)); - aColors[0] = IGraphics::CColorVertex(0, Color.r, Color.g, Color.b, 1.0f); - Color = color_cast(ColorHSVA(Hsv.x, 1.0f, 1.0f)); - aColors[1] = IGraphics::CColorVertex(1, Color.r, Color.g, Color.b, 1.0f); - Color = color_cast(ColorHSVA(Hsv.x, 1.0f, 1.0f)); - aColors[2] = IGraphics::CColorVertex(2, Color.r, Color.g, Color.b, 1.0f); - Color = color_cast(ColorHSVA(Hsv.x, 0.0f, 1.0f)); - aColors[3] = IGraphics::CColorVertex(3, Color.r, Color.g, Color.b, 1.0f); - - pEditor->Graphics()->SetColorVertex(aColors, 4); - - IGraphics::CQuadItem QuadItem(SVPicker.x, SVPicker.y, SVPicker.w, SVPicker.h); - pEditor->Graphics()->QuadsDrawTL(&QuadItem, 1); - - // base: transparent - black - aColors[0] = IGraphics::CColorVertex(0, 0.0f, 0.0f, 0.0f, 0.0f); - aColors[1] = IGraphics::CColorVertex(1, 0.0f, 0.0f, 0.0f, 0.0f); - aColors[2] = IGraphics::CColorVertex(2, 0.0f, 0.0f, 0.0f, 1.0f); - aColors[3] = IGraphics::CColorVertex(3, 0.0f, 0.0f, 0.0f, 1.0f); - - pEditor->Graphics()->SetColorVertex(aColors, 4); - - pEditor->Graphics()->QuadsDrawTL(&QuadItem, 1); - - pEditor->Graphics()->QuadsEnd(); - - // marker - const vec2 Marker = vec2(Hsv.y, (1.0f - Hsv.z)) * vec2(SVPicker.w, SVPicker.h); - pEditor->Graphics()->QuadsBegin(); - pEditor->Graphics()->SetColor(0.5f, 0.5f, 0.5f, 1.0f); - IGraphics::CQuadItem aMarker[2]; - aMarker[0] = IGraphics::CQuadItem(SVPicker.x + Marker.x, SVPicker.y + Marker.y - 5.0f * pEditor->UI()->PixelSize(), pEditor->UI()->PixelSize(), 11.0f * pEditor->UI()->PixelSize()); - aMarker[1] = IGraphics::CQuadItem(SVPicker.x + Marker.x - 5.0f * pEditor->UI()->PixelSize(), SVPicker.y + Marker.y, 11.0f * pEditor->UI()->PixelSize(), pEditor->UI()->PixelSize()); - pEditor->Graphics()->QuadsDrawTL(aMarker, 2); - pEditor->Graphics()->QuadsEnd(); - - // logic - float X, Y; - if(pEditor->UI()->DoPickerLogic(&CEditor::ms_SVPicker, &SVPicker, &X, &Y)) - { - Hsv.y = X / SVPicker.w; - Hsv.z = 1.0f - Y / SVPicker.h; - } - - // hue slider - static const float s_aaColorIndices[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 - }; - - pEditor->Graphics()->QuadsBegin(); - const float Offset = HuePicker.h / 6.0f; - for(size_t j = 0; j < std::size(s_aaColorIndices) - 1; ++j) - { - const ColorRGBA ColorTop = ColorRGBA(s_aaColorIndices[j][0], s_aaColorIndices[j][1], s_aaColorIndices[j][2], 1.0f); - const ColorRGBA ColorBottom = ColorRGBA(s_aaColorIndices[j + 1][0], s_aaColorIndices[j + 1][1], s_aaColorIndices[j + 1][2], 1.0f); - - aColors[0] = IGraphics::CColorVertex(0, ColorTop.r, ColorTop.g, ColorTop.b, ColorTop.a); - aColors[1] = IGraphics::CColorVertex(1, ColorTop.r, ColorTop.g, ColorTop.b, ColorTop.a); - aColors[2] = IGraphics::CColorVertex(2, ColorBottom.r, ColorBottom.g, ColorBottom.b, ColorBottom.a); - aColors[3] = IGraphics::CColorVertex(3, ColorBottom.r, ColorBottom.g, ColorBottom.b, ColorBottom.a); - pEditor->Graphics()->SetColorVertex(aColors, 4); - QuadItem = IGraphics::CQuadItem(HuePicker.x, HuePicker.y + Offset * j, HuePicker.w, Offset); - pEditor->Graphics()->QuadsDrawTL(&QuadItem, 1); - } - - // marker - pEditor->Graphics()->SetColor(0.5f, 0.5f, 0.5f, 1.0f); - IGraphics::CQuadItem QuadItemMarker(HuePicker.x, HuePicker.y + (1.0f - Hsv.x) * HuePicker.h, HuePicker.w, pEditor->UI()->PixelSize()); - pEditor->Graphics()->QuadsDrawTL(&QuadItemMarker, 1); - - pEditor->Graphics()->QuadsEnd(); - - if(pEditor->UI()->DoPickerLogic(&CEditor::ms_HuePicker, &HuePicker, &X, &Y)) - { - Hsv.x = 1.0f - Y / HuePicker.h; - } - - CEditor::ms_PickerColor = Hsv; - - return CUI::POPUP_KEEP_OPEN; -} - CUI::EPopupMenuFunctionResult CEditor::PopupEntities(void *pContext, CUIRect View, bool Active) { CEditor *pEditor = static_cast(pContext);