mirror of
https://github.com/ddnet/ddnet.git
synced 2024-11-10 10:08:18 +00:00
Add generic color picker popup to UI, add alpha support
Use the popup system ported from the editor to reimplement the color picker popup. Remove special handling necessary for the hard-coded color picker. Add alpha support to the color picker popup.
This commit is contained in:
parent
938c57e03a
commit
e50bd4bb6c
|
@ -51,8 +51,6 @@ ColorRGBA CMenus::ms_ColorTabbarInactiveIngame;
|
|||
ColorRGBA CMenus::ms_ColorTabbarActiveIngame;
|
||||
ColorRGBA CMenus::ms_ColorTabbarHoverIngame;
|
||||
|
||||
SColorPicker CMenus::ms_ColorPicker;
|
||||
|
||||
float CMenus::ms_ButtonHeight = 25.0f;
|
||||
float CMenus::ms_ListheaderHeight = 17.0f;
|
||||
|
||||
|
@ -122,28 +120,11 @@ int CMenus::DoButton_Toggle(const void *pID, int Checked, const CUIRect *pRect,
|
|||
return Active ? UI()->DoButtonLogic(pID, Checked, pRect) : 0;
|
||||
}
|
||||
|
||||
int CMenus::DoButton_Menu(CButtonContainer *pButtonContainer, const char *pText, int Checked, const CUIRect *pRect, const char *pImageName, int Corners, float r, float FontFactor, vec4 ColorHot, vec4 Color, bool CheckForActiveColorPicker)
|
||||
int CMenus::DoButton_Menu(CButtonContainer *pButtonContainer, const char *pText, int Checked, const CUIRect *pRect, const char *pImageName, int Corners, float r, float FontFactor, vec4 ColorHot, vec4 Color)
|
||||
{
|
||||
CUIRect Text = *pRect;
|
||||
|
||||
bool MouseInsideColorPicker = false;
|
||||
|
||||
if(CheckForActiveColorPicker)
|
||||
{
|
||||
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;
|
||||
|
||||
MouseInsideColorPicker = UI()->MouseInside(&PickerRect);
|
||||
}
|
||||
}
|
||||
|
||||
if(!MouseInsideColorPicker)
|
||||
Color.a *= UI()->ButtonColorMul(pButtonContainer);
|
||||
Color.a *= UI()->ButtonColorMul(pButtonContainer);
|
||||
pRect->Draw(Color, Corners, r);
|
||||
|
||||
if(pImageName)
|
||||
|
@ -170,9 +151,6 @@ int CMenus::DoButton_Menu(CButtonContainer *pButtonContainer, const char *pText,
|
|||
Text.HMargin((Text.h * FontFactor) / 2.0f, &Text);
|
||||
UI()->DoLabel(&Text, pText, Text.h * CUI::ms_FontmodHeight, TEXTALIGN_MC);
|
||||
|
||||
if(MouseInsideColorPicker)
|
||||
return 0;
|
||||
|
||||
return UI()->DoButtonLogic(pButtonContainer, Checked, pRect);
|
||||
}
|
||||
|
||||
|
@ -374,7 +352,7 @@ void CMenus::DoLaserPreview(const CUIRect *pRect, const ColorHSLA LaserOutlineCo
|
|||
}
|
||||
}
|
||||
|
||||
ColorHSLA CMenus::DoLine_ColorPicker(CButtonContainer *pResetID, const float LineSize, const float LabelSize, const float BottomMargin, CUIRect *pMainRect, const char *pText, unsigned int *pColorValue, const ColorRGBA DefaultColor, bool CheckBoxSpacing, int *pCheckBoxValue)
|
||||
ColorHSLA CMenus::DoLine_ColorPicker(CButtonContainer *pResetID, const float LineSize, const float LabelSize, const float BottomMargin, CUIRect *pMainRect, const char *pText, unsigned int *pColorValue, const ColorRGBA DefaultColor, bool CheckBoxSpacing, int *pCheckBoxValue, bool Alpha)
|
||||
{
|
||||
CUIRect Section, ColorPickerButton, ResetButton, Label;
|
||||
|
||||
|
@ -391,9 +369,9 @@ ColorHSLA CMenus::DoLine_ColorPicker(CButtonContainer *pResetID, const float Lin
|
|||
if(DoButton_CheckBox(pCheckBoxValue, "", *pCheckBoxValue, &CheckBox))
|
||||
*pCheckBoxValue ^= 1;
|
||||
}
|
||||
Section.VSplitLeft(5.0f, nullptr, &Section);
|
||||
}
|
||||
|
||||
Section.VSplitLeft(5.0f, nullptr, &Section);
|
||||
Section.VSplitMid(&Label, &Section, Section.h);
|
||||
Section.VSplitRight(60.0f, &Section, &ResetButton);
|
||||
Section.VSplitRight(8.0f, &Section, nullptr);
|
||||
|
@ -401,17 +379,46 @@ ColorHSLA CMenus::DoLine_ColorPicker(CButtonContainer *pResetID, const float Lin
|
|||
|
||||
UI()->DoLabel(&Label, pText, LabelSize, TEXTALIGN_ML);
|
||||
|
||||
ColorHSLA PickedColor = RenderHSLColorPicker(&ColorPickerButton, pColorValue, false);
|
||||
ColorHSLA PickedColor = DoButton_ColorPicker(&ColorPickerButton, pColorValue, Alpha);
|
||||
|
||||
ResetButton.HMargin(2.0f, &ResetButton);
|
||||
if(DoButton_Menu(pResetID, Localize("Reset"), 0, &ResetButton, nullptr, IGraphics::CORNER_ALL, 8.0f, 0.0f, vec4(1, 1, 1, 0.5f), vec4(1, 1, 1, 0.25f), true))
|
||||
if(DoButton_Menu(pResetID, Localize("Reset"), 0, &ResetButton, nullptr, IGraphics::CORNER_ALL, 8.0f, 0.0f, vec4(1, 1, 1, 0.5f), vec4(1, 1, 1, 0.25f)))
|
||||
{
|
||||
*pColorValue = color_cast<ColorHSLA>(DefaultColor).Pack(false);
|
||||
*pColorValue = color_cast<ColorHSLA>(DefaultColor).Pack(Alpha);
|
||||
}
|
||||
|
||||
return PickedColor;
|
||||
}
|
||||
|
||||
ColorHSLA CMenus::DoButton_ColorPicker(const CUIRect *pRect, unsigned int *pColor, bool Alpha)
|
||||
{
|
||||
ColorHSLA HSLColor = ColorHSLA(*pColor, Alpha);
|
||||
|
||||
ColorRGBA Outline = ColorRGBA(1.0f, 1.0f, 1.0f, 0.25f);
|
||||
Outline.a *= UI()->ButtonColorMul(pColor);
|
||||
|
||||
CUIRect Rect;
|
||||
pRect->Margin(3.0f, &Rect);
|
||||
|
||||
pRect->Draw(Outline, IGraphics::CORNER_ALL, 4.0f);
|
||||
Rect.Draw(color_cast<ColorRGBA>(HSLColor), IGraphics::CORNER_ALL, 4.0f);
|
||||
|
||||
static CUI::SColorPickerPopupContext s_ColorPickerPopupContext;
|
||||
if(UI()->DoButtonLogic(pColor, 0, pRect))
|
||||
{
|
||||
s_ColorPickerPopupContext.m_pColor = pColor;
|
||||
s_ColorPickerPopupContext.m_HSVColor = color_cast<ColorHSVA>(HSLColor).Pack(Alpha);
|
||||
s_ColorPickerPopupContext.m_Alpha = Alpha;
|
||||
UI()->ShowPopupColorPicker(UI()->MouseX(), UI()->MouseY(), &s_ColorPickerPopupContext);
|
||||
}
|
||||
else if(UI()->IsPopupOpen(&s_ColorPickerPopupContext) && s_ColorPickerPopupContext.m_pColor == pColor)
|
||||
{
|
||||
HSLColor = color_cast<ColorHSLA>(ColorHSVA(s_ColorPickerPopupContext.m_HSVColor, Alpha));
|
||||
}
|
||||
|
||||
return HSLColor;
|
||||
}
|
||||
|
||||
int CMenus::DoButton_CheckBoxAutoVMarginAndSet(const void *pID, const char *pText, int *pValue, CUIRect *pRect, float VMargin)
|
||||
{
|
||||
CUIRect CheckBoxRect;
|
||||
|
@ -951,196 +958,6 @@ bool CMenus::CanDisplayWarning()
|
|||
return m_Popup == POPUP_NONE;
|
||||
}
|
||||
|
||||
void CMenus::RenderColorPicker()
|
||||
{
|
||||
if(!ms_ColorPicker.m_Active)
|
||||
return;
|
||||
|
||||
if(UI()->ConsumeHotkey(CUI::HOTKEY_ESCAPE))
|
||||
{
|
||||
ms_ColorPicker.m_Active = false;
|
||||
UI()->SetValueSelectorTextMode(false);
|
||||
UI()->SetActiveItem(nullptr);
|
||||
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;
|
||||
UI()->SetValueSelectorTextMode(false);
|
||||
UI()->SetActiveItem(nullptr);
|
||||
return;
|
||||
}
|
||||
|
||||
// Prevent activation of UI elements outside of active color picker
|
||||
if(UI()->MouseInside(&PickerRect))
|
||||
UI()->SetHotItem(&ms_ColorPicker);
|
||||
|
||||
// Render
|
||||
ColorRGBA BackgroundColor(0.1f, 0.1f, 0.1f, 1.0f);
|
||||
PickerRect.Draw(BackgroundColor, 0, 0);
|
||||
|
||||
CUIRect ColorsArea, HueArea, ValuesHitbox, BottomArea, HueRect, SatRect, ValueRect, HexRect, AlphaRect;
|
||||
PickerRect.Margin(3, &ColorsArea);
|
||||
|
||||
ColorsArea.HSplitBottom(ms_ColorPicker.ms_Height - 140.0f, &ColorsArea, &ValuesHitbox);
|
||||
ColorsArea.VSplitRight(20, &ColorsArea, &HueArea);
|
||||
|
||||
BottomArea = ValuesHitbox;
|
||||
BottomArea.HSplitTop(3, 0x0, &BottomArea);
|
||||
HueArea.VSplitLeft(3, 0x0, &HueArea);
|
||||
|
||||
BottomArea.HSplitTop(20, &HueRect, &BottomArea);
|
||||
BottomArea.HSplitTop(3, 0x0, &BottomArea);
|
||||
|
||||
constexpr float ValuePadding = 5.0f;
|
||||
const float HsvValueWidth = (HueRect.w - ValuePadding * 2) / 3.0f;
|
||||
const float HexValueWidth = HsvValueWidth * 2 + ValuePadding;
|
||||
|
||||
HueRect.VSplitLeft(HsvValueWidth, &HueRect, &SatRect);
|
||||
SatRect.VSplitLeft(ValuePadding, 0x0, &SatRect);
|
||||
SatRect.VSplitLeft(HsvValueWidth, &SatRect, &ValueRect);
|
||||
ValueRect.VSplitLeft(ValuePadding, 0x0, &ValueRect);
|
||||
|
||||
BottomArea.HSplitTop(20, &HexRect, &BottomArea);
|
||||
HexRect.VSplitLeft(HexValueWidth, &HexRect, &AlphaRect);
|
||||
AlphaRect.VSplitLeft(ValuePadding, 0x0, &AlphaRect);
|
||||
|
||||
if(UI()->MouseButtonReleased(1) && !UI()->MouseInside(&ValuesHitbox))
|
||||
{
|
||||
ms_ColorPicker.m_Active = false;
|
||||
UI()->SetValueSelectorTextMode(false);
|
||||
UI()->SetActiveItem(nullptr);
|
||||
return;
|
||||
}
|
||||
|
||||
ColorRGBA BlackColor(0, 0, 0, 0.5f);
|
||||
|
||||
HueArea.Draw(BlackColor, 0, 0);
|
||||
HueArea.Margin(1, &HueArea);
|
||||
|
||||
ColorsArea.Draw(BlackColor, 0, 0);
|
||||
ColorsArea.Margin(1, &ColorsArea);
|
||||
|
||||
ColorHSVA PickerColorHSV(ms_ColorPicker.m_HSVColor);
|
||||
unsigned H = (unsigned)(PickerColorHSV.x * 255.0f);
|
||||
unsigned S = (unsigned)(PickerColorHSV.y * 255.0f);
|
||||
unsigned V = (unsigned)(PickerColorHSV.z * 255.0f);
|
||||
|
||||
// Color Area
|
||||
vec4 TL = color_cast<ColorRGBA>(ColorHSVA(PickerColorHSV.x, 0.0f, 1.0f));
|
||||
vec4 TR = color_cast<ColorRGBA>(ColorHSVA(PickerColorHSV.x, 1.0f, 1.0f));
|
||||
vec4 BL = color_cast<ColorRGBA>(ColorHSVA(PickerColorHSV.x, 0.0f, 1.0f));
|
||||
vec4 BR = color_cast<ColorRGBA>(ColorHSVA(PickerColorHSV.x, 1.0f, 1.0f));
|
||||
|
||||
ColorsArea.Draw4(TL, TR, BL, BR, IGraphics::CORNER_NONE, 0.0f);
|
||||
|
||||
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);
|
||||
|
||||
ColorsArea.Draw4(TL, TR, BL, BR, IGraphics::CORNER_NONE, 0.0f);
|
||||
|
||||
// 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;
|
||||
HuePartialArea.Draw4(TL, TL, BL, BL, IGraphics::CORNER_NONE, 0.0f);
|
||||
}
|
||||
|
||||
// Editboxes Area
|
||||
static char s_aValueSelectorIds[4];
|
||||
|
||||
H = UI()->DoValueSelector(&s_aValueSelectorIds[0], &HueRect, "H:", H, 0, 255);
|
||||
S = UI()->DoValueSelector(&s_aValueSelectorIds[1], &SatRect, "S:", S, 0, 255);
|
||||
V = UI()->DoValueSelector(&s_aValueSelectorIds[2], &ValueRect, "V:", V, 0, 255);
|
||||
|
||||
PickerColorHSV = ColorHSVA(H / 255.0f, S / 255.0f, V / 255.0f);
|
||||
|
||||
SValueSelectorProperties Props;
|
||||
Props.m_UseScroll = false;
|
||||
Props.m_IsHex = true;
|
||||
unsigned int Hex = color_cast<ColorRGBA>(PickerColorHSV).Pack(false);
|
||||
unsigned int NewHex = UI()->DoValueSelector(&s_aValueSelectorIds[3], &HexRect, "Hex:", Hex, 0, 0xFFFFFF, Props);
|
||||
|
||||
if(Hex != NewHex)
|
||||
PickerColorHSV = color_cast<ColorHSVA>(ColorRGBA(NewHex));
|
||||
|
||||
// TODO : ALPHA SUPPORT
|
||||
UI()->DoLabel(&AlphaRect, "A: 255", 10, TEXTALIGN_MC);
|
||||
AlphaRect.Draw(ColorRGBA(0, 0, 0, 0.65f), IGraphics::CORNER_ALL, 5.0f);
|
||||
|
||||
// Logic
|
||||
float PickerX, PickerY;
|
||||
static int s_ColorPickerId = 0;
|
||||
if(UI()->DoPickerLogic(&s_ColorPickerId, &ColorsArea, &PickerX, &PickerY))
|
||||
{
|
||||
PickerColorHSV.y = PickerX / ColorsArea.w;
|
||||
PickerColorHSV.z = 1.0f - PickerY / ColorsArea.h;
|
||||
}
|
||||
|
||||
static int s_HuePickerId = 0;
|
||||
if(UI()->DoPickerLogic(&s_HuePickerId, &HueArea, &PickerX, &PickerY))
|
||||
PickerColorHSV.x = 1.0f - PickerY / HueArea.h;
|
||||
|
||||
// Marker Color Area
|
||||
const float MarkerX = ColorsArea.x + ColorsArea.w * PickerColorHSV.y;
|
||||
const float MarkerY = ColorsArea.y + ColorsArea.h * (1.0f - PickerColorHSV.z);
|
||||
|
||||
const float MarkerOutlineInd = PickerColorHSV.z > 0.5f ? 0.0f : 1.0f;
|
||||
const ColorRGBA MarkerOutline = ColorRGBA(MarkerOutlineInd, MarkerOutlineInd, MarkerOutlineInd, 1.0f);
|
||||
|
||||
Graphics()->TextureClear();
|
||||
Graphics()->QuadsBegin();
|
||||
Graphics()->SetColor(MarkerOutline);
|
||||
Graphics()->DrawCircle(MarkerX, MarkerY, 4.5f, 32);
|
||||
Graphics()->SetColor(color_cast<ColorRGBA>(PickerColorHSV));
|
||||
Graphics()->DrawCircle(MarkerX, MarkerY, 3.5f, 32);
|
||||
Graphics()->QuadsEnd();
|
||||
|
||||
// Marker Hue Area
|
||||
CUIRect HueMarker;
|
||||
HueArea.Margin(-2.5f, &HueMarker);
|
||||
HueMarker.h = 6.5f;
|
||||
HueMarker.y = (HueArea.y + HueArea.h * (1.0f - PickerColorHSV.x)) - HueMarker.h / 2.0f;
|
||||
|
||||
const ColorRGBA HueMarkerColor = color_cast<ColorRGBA>(ColorHSVA(PickerColorHSV.x, 1, 1, 1));
|
||||
const float HueMarkerOutlineColor = PickerColorHSV.x > 0.75f ? 1.0f : 0.0f;
|
||||
const ColorRGBA HueMarkerOutline = ColorRGBA(HueMarkerOutlineColor, HueMarkerOutlineColor, HueMarkerOutlineColor, 1);
|
||||
|
||||
HueMarker.Draw(HueMarkerOutline, IGraphics::CORNER_ALL, 1.2f);
|
||||
HueMarker.Margin(1.2f, &HueMarker);
|
||||
HueMarker.Draw(HueMarkerColor, IGraphics::CORNER_ALL, 1.2f);
|
||||
|
||||
ms_ColorPicker.m_HSVColor = PickerColorHSV.Pack(false);
|
||||
*ms_ColorPicker.m_pColor = color_cast<ColorHSLA>(PickerColorHSV).Pack(false);
|
||||
}
|
||||
|
||||
int CMenus::Render()
|
||||
{
|
||||
if(Client()->State() == IClient::STATE_DEMOPLAYBACK && m_Popup == POPUP_NONE)
|
||||
|
@ -2048,7 +1865,6 @@ void CMenus::SetActive(bool Active)
|
|||
{
|
||||
if(Active != m_MenuActive)
|
||||
{
|
||||
ms_ColorPicker.m_Active = false;
|
||||
UI()->SetHotItem(nullptr);
|
||||
UI()->SetActiveItem(nullptr);
|
||||
}
|
||||
|
|
|
@ -29,22 +29,6 @@ struct CServerProcess
|
|||
PROCESS m_Process;
|
||||
};
|
||||
|
||||
struct SColorPicker
|
||||
{
|
||||
public:
|
||||
const float ms_Width = 160.0f;
|
||||
const float ms_Height = 186.0f;
|
||||
|
||||
float m_X;
|
||||
float m_Y;
|
||||
|
||||
bool m_Active;
|
||||
|
||||
CUIRect m_AttachedRect;
|
||||
unsigned int *m_pColor;
|
||||
unsigned int m_HSVColor;
|
||||
};
|
||||
|
||||
// component to fetch keypresses, override all other input
|
||||
class CMenusKeyBinder : public CComponent
|
||||
{
|
||||
|
@ -71,11 +55,9 @@ class CMenus : public CComponent
|
|||
static ColorRGBA ms_ColorTabbarActive;
|
||||
static ColorRGBA ms_ColorTabbarHover;
|
||||
|
||||
static SColorPicker ms_ColorPicker;
|
||||
|
||||
int DoButton_FontIcon(CButtonContainer *pButtonContainer, const char *pText, int Checked, const CUIRect *pRect, int Corners = IGraphics::CORNER_ALL, bool Enabled = true);
|
||||
int DoButton_Toggle(const void *pID, int Checked, const CUIRect *pRect, bool Active);
|
||||
int DoButton_Menu(CButtonContainer *pButtonContainer, const char *pText, int Checked, const CUIRect *pRect, const char *pImageName = nullptr, int Corners = IGraphics::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), bool CheckForActiveColorPicker = false);
|
||||
int DoButton_Menu(CButtonContainer *pButtonContainer, const char *pText, int Checked, const CUIRect *pRect, const char *pImageName = nullptr, int Corners = IGraphics::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 DoButton_MenuTab(CButtonContainer *pButtonContainer, const char *pText, int Checked, const CUIRect *pRect, int Corners, SUIAnimator *pAnimator = nullptr, const ColorRGBA *pDefaultColor = nullptr, const ColorRGBA *pActiveColor = nullptr, const ColorRGBA *pHoverColor = nullptr, float EdgeRounding = 10);
|
||||
|
||||
int DoButton_CheckBox_Common(const void *pID, const char *pText, const char *pBoxText, const CUIRect *pRect);
|
||||
|
@ -83,7 +65,8 @@ class CMenus : public CComponent
|
|||
int DoButton_CheckBoxAutoVMarginAndSet(const void *pID, const char *pText, int *pValue, CUIRect *pRect, float VMargin);
|
||||
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);
|
||||
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);
|
||||
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);
|
||||
|
||||
|
@ -96,8 +79,6 @@ class CMenus : public CComponent
|
|||
void DoJoystickAxisPicker(CUIRect View);
|
||||
void DoJoystickBar(const CUIRect *pRect, float Current, float Tolerance, bool Active);
|
||||
|
||||
void RenderColorPicker();
|
||||
|
||||
void RefreshSkins();
|
||||
|
||||
void RandomSkin();
|
||||
|
@ -679,7 +660,6 @@ private:
|
|||
// found in menus_settings.cpp
|
||||
void RenderSettingsDDNet(CUIRect MainView);
|
||||
void RenderSettingsAppearance(CUIRect MainView);
|
||||
ColorHSLA RenderHSLColorPicker(const CUIRect *pRect, unsigned int *pColor, bool Alpha);
|
||||
ColorHSLA RenderHSLScrollbars(CUIRect *pRect, unsigned int *pColor, bool Alpha = false, bool ClampedLight = false);
|
||||
|
||||
int RenderDropDown(int &CurDropDownState, CUIRect *pRect, int CurSelection, const void **pIDs, const char **pStr, int PickNum, CButtonContainer *pButtonContainer, float &ScrollVal);
|
||||
|
|
|
@ -2122,7 +2122,6 @@ void CMenus::RenderSettings(CUIRect MainView)
|
|||
static CButtonContainer s_aTabButtons[sizeof(apTabs)];
|
||||
|
||||
int NumTabs = (int)std::size(apTabs);
|
||||
int PreviousPage = g_Config.m_UiSettingsPage;
|
||||
|
||||
for(int i = 0; i < NumTabs; i++)
|
||||
{
|
||||
|
@ -2132,9 +2131,6 @@ void CMenus::RenderSettings(CUIRect MainView)
|
|||
g_Config.m_UiSettingsPage = i;
|
||||
}
|
||||
|
||||
if(PreviousPage != g_Config.m_UiSettingsPage)
|
||||
ms_ColorPicker.m_Active = false;
|
||||
|
||||
MainView.Margin(10.0f, &MainView);
|
||||
|
||||
if(g_Config.m_UiSettingsPage == SETTINGS_LANGUAGE)
|
||||
|
@ -2196,49 +2192,6 @@ void CMenus::RenderSettings(CUIRect MainView)
|
|||
}
|
||||
else if(m_NeedRestartGeneral || m_NeedRestartSkins || m_NeedRestartGraphics || m_NeedRestartSound || m_NeedRestartDDNet)
|
||||
UI()->DoLabel(&RestartWarning, Localize("You must restart the game for all settings to take effect."), 14.0f, TEXTALIGN_ML);
|
||||
|
||||
RenderColorPicker();
|
||||
}
|
||||
|
||||
ColorHSLA CMenus::RenderHSLColorPicker(const CUIRect *pRect, unsigned int *pColor, bool Alpha)
|
||||
{
|
||||
ColorHSLA HSLColor(*pColor, false);
|
||||
ColorRGBA RGBColor = color_cast<ColorRGBA>(HSLColor);
|
||||
|
||||
ColorRGBA Outline(1, 1, 1, 0.25f);
|
||||
const float OutlineSize = 3.0f;
|
||||
Outline.a *= UI()->ButtonColorMul(pColor);
|
||||
|
||||
CUIRect Rect;
|
||||
pRect->Margin(OutlineSize, &Rect);
|
||||
|
||||
pRect->Draw(Outline, IGraphics::CORNER_ALL, 4.0f);
|
||||
Rect.Draw(RGBColor, IGraphics::CORNER_ALL, 4.0f);
|
||||
|
||||
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))
|
||||
return HSLColor;
|
||||
}
|
||||
|
||||
const CUIRect *pScreen = UI()->Screen();
|
||||
ms_ColorPicker.m_X = minimum(UI()->MouseX(), pScreen->w - ms_ColorPicker.ms_Width);
|
||||
ms_ColorPicker.m_Y = minimum(UI()->MouseY(), pScreen->h - ms_ColorPicker.ms_Height);
|
||||
ms_ColorPicker.m_pColor = pColor;
|
||||
ms_ColorPicker.m_Active = true;
|
||||
ms_ColorPicker.m_AttachedRect = *pRect;
|
||||
ms_ColorPicker.m_HSVColor = color_cast<ColorHSVA, ColorHSLA>(HSLColor).Pack(false);
|
||||
}
|
||||
|
||||
return HSLColor;
|
||||
}
|
||||
|
||||
ColorHSLA CMenus::RenderHSLScrollbars(CUIRect *pRect, unsigned int *pColor, bool Alpha, bool ClampedLight)
|
||||
|
|
|
@ -1539,3 +1539,180 @@ void CUI::ShowPopupSelection(float X, float Y, SSelectionPopupContext *pContext)
|
|||
pContext->m_pSelection = nullptr;
|
||||
DoPopupMenu(pContext, X, Y, SSelectionPopupContext::POPUP_MAX_WIDTH + 10.0f, PopupHeight, pContext, PopupSelection);
|
||||
}
|
||||
|
||||
CUI::EPopupMenuFunctionResult CUI::PopupColorPicker(void *pContext, CUIRect View, bool Active)
|
||||
{
|
||||
SColorPickerPopupContext *pColorPicker = static_cast<SColorPickerPopupContext *>(pContext);
|
||||
CUI *pUI = pColorPicker->m_pUI;
|
||||
|
||||
CUIRect ColorsArea = View, HueArea, BottomArea, HueRect, SatRect, ValueRect, HexRect, AlphaRect;
|
||||
|
||||
ColorsArea.HSplitBottom(View.h - 140.0f, &ColorsArea, &BottomArea);
|
||||
ColorsArea.VSplitRight(20.0f, &ColorsArea, &HueArea);
|
||||
|
||||
BottomArea.HSplitTop(3.0f, nullptr, &BottomArea);
|
||||
HueArea.VSplitLeft(3.0f, nullptr, &HueArea);
|
||||
|
||||
BottomArea.HSplitTop(20.0f, &HueRect, &BottomArea);
|
||||
BottomArea.HSplitTop(3.0f, nullptr, &BottomArea);
|
||||
|
||||
constexpr float ValuePadding = 5.0f;
|
||||
const float HsvValueWidth = (HueRect.w - ValuePadding * 2) / 3.0f;
|
||||
const float HexValueWidth = HsvValueWidth * 2 + ValuePadding;
|
||||
|
||||
HueRect.VSplitLeft(HsvValueWidth, &HueRect, &SatRect);
|
||||
SatRect.VSplitLeft(ValuePadding, nullptr, &SatRect);
|
||||
SatRect.VSplitLeft(HsvValueWidth, &SatRect, &ValueRect);
|
||||
ValueRect.VSplitLeft(ValuePadding, nullptr, &ValueRect);
|
||||
|
||||
BottomArea.HSplitTop(20.0f, &HexRect, &BottomArea);
|
||||
HexRect.VSplitLeft(HexValueWidth, &HexRect, &AlphaRect);
|
||||
AlphaRect.VSplitLeft(ValuePadding, nullptr, &AlphaRect);
|
||||
|
||||
const ColorRGBA BlackColor = ColorRGBA(0.0f, 0.0f, 0.0f, 0.5f);
|
||||
|
||||
HueArea.Draw(BlackColor, IGraphics::CORNER_NONE, 0.0f);
|
||||
HueArea.Margin(1.0f, &HueArea);
|
||||
|
||||
ColorsArea.Draw(BlackColor, IGraphics::CORNER_NONE, 0.0f);
|
||||
ColorsArea.Margin(1.0f, &ColorsArea);
|
||||
|
||||
ColorHSVA PickerColorHSV = ColorHSVA(pColorPicker->m_HSVColor, pColorPicker->m_Alpha);
|
||||
unsigned H = (unsigned)(PickerColorHSV.x * 255.0f);
|
||||
unsigned S = (unsigned)(PickerColorHSV.y * 255.0f);
|
||||
unsigned V = (unsigned)(PickerColorHSV.z * 255.0f);
|
||||
unsigned A = (unsigned)(PickerColorHSV.a * 255.0f);
|
||||
|
||||
// Color Area
|
||||
ColorRGBA TL, TR, BL, BR;
|
||||
TL = BL = color_cast<ColorRGBA>(ColorHSVA(PickerColorHSV.x, 0.0f, 1.0f));
|
||||
TR = BR = color_cast<ColorRGBA>(ColorHSVA(PickerColorHSV.x, 1.0f, 1.0f));
|
||||
ColorsArea.Draw4(TL, TR, BL, BR, IGraphics::CORNER_NONE, 0.0f);
|
||||
|
||||
TL = TR = ColorRGBA(0.0f, 0.0f, 0.0f, 0.0f);
|
||||
BL = BR = ColorRGBA(0.0f, 0.0f, 0.0f, 1.0f);
|
||||
ColorsArea.Draw4(TL, TR, BL, BR, IGraphics::CORNER_NONE, 0.0f);
|
||||
|
||||
// Hue Area
|
||||
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
|
||||
};
|
||||
|
||||
const float HuePickerOffset = HueArea.h / 6.0f;
|
||||
CUIRect HuePartialArea = HueArea;
|
||||
HuePartialArea.h = HuePickerOffset;
|
||||
|
||||
for(size_t j = 0; j < std::size(s_aaColorIndices) - 1; j++)
|
||||
{
|
||||
TL = ColorRGBA(s_aaColorIndices[j][0], s_aaColorIndices[j][1], s_aaColorIndices[j][2], 1.0f);
|
||||
BL = ColorRGBA(s_aaColorIndices[j + 1][0], s_aaColorIndices[j + 1][1], s_aaColorIndices[j + 1][2], 1.0f);
|
||||
|
||||
HuePartialArea.y = HueArea.y + HuePickerOffset * j;
|
||||
HuePartialArea.Draw4(TL, TL, BL, BL, IGraphics::CORNER_NONE, 0.0f);
|
||||
}
|
||||
|
||||
// Editboxes Area
|
||||
H = pUI->DoValueSelector(&pColorPicker->m_aValueSelectorIds[0], &HueRect, "H:", H, 0, 255);
|
||||
S = pUI->DoValueSelector(&pColorPicker->m_aValueSelectorIds[1], &SatRect, "S:", S, 0, 255);
|
||||
V = pUI->DoValueSelector(&pColorPicker->m_aValueSelectorIds[2], &ValueRect, "V:", V, 0, 255);
|
||||
if(pColorPicker->m_Alpha)
|
||||
{
|
||||
A = pUI->DoValueSelector(&pColorPicker->m_aValueSelectorIds[3], &AlphaRect, "A:", A, 0, 255);
|
||||
}
|
||||
else
|
||||
{
|
||||
char aBuf[8];
|
||||
str_format(aBuf, sizeof(aBuf), "A: %d", A);
|
||||
pUI->DoLabel(&AlphaRect, aBuf, 10.0f, TEXTALIGN_MC);
|
||||
AlphaRect.Draw(ColorRGBA(0.0f, 0.0f, 0.0f, 0.65f), IGraphics::CORNER_ALL, 3.0f);
|
||||
}
|
||||
|
||||
PickerColorHSV = ColorHSVA(H / 255.0f, S / 255.0f, V / 255.0f, A / 255.0f);
|
||||
|
||||
const auto RotateByteLeft = [pColorPicker](unsigned Num) {
|
||||
if(pColorPicker->m_Alpha)
|
||||
{
|
||||
// ARGB -> RGBA (internal -> displayed)
|
||||
return ((Num & 0xFF000000u) >> 24) | (Num << 8);
|
||||
}
|
||||
return Num;
|
||||
};
|
||||
const auto RotateByteRight = [pColorPicker](unsigned Num) {
|
||||
if(pColorPicker->m_Alpha)
|
||||
{
|
||||
// RGBA -> ARGB (displayed -> internal)
|
||||
return ((Num & 0xFFu) << 24) | (Num >> 8);
|
||||
}
|
||||
return Num;
|
||||
};
|
||||
|
||||
SValueSelectorProperties Props;
|
||||
Props.m_UseScroll = false;
|
||||
Props.m_IsHex = true;
|
||||
Props.m_HexPrefix = pColorPicker->m_Alpha ? 8 : 6;
|
||||
const unsigned Hex = RotateByteLeft(color_cast<ColorRGBA>(PickerColorHSV).Pack(pColorPicker->m_Alpha));
|
||||
const unsigned NewHex = pUI->DoValueSelector(&pColorPicker->m_aValueSelectorIds[4], &HexRect, "Hex:", Hex, 0, pColorPicker->m_Alpha ? 0xFFFFFFFFll : 0xFFFFFFll, Props);
|
||||
if(Hex != NewHex)
|
||||
{
|
||||
PickerColorHSV = color_cast<ColorHSVA>(ColorRGBA(RotateByteRight(NewHex), pColorPicker->m_Alpha));
|
||||
if(!pColorPicker->m_Alpha)
|
||||
PickerColorHSV.a = A / 255.0f;
|
||||
}
|
||||
|
||||
// Logic
|
||||
float PickerX, PickerY;
|
||||
if(pUI->DoPickerLogic(&pColorPicker->m_ColorPickerId, &ColorsArea, &PickerX, &PickerY))
|
||||
{
|
||||
PickerColorHSV.y = PickerX / ColorsArea.w;
|
||||
PickerColorHSV.z = 1.0f - PickerY / ColorsArea.h;
|
||||
}
|
||||
|
||||
if(pUI->DoPickerLogic(&pColorPicker->m_HuePickerId, &HueArea, &PickerX, &PickerY))
|
||||
PickerColorHSV.x = 1.0f - PickerY / HueArea.h;
|
||||
|
||||
// Marker Color Area
|
||||
const float MarkerX = ColorsArea.x + ColorsArea.w * PickerColorHSV.y;
|
||||
const float MarkerY = ColorsArea.y + ColorsArea.h * (1.0f - PickerColorHSV.z);
|
||||
|
||||
const float MarkerOutlineInd = PickerColorHSV.z > 0.5f ? 0.0f : 1.0f;
|
||||
const ColorRGBA MarkerOutline = ColorRGBA(MarkerOutlineInd, MarkerOutlineInd, MarkerOutlineInd, 1.0f);
|
||||
|
||||
pUI->Graphics()->TextureClear();
|
||||
pUI->Graphics()->QuadsBegin();
|
||||
pUI->Graphics()->SetColor(MarkerOutline);
|
||||
pUI->Graphics()->DrawCircle(MarkerX, MarkerY, 4.5f, 32);
|
||||
pUI->Graphics()->SetColor(color_cast<ColorRGBA>(PickerColorHSV));
|
||||
pUI->Graphics()->DrawCircle(MarkerX, MarkerY, 3.5f, 32);
|
||||
pUI->Graphics()->QuadsEnd();
|
||||
|
||||
// Marker Hue Area
|
||||
CUIRect HueMarker;
|
||||
HueArea.Margin(-2.5f, &HueMarker);
|
||||
HueMarker.h = 6.5f;
|
||||
HueMarker.y = (HueArea.y + HueArea.h * (1.0f - PickerColorHSV.x)) - HueMarker.h / 2.0f;
|
||||
|
||||
const ColorRGBA HueMarkerColor = color_cast<ColorRGBA>(ColorHSVA(PickerColorHSV.x, 1.0f, 1.0f, 1.0f));
|
||||
const float HueMarkerOutlineColor = PickerColorHSV.x > 0.75f ? 1.0f : 0.0f;
|
||||
const ColorRGBA HueMarkerOutline = ColorRGBA(HueMarkerOutlineColor, HueMarkerOutlineColor, HueMarkerOutlineColor, 1.0f);
|
||||
|
||||
HueMarker.Draw(HueMarkerOutline, IGraphics::CORNER_ALL, 1.2f);
|
||||
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<ColorHSLA>(PickerColorHSV).Pack(pColorPicker->m_Alpha);
|
||||
|
||||
return CUI::POPUP_KEEP_OPEN;
|
||||
}
|
||||
|
||||
void CUI::ShowPopupColorPicker(float X, float Y, SColorPickerPopupContext *pContext)
|
||||
{
|
||||
pContext->m_pUI = this;
|
||||
DoPopupMenu(pContext, X, Y, 160.0f + 10.0f, 186.0f + 10.0f, pContext, PopupColorPicker);
|
||||
}
|
||||
|
|
|
@ -332,6 +332,7 @@ private:
|
|||
static CUI::EPopupMenuFunctionResult PopupMessage(void *pContext, CUIRect View, bool Active);
|
||||
static CUI::EPopupMenuFunctionResult PopupConfirm(void *pContext, CUIRect View, bool Active);
|
||||
static CUI::EPopupMenuFunctionResult PopupSelection(void *pContext, CUIRect View, bool Active);
|
||||
static CUI::EPopupMenuFunctionResult PopupColorPicker(void *pContext, CUIRect View, bool Active);
|
||||
|
||||
IClient *m_pClient;
|
||||
IGraphics *m_pGraphics;
|
||||
|
@ -574,6 +575,18 @@ public:
|
|||
void Reset();
|
||||
};
|
||||
void ShowPopupSelection(float X, float Y, SSelectionPopupContext *pContext);
|
||||
|
||||
struct SColorPickerPopupContext : public SPopupMenuId
|
||||
{
|
||||
CUI *m_pUI; // set by CUI when popup is shown
|
||||
bool m_Alpha = false;
|
||||
unsigned int *m_pColor;
|
||||
unsigned int m_HSVColor;
|
||||
const char m_HuePickerId = 0;
|
||||
const char m_ColorPickerId = 0;
|
||||
const char m_aValueSelectorIds[5] = {0};
|
||||
};
|
||||
void ShowPopupColorPicker(float X, float Y, SColorPickerPopupContext *pContext);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in a new issue