diff --git a/src/game/editor/editor.cpp b/src/game/editor/editor.cpp index ce5885af0..7121da923 100644 --- a/src/game/editor/editor.cpp +++ b/src/game/editor/editor.cpp @@ -3098,58 +3098,15 @@ int CEditor::DoProperties(CUIRect *pToolBox, CProperty *pProps, int *pIDs, int * } else if(pProps[i].m_Type == PROPTYPE_COLOR) { - const ColorRGBA ColorPick = ColorRGBA::UnpackAlphaLast(pProps[i].m_Value); - - CUIRect ColorRect; - 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 auto &&SetColor = [&](ColorRGBA NewColor) { + const int NewValue = NewColor.PackAlphaLast(); + if(NewValue != pProps[i].m_Value) { - 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 ParsedColor = color_parse(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(ColorPick); - s_ColorPickerPopupContext.m_HsvaColor = color_cast(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; + *pNewVal = NewValue; Change = i; } - } + }; + DoColorPickerButton(&pIDs[i], &Shifter, ColorRGBA::UnpackAlphaLast(pProps[i].m_Value), SetColor); } else if(pProps[i].m_Type == PROPTYPE_IMAGE) { @@ -3284,6 +3241,60 @@ int CEditor::DoProperties(CUIRect *pToolBox, CProperty *pProps, int *pIDs, int * return Change; } +void CEditor::DoColorPickerButton(const void *pID, const CUIRect *pRect, ColorRGBA Color, const std::function &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 ParsedColor = color_parse(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(Color); + m_ColorPickerPopupContext.m_HsvaColor = color_cast(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) { 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) SetHotEnvelopePoint(View, pEnvelope, s_ActiveChannels); @@ -6401,8 +6417,7 @@ void CEditor::RenderEnvelopeEditor(CUIRect View) if(m_vSelectedEnvelopePoints.size() == 1) { m_UpdateEnvPointInfo = true; - static SPopupMenuId s_PopupEnvPointId; - UI()->DoPopupMenu(&s_PopupEnvPointId, UI()->MouseX(), UI()->MouseY(), 150, 56, this, PopupEnvPoint); + ShowPopupEnvPoint(); } else if(m_vSelectedEnvelopePoints.size() > 1) { @@ -6545,8 +6560,7 @@ void CEditor::RenderEnvelopeEditor(CUIRect View) if(IsTangentOutPointSelected(i, c)) { m_UpdateEnvPointInfo = true; - static SPopupMenuId s_PopupEnvPointId; - UI()->DoPopupMenu(&s_PopupEnvPointId, UI()->MouseX(), UI()->MouseY(), 150, 56, this, PopupEnvPoint); + ShowPopupEnvPoint(); } UI()->SetActiveItem(nullptr); } @@ -6678,8 +6692,7 @@ void CEditor::RenderEnvelopeEditor(CUIRect View) if(IsTangentInPointSelected(i, c)) { m_UpdateEnvPointInfo = true; - static SPopupMenuId s_PopupEnvPointId; - UI()->DoPopupMenu(&s_PopupEnvPointId, UI()->MouseX(), UI()->MouseY(), 150, 56, this, PopupEnvPoint); + ShowPopupEnvPoint(); } UI()->SetActiveItem(nullptr); } diff --git a/src/game/editor/editor.h b/src/game/editor/editor.h index 1d66de2fd..19327666c 100644 --- a/src/game/editor/editor.h +++ b/src/game/editor/editor.h @@ -496,6 +496,10 @@ public: 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 &SetColor); + int m_Mode; int m_Dialog; char m_aTooltip[256] = ""; diff --git a/src/game/editor/popups.cpp b/src/game/editor/popups.cpp index 14ce6e499..3cddb4321 100644 --- a/src/game/editor/popups.cpp +++ b/src/game/editor/popups.cpp @@ -1296,10 +1296,34 @@ CUI::EPopupMenuFunctionResult CEditor::PopupEnvPoint(void *pContext, CUIRect Vie pEditor->m_ShowEnvelopePreview = SHOWENV_SELECTED; + std::shared_ptr 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_CurTimeInput; - std::shared_ptr pEnvelope = pEditor->m_Map.m_vpEnvelopes[pEditor->m_SelectedEnvelope]; if(pEditor->m_UpdateEnvPointInfo) { pEditor->m_UpdateEnvPointInfo = false; @@ -1336,14 +1360,14 @@ CUI::EPopupMenuFunctionResult CEditor::PopupEnvPoint(void *pContext, CUIRect Vie View.HSplitTop(RowHeight, &Row, &View); Row.VSplitLeft(60.0f, &Label, &Row); 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"); - View.HMargin(4.0f, &View); + View.HSplitTop(4.0f, nullptr, &View); View.HSplitTop(RowHeight, &Row, &View); Row.VSplitLeft(60.0f, &Label, &Row); 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"); 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 { auto [SelectedIndex, SelectedChannel] = pEditor->m_vSelectedEnvelopePoints.front(); - if(pEnvelope->GetChannels() == 4) CurrentValue = clamp(CurrentValue, 0.0f, 1.0f); 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(); } - View.HMargin(6.0f, &View); + View.HSplitTop(6.0f, nullptr, &View); View.HSplitTop(RowHeight, &Row, &View); static int s_DeleteButtonID = 0; const char *pButtonText = pEditor->IsTangentSelected() ? "Reset" : "Delete";