mirror of
https://github.com/ddnet/ddnet.git
synced 2024-11-10 01:58:19 +00:00
Merge pull request #7433 from Robyt3/Editor-Color-Picker-Refactoring
Show color picker button for color envelope points
This commit is contained in:
commit
79e244f166
|
@ -3098,58 +3098,15 @@ int CEditor::DoProperties(CUIRect *pToolBox, CProperty *pProps, int *pIDs, int *
|
||||||
}
|
}
|
||||||
else if(pProps[i].m_Type == PROPTYPE_COLOR)
|
else if(pProps[i].m_Type == PROPTYPE_COLOR)
|
||||||
{
|
{
|
||||||
const ColorRGBA ColorPick = ColorRGBA::UnpackAlphaLast<ColorRGBA>(pProps[i].m_Value);
|
const auto &&SetColor = [&](ColorRGBA NewColor) {
|
||||||
|
const int NewValue = NewColor.PackAlphaLast();
|
||||||
CUIRect ColorRect;
|
if(NewValue != pProps[i].m_Value)
|
||||||
Shifter.Draw(ColorRGBA(1.0f, 1.0f, 1.0f, 0.5f * UI()->ButtonColorMul(&pIDs[i])), IGraphics::CORNER_ALL, 5.0f);
|
|
||||||
Shifter.Margin(1.0f, &ColorRect);
|
|
||||||
ColorRect.Draw(ColorPick, IGraphics::CORNER_ALL, ColorRect.h / 2.0f);
|
|
||||||
|
|
||||||
static CUI::SColorPickerPopupContext s_ColorPickerPopupContext;
|
|
||||||
const int ButtonResult = DoButton_Editor_Common(&pIDs[i], nullptr, 0, &Shifter, 0, "Click to show the color picker. Shift+rightclick to copy color to clipboard. Shift+leftclick to paste color from clipboard.");
|
|
||||||
if(Input()->ShiftIsPressed())
|
|
||||||
{
|
|
||||||
if(ButtonResult == 1)
|
|
||||||
{
|
{
|
||||||
const char *pClipboard = Input()->GetClipboardText();
|
*pNewVal = NewValue;
|
||||||
if(*pClipboard == '#' || *pClipboard == '$') // ignore leading # (web color format) and $ (console color format)
|
|
||||||
++pClipboard;
|
|
||||||
if(str_isallnum_hex(pClipboard))
|
|
||||||
{
|
|
||||||
std::optional<ColorRGBA> ParsedColor = color_parse<ColorRGBA>(pClipboard);
|
|
||||||
if(ParsedColor)
|
|
||||||
{
|
|
||||||
*pNewVal = ParsedColor.value().PackAlphaLast();
|
|
||||||
Change = i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if(ButtonResult == 2)
|
|
||||||
{
|
|
||||||
char aClipboard[9];
|
|
||||||
str_format(aClipboard, sizeof(aClipboard), "%08X", ColorPick.PackAlphaLast());
|
|
||||||
Input()->SetClipboardText(aClipboard);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if(ButtonResult > 0)
|
|
||||||
{
|
|
||||||
if(s_ColorPickerPopupContext.m_ColorMode == CUI::SColorPickerPopupContext::MODE_UNSET)
|
|
||||||
s_ColorPickerPopupContext.m_ColorMode = CUI::SColorPickerPopupContext::MODE_RGBA;
|
|
||||||
s_ColorPickerPopupContext.m_RgbaColor = ColorPick;
|
|
||||||
s_ColorPickerPopupContext.m_HslaColor = color_cast<ColorHSLA>(ColorPick);
|
|
||||||
s_ColorPickerPopupContext.m_HsvaColor = color_cast<ColorHSVA>(s_ColorPickerPopupContext.m_HslaColor);
|
|
||||||
s_ColorPickerPopupContext.m_Alpha = true;
|
|
||||||
UI()->ShowPopupColorPicker(UI()->MouseX(), UI()->MouseY(), &s_ColorPickerPopupContext);
|
|
||||||
}
|
|
||||||
else if(UI()->IsPopupOpen(&s_ColorPickerPopupContext))
|
|
||||||
{
|
|
||||||
const int NewColor = s_ColorPickerPopupContext.m_RgbaColor.PackAlphaLast(s_ColorPickerPopupContext.m_Alpha);
|
|
||||||
if(NewColor != pProps[i].m_Value)
|
|
||||||
{
|
|
||||||
*pNewVal = NewColor;
|
|
||||||
Change = i;
|
Change = i;
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
DoColorPickerButton(&pIDs[i], &Shifter, ColorRGBA::UnpackAlphaLast<ColorRGBA>(pProps[i].m_Value), SetColor);
|
||||||
}
|
}
|
||||||
else if(pProps[i].m_Type == PROPTYPE_IMAGE)
|
else if(pProps[i].m_Type == PROPTYPE_IMAGE)
|
||||||
{
|
{
|
||||||
|
@ -3284,6 +3241,60 @@ int CEditor::DoProperties(CUIRect *pToolBox, CProperty *pProps, int *pIDs, int *
|
||||||
return Change;
|
return Change;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CEditor::DoColorPickerButton(const void *pID, const CUIRect *pRect, ColorRGBA Color, const std::function<void(ColorRGBA Color)> &SetColor)
|
||||||
|
{
|
||||||
|
CUIRect ColorRect;
|
||||||
|
pRect->Draw(ColorRGBA(1.0f, 1.0f, 1.0f, 0.5f * UI()->ButtonColorMul(pID)), IGraphics::CORNER_ALL, 5.0f);
|
||||||
|
pRect->Margin(1.0f, &ColorRect);
|
||||||
|
ColorRect.Draw(Color, IGraphics::CORNER_ALL, 5.0f);
|
||||||
|
|
||||||
|
const int ButtonResult = DoButton_Editor_Common(pID, nullptr, 0, pRect, 0, "Click to show the color picker. Shift+rightclick to copy color to clipboard. Shift+leftclick to paste color from clipboard.");
|
||||||
|
if(Input()->ShiftIsPressed())
|
||||||
|
{
|
||||||
|
if(ButtonResult == 1)
|
||||||
|
{
|
||||||
|
const char *pClipboard = Input()->GetClipboardText();
|
||||||
|
if(*pClipboard == '#' || *pClipboard == '$') // ignore leading # (web color format) and $ (console color format)
|
||||||
|
++pClipboard;
|
||||||
|
if(str_isallnum_hex(pClipboard))
|
||||||
|
{
|
||||||
|
std::optional<ColorRGBA> ParsedColor = color_parse<ColorRGBA>(pClipboard);
|
||||||
|
if(ParsedColor)
|
||||||
|
{
|
||||||
|
SetColor(ParsedColor.value());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(ButtonResult == 2)
|
||||||
|
{
|
||||||
|
char aClipboard[9];
|
||||||
|
str_format(aClipboard, sizeof(aClipboard), "%08X", Color.PackAlphaLast());
|
||||||
|
Input()->SetClipboardText(aClipboard);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(ButtonResult > 0)
|
||||||
|
{
|
||||||
|
if(m_ColorPickerPopupContext.m_ColorMode == CUI::SColorPickerPopupContext::MODE_UNSET)
|
||||||
|
m_ColorPickerPopupContext.m_ColorMode = CUI::SColorPickerPopupContext::MODE_RGBA;
|
||||||
|
m_ColorPickerPopupContext.m_RgbaColor = Color;
|
||||||
|
m_ColorPickerPopupContext.m_HslaColor = color_cast<ColorHSLA>(Color);
|
||||||
|
m_ColorPickerPopupContext.m_HsvaColor = color_cast<ColorHSVA>(m_ColorPickerPopupContext.m_HslaColor);
|
||||||
|
m_ColorPickerPopupContext.m_Alpha = true;
|
||||||
|
m_pColorPickerPopupActiveID = pID;
|
||||||
|
UI()->ShowPopupColorPicker(UI()->MouseX(), UI()->MouseY(), &m_ColorPickerPopupContext);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(UI()->IsPopupOpen(&m_ColorPickerPopupContext))
|
||||||
|
{
|
||||||
|
if(m_pColorPickerPopupActiveID == pID)
|
||||||
|
SetColor(m_ColorPickerPopupContext.m_RgbaColor);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_pColorPickerPopupActiveID = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void CEditor::RenderLayers(CUIRect LayersBox)
|
void CEditor::RenderLayers(CUIRect LayersBox)
|
||||||
{
|
{
|
||||||
const float RowHeight = 12.0f;
|
const float RowHeight = 12.0f;
|
||||||
|
@ -6258,6 +6269,11 @@ void CEditor::RenderEnvelopeEditor(CUIRect View)
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
|
static SPopupMenuId s_PopupEnvPointId;
|
||||||
|
const auto &&ShowPopupEnvPoint = [&]() {
|
||||||
|
UI()->DoPopupMenu(&s_PopupEnvPointId, UI()->MouseX(), UI()->MouseY(), 150, 56 + (pEnvelope->GetChannels() == 4 ? 16.0f : 0.0f), this, PopupEnvPoint);
|
||||||
|
};
|
||||||
|
|
||||||
if(s_Operation == OP_NONE)
|
if(s_Operation == OP_NONE)
|
||||||
SetHotEnvelopePoint(View, pEnvelope, s_ActiveChannels);
|
SetHotEnvelopePoint(View, pEnvelope, s_ActiveChannels);
|
||||||
|
|
||||||
|
@ -6401,8 +6417,7 @@ void CEditor::RenderEnvelopeEditor(CUIRect View)
|
||||||
if(m_vSelectedEnvelopePoints.size() == 1)
|
if(m_vSelectedEnvelopePoints.size() == 1)
|
||||||
{
|
{
|
||||||
m_UpdateEnvPointInfo = true;
|
m_UpdateEnvPointInfo = true;
|
||||||
static SPopupMenuId s_PopupEnvPointId;
|
ShowPopupEnvPoint();
|
||||||
UI()->DoPopupMenu(&s_PopupEnvPointId, UI()->MouseX(), UI()->MouseY(), 150, 56, this, PopupEnvPoint);
|
|
||||||
}
|
}
|
||||||
else if(m_vSelectedEnvelopePoints.size() > 1)
|
else if(m_vSelectedEnvelopePoints.size() > 1)
|
||||||
{
|
{
|
||||||
|
@ -6545,8 +6560,7 @@ void CEditor::RenderEnvelopeEditor(CUIRect View)
|
||||||
if(IsTangentOutPointSelected(i, c))
|
if(IsTangentOutPointSelected(i, c))
|
||||||
{
|
{
|
||||||
m_UpdateEnvPointInfo = true;
|
m_UpdateEnvPointInfo = true;
|
||||||
static SPopupMenuId s_PopupEnvPointId;
|
ShowPopupEnvPoint();
|
||||||
UI()->DoPopupMenu(&s_PopupEnvPointId, UI()->MouseX(), UI()->MouseY(), 150, 56, this, PopupEnvPoint);
|
|
||||||
}
|
}
|
||||||
UI()->SetActiveItem(nullptr);
|
UI()->SetActiveItem(nullptr);
|
||||||
}
|
}
|
||||||
|
@ -6678,8 +6692,7 @@ void CEditor::RenderEnvelopeEditor(CUIRect View)
|
||||||
if(IsTangentInPointSelected(i, c))
|
if(IsTangentInPointSelected(i, c))
|
||||||
{
|
{
|
||||||
m_UpdateEnvPointInfo = true;
|
m_UpdateEnvPointInfo = true;
|
||||||
static SPopupMenuId s_PopupEnvPointId;
|
ShowPopupEnvPoint();
|
||||||
UI()->DoPopupMenu(&s_PopupEnvPointId, UI()->MouseX(), UI()->MouseY(), 150, 56, this, PopupEnvPoint);
|
|
||||||
}
|
}
|
||||||
UI()->SetActiveItem(nullptr);
|
UI()->SetActiveItem(nullptr);
|
||||||
}
|
}
|
||||||
|
|
|
@ -496,6 +496,10 @@ public:
|
||||||
|
|
||||||
int DoProperties(CUIRect *pToolbox, CProperty *pProps, int *pIDs, int *pNewVal, ColorRGBA Color = ColorRGBA(1, 1, 1, 0.5f));
|
int DoProperties(CUIRect *pToolbox, CProperty *pProps, int *pIDs, int *pNewVal, ColorRGBA Color = ColorRGBA(1, 1, 1, 0.5f));
|
||||||
|
|
||||||
|
CUI::SColorPickerPopupContext m_ColorPickerPopupContext;
|
||||||
|
const void *m_pColorPickerPopupActiveID = nullptr;
|
||||||
|
void DoColorPickerButton(const void *pID, const CUIRect *pRect, ColorRGBA Color, const std::function<void(ColorRGBA Color)> &SetColor);
|
||||||
|
|
||||||
int m_Mode;
|
int m_Mode;
|
||||||
int m_Dialog;
|
int m_Dialog;
|
||||||
char m_aTooltip[256] = "";
|
char m_aTooltip[256] = "";
|
||||||
|
|
|
@ -1296,10 +1296,34 @@ CUI::EPopupMenuFunctionResult CEditor::PopupEnvPoint(void *pContext, CUIRect Vie
|
||||||
|
|
||||||
pEditor->m_ShowEnvelopePreview = SHOWENV_SELECTED;
|
pEditor->m_ShowEnvelopePreview = SHOWENV_SELECTED;
|
||||||
|
|
||||||
|
std::shared_ptr<CEnvelope> pEnvelope = pEditor->m_Map.m_vpEnvelopes[pEditor->m_SelectedEnvelope];
|
||||||
|
|
||||||
|
if(pEnvelope->GetChannels() == 4)
|
||||||
|
{
|
||||||
|
View.HSplitTop(RowHeight, &Row, &View);
|
||||||
|
View.HSplitTop(4.0f, nullptr, &View);
|
||||||
|
Row.VSplitLeft(60.0f, &Label, &Row);
|
||||||
|
Row.VSplitLeft(10.0f, nullptr, &EditBox);
|
||||||
|
pEditor->UI()->DoLabel(&Label, "Color:", RowHeight - 2.0f, TEXTALIGN_ML);
|
||||||
|
|
||||||
|
const auto [SelectedIndex, _] = pEditor->m_vSelectedEnvelopePoints.front();
|
||||||
|
auto *pValues = pEnvelope->m_vPoints[SelectedIndex].m_aValues;
|
||||||
|
const ColorRGBA Color = ColorRGBA(fx2f(pValues[0]), fx2f(pValues[1]), fx2f(pValues[2]), fx2f(pValues[3]));
|
||||||
|
const auto &&SetColor = [&](ColorRGBA NewColor) {
|
||||||
|
if(Color == NewColor)
|
||||||
|
return;
|
||||||
|
for(int Channel = 0; Channel < 4; ++Channel)
|
||||||
|
pValues[Channel] = f2fx(NewColor[Channel]);
|
||||||
|
pEditor->m_UpdateEnvPointInfo = true;
|
||||||
|
pEditor->m_Map.OnModify();
|
||||||
|
};
|
||||||
|
static char s_ColorPickerButton;
|
||||||
|
pEditor->DoColorPickerButton(&s_ColorPickerButton, &EditBox, Color, SetColor);
|
||||||
|
}
|
||||||
|
|
||||||
static CLineInputNumber s_CurValueInput;
|
static CLineInputNumber s_CurValueInput;
|
||||||
static CLineInputNumber s_CurTimeInput;
|
static CLineInputNumber s_CurTimeInput;
|
||||||
|
|
||||||
std::shared_ptr<CEnvelope> pEnvelope = pEditor->m_Map.m_vpEnvelopes[pEditor->m_SelectedEnvelope];
|
|
||||||
if(pEditor->m_UpdateEnvPointInfo)
|
if(pEditor->m_UpdateEnvPointInfo)
|
||||||
{
|
{
|
||||||
pEditor->m_UpdateEnvPointInfo = false;
|
pEditor->m_UpdateEnvPointInfo = false;
|
||||||
|
@ -1336,14 +1360,14 @@ CUI::EPopupMenuFunctionResult CEditor::PopupEnvPoint(void *pContext, CUIRect Vie
|
||||||
View.HSplitTop(RowHeight, &Row, &View);
|
View.HSplitTop(RowHeight, &Row, &View);
|
||||||
Row.VSplitLeft(60.0f, &Label, &Row);
|
Row.VSplitLeft(60.0f, &Label, &Row);
|
||||||
Row.VSplitLeft(10.0f, nullptr, &EditBox);
|
Row.VSplitLeft(10.0f, nullptr, &EditBox);
|
||||||
pEditor->UI()->DoLabel(&Label, "Value:", RowHeight - 2.0f, TEXTALIGN_LEFT);
|
pEditor->UI()->DoLabel(&Label, "Value:", RowHeight - 2.0f, TEXTALIGN_ML);
|
||||||
pEditor->DoEditBox(&s_CurValueInput, &EditBox, RowHeight - 2.0f, IGraphics::CORNER_ALL, "The value of the selected envelope point");
|
pEditor->DoEditBox(&s_CurValueInput, &EditBox, RowHeight - 2.0f, IGraphics::CORNER_ALL, "The value of the selected envelope point");
|
||||||
|
|
||||||
View.HMargin(4.0f, &View);
|
View.HSplitTop(4.0f, nullptr, &View);
|
||||||
View.HSplitTop(RowHeight, &Row, &View);
|
View.HSplitTop(RowHeight, &Row, &View);
|
||||||
Row.VSplitLeft(60.0f, &Label, &Row);
|
Row.VSplitLeft(60.0f, &Label, &Row);
|
||||||
Row.VSplitLeft(10.0f, nullptr, &EditBox);
|
Row.VSplitLeft(10.0f, nullptr, &EditBox);
|
||||||
pEditor->UI()->DoLabel(&Label, "Time (in s):", RowHeight - 2.0f, TEXTALIGN_LEFT);
|
pEditor->UI()->DoLabel(&Label, "Time (in s):", RowHeight - 2.0f, TEXTALIGN_ML);
|
||||||
pEditor->DoEditBox(&s_CurTimeInput, &EditBox, RowHeight - 2.0f, IGraphics::CORNER_ALL, "The time of the selected envelope point");
|
pEditor->DoEditBox(&s_CurTimeInput, &EditBox, RowHeight - 2.0f, IGraphics::CORNER_ALL, "The time of the selected envelope point");
|
||||||
|
|
||||||
if(pEditor->Input()->KeyIsPressed(KEY_RETURN) || pEditor->Input()->KeyIsPressed(KEY_KP_ENTER))
|
if(pEditor->Input()->KeyIsPressed(KEY_RETURN) || pEditor->Input()->KeyIsPressed(KEY_KP_ENTER))
|
||||||
|
@ -1371,7 +1395,6 @@ CUI::EPopupMenuFunctionResult CEditor::PopupEnvPoint(void *pContext, CUIRect Vie
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
auto [SelectedIndex, SelectedChannel] = pEditor->m_vSelectedEnvelopePoints.front();
|
auto [SelectedIndex, SelectedChannel] = pEditor->m_vSelectedEnvelopePoints.front();
|
||||||
|
|
||||||
if(pEnvelope->GetChannels() == 4)
|
if(pEnvelope->GetChannels() == 4)
|
||||||
CurrentValue = clamp(CurrentValue, 0.0f, 1.0f);
|
CurrentValue = clamp(CurrentValue, 0.0f, 1.0f);
|
||||||
pEnvelope->m_vPoints[SelectedIndex].m_aValues[SelectedChannel] = f2fx(CurrentValue);
|
pEnvelope->m_vPoints[SelectedIndex].m_aValues[SelectedChannel] = f2fx(CurrentValue);
|
||||||
|
@ -1400,7 +1423,7 @@ CUI::EPopupMenuFunctionResult CEditor::PopupEnvPoint(void *pContext, CUIRect Vie
|
||||||
pEditor->m_Map.OnModify();
|
pEditor->m_Map.OnModify();
|
||||||
}
|
}
|
||||||
|
|
||||||
View.HMargin(6.0f, &View);
|
View.HSplitTop(6.0f, nullptr, &View);
|
||||||
View.HSplitTop(RowHeight, &Row, &View);
|
View.HSplitTop(RowHeight, &Row, &View);
|
||||||
static int s_DeleteButtonID = 0;
|
static int s_DeleteButtonID = 0;
|
||||||
const char *pButtonText = pEditor->IsTangentSelected() ? "Reset" : "Delete";
|
const char *pButtonText = pEditor->IsTangentSelected() ? "Reset" : "Delete";
|
||||||
|
|
Loading…
Reference in a new issue