From e17d0597c2f150ceaba0c4d4be78838af4162a9d Mon Sep 17 00:00:00 2001 From: msiglreith Date: Thu, 26 Nov 2015 13:30:36 +0100 Subject: [PATCH] add hsv color picker for editor --- src/base/color.h | 56 ++++++++++++++++++++ src/game/editor/editor.cpp | 27 +++++++++- src/game/editor/editor.h | 4 +- src/game/editor/popups.cpp | 105 +++++++++++++++++++++++++++++++++++++ 4 files changed, 189 insertions(+), 3 deletions(-) diff --git a/src/base/color.h b/src/base/color.h index 22792bf8b..bd7bcddd1 100644 --- a/src/base/color.h +++ b/src/base/color.h @@ -56,4 +56,60 @@ inline vec4 HexToRgba(int hex) return c; } +/* + Function: HsvToRgb + Converts Hsv to Rgb +*/ +inline vec3 HsvToRgb(vec3 hsv) +{ + int h = int(hsv.x * 6.0f); + float f = hsv.x * 6.0f - h; + float p = hsv.z * (1.0f - hsv.y); + float q = hsv.z * (1.0f - hsv.y * f); + float t = hsv.z * (1.0f - hsv.y * (1.0f - f)); + + vec3 rgb = vec3(0.0f, 0.0f, 0.0f); + + switch(h % 6) + { + case 0: + rgb.r = hsv.z; + rgb.g = t; + rgb.b = p; + break; + + case 1: + rgb.r = q; + rgb.g = hsv.z; + rgb.b = p; + break; + + case 2: + rgb.r = p; + rgb.g = hsv.z; + rgb.b = t; + break; + + case 3: + rgb.r = p; + rgb.g = q; + rgb.b = hsv.z; + break; + + case 4: + rgb.r = t; + rgb.g = p; + rgb.b = hsv.z; + break; + + case 5: + rgb.r = hsv.z; + rgb.g = p; + rgb.b = q; + break; + } + + return rgb; +} + #endif diff --git a/src/game/editor/editor.cpp b/src/game/editor/editor.cpp index 6a24329bd..444ba66cf 100644 --- a/src/game/editor/editor.cpp +++ b/src/game/editor/editor.cpp @@ -2401,6 +2401,14 @@ int CEditor::DoProperties(CUIRect *pToolBox, CProperty *pProps, int *pIDs, int * static const char *s_paTexts[4] = {"R", "G", "B", "A"}; static int s_aShift[] = {24, 16, 8, 0}; int NewColor = 0; + + // extra space + CUIRect ColorBox, ColorSlots; + + pToolBox->HSplitTop(3.0f*13.0f, &Slot, pToolBox); + Slot.VSplitMid(&ColorBox, &ColorSlots); + ColorBox.HMargin(1.0f, &ColorBox); + ColorBox.VMargin(6.0f, &ColorBox); for(int c = 0; c < 4; c++) { @@ -2409,11 +2417,26 @@ int CEditor::DoProperties(CUIRect *pToolBox, CProperty *pProps, int *pIDs, int * if(c != 3) { - pToolBox->HSplitTop(13.0f, &Slot, pToolBox); - Slot.VSplitMid(0, &Shifter); + ColorSlots.HSplitTop(13.0f, &Shifter, &ColorSlots); Shifter.HMargin(1.0f, &Shifter); } } + + // color picker + vec4 Color = vec4( + ((pProps[i].m_Value >> s_aShift[0])&0xff)/255.0f, + ((pProps[i].m_Value >> s_aShift[1])&0xff)/255.0f, + ((pProps[i].m_Value >> s_aShift[2])&0xff)/255.0f, + 1.0f); + + static int s_ColorPicker, s_ColorPickerID; + + RenderTools()->DrawUIRect(&ColorBox, Color, 0, 0.0f); + if(DoButton_Editor_Common(&s_ColorPicker, 0x0, 0, &ColorBox, 0, 0x0)) + { + // TODO: BeaR: + UiInvokePopupMenu(&s_ColorPickerID, 0, UI()->MouseX(), UI()->MouseY(), 180, 150, PopupColorPicker); + } if(NewColor != pProps[i].m_Value) { diff --git a/src/game/editor/editor.h b/src/game/editor/editor.h index bd2bfc30e..9b4bdf8fe 100644 --- a/src/game/editor/editor.h +++ b/src/game/editor/editor.h @@ -587,6 +587,7 @@ public: m_SelectedEnvelopePoint = -1; m_SelectedColor = vec4(0,0,0,0); + m_SelectedPickerColor = vec3(1,0,0); ms_pUiGotContext = 0; } @@ -729,6 +730,7 @@ public: int m_SelectedImage; vec4 m_SelectedColor; + vec3 m_SelectedPickerColor; IGraphics::CTextureHandle m_CheckerTexture; IGraphics::CTextureHandle m_BackgroundTexture; @@ -782,9 +784,9 @@ public: static int PopupImage(CEditor *pEditor, CUIRect View); static int PopupMenuFile(CEditor *pEditor, CUIRect View); static int PopupSelectConfigAutoMap(CEditor *pEditor, CUIRect View); - static int PopupSelectDoodadRuleSet(CEditor *pEditor, CUIRect View); static int PopupDoodadAutoMap(CEditor *pEditor, CUIRect View); + static int PopupColorPicker(CEditor *pEditor, CUIRect View); static void CallbackOpenMap(const char *pFileName, int StorageType, void *pUser); static void CallbackAppendMap(const char *pFileName, int StorageType, void *pUser); diff --git a/src/game/editor/popups.cpp b/src/game/editor/popups.cpp index 081581975..bb9d3d541 100644 --- a/src/game/editor/popups.cpp +++ b/src/game/editor/popups.cpp @@ -1,6 +1,7 @@ /* (c) Magnus Auvinen. See licence.txt in the root of the distribution for more information. */ /* If you are missing that file, acquire a complete release at teeworlds.com. */ +#include #include #include @@ -1030,3 +1031,107 @@ bool CEditor::PopupAutoMapProceedOrder() return false; } + +int CEditor::PopupColorPicker(CEditor *pEditor, CUIRect View) +{ + CUIRect SVPicker, HuePicker; + View.VSplitRight(20.0f, &SVPicker, &HuePicker); + HuePicker.VSplitLeft(4.0f, 0x0, &HuePicker); + + pEditor->Graphics()->TextureClear(); + pEditor->Graphics()->QuadsBegin(); + + // base: white - hue + vec3 hsv = pEditor->m_SelectedPickerColor; + IGraphics::CColorVertex ColorArray[4]; + + vec3 c = HsvToRgb(vec3(hsv.x, 0.0f, 1.0f)); + ColorArray[0] = IGraphics::CColorVertex(0, c.r, c.g, c.b, 1.0f); + c = HsvToRgb(vec3(hsv.x, 1.0f, 1.0f)); + ColorArray[1] = IGraphics::CColorVertex(1, c.r, c.g, c.b, 1.0f); + c = HsvToRgb(vec3(hsv.x, 1.0f, 1.0f)); + ColorArray[2] = IGraphics::CColorVertex(2, c.r, c.g, c.b, 1.0f); + c = HsvToRgb(vec3(hsv.x, 0.0f, 1.0f)); + ColorArray[3] = IGraphics::CColorVertex(3, c.r, c.g, c.b, 1.0f); + + pEditor->Graphics()->SetColorVertex(ColorArray, 4); + + IGraphics::CQuadItem QuadItem(SVPicker.x, SVPicker.y, SVPicker.w, SVPicker.h); + pEditor->Graphics()->QuadsDrawTL(&QuadItem, 1); + + // base: transparent - black + ColorArray[0] = IGraphics::CColorVertex(0, 0.0f, 0.0f, 0.0f, 0.0f); + ColorArray[1] = IGraphics::CColorVertex(1, 0.0f, 0.0f, 0.0f, 0.0f); + ColorArray[2] = IGraphics::CColorVertex(2, 0.0f, 0.0f, 0.0f, 1.0f); + ColorArray[3] = IGraphics::CColorVertex(3, 0.0f, 0.0f, 0.0f, 1.0f); + + pEditor->Graphics()->SetColorVertex(ColorArray, 4); + + pEditor->Graphics()->QuadsDrawTL(&QuadItem, 1); + + pEditor->Graphics()->QuadsEnd(); + + // marker + vec2 Marker = vec2(hsv.y*pEditor->UI()->Scale(), (1.0f - hsv.z)*pEditor->UI()->Scale()) * 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; + static int ms_SVPicker = 0; + if(pEditor->UI()->DoPickerLogic(&ms_SVPicker, &SVPicker, &X, &Y)) + { + hsv.y = X/SVPicker.w; + hsv.z = 1.0f - Y/SVPicker.h; + } + + // hue slider + 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 + }; + + pEditor->Graphics()->QuadsBegin(); + vec4 ColorTop, ColorBottom; + float Offset = HuePicker.h/6.0f; + for(int j = 0; j < 6; j++) + { + ColorTop = vec4(s_aColorIndices[j][0], s_aColorIndices[j][1], s_aColorIndices[j][2], 1.0f); + ColorBottom = vec4(s_aColorIndices[j+1][0], s_aColorIndices[j+1][1], s_aColorIndices[j+1][2], 1.0f); + + ColorArray[0] = IGraphics::CColorVertex(0, ColorTop.r, ColorTop.g, ColorTop.b, ColorTop.a); + ColorArray[1] = IGraphics::CColorVertex(1, ColorTop.r, ColorTop.g, ColorTop.b, ColorTop.a); + ColorArray[2] = IGraphics::CColorVertex(2, ColorBottom.r, ColorBottom.g, ColorBottom.b, ColorBottom.a); + ColorArray[3] = IGraphics::CColorVertex(3, ColorBottom.r, ColorBottom.g, ColorBottom.b, ColorBottom.a); + pEditor->Graphics()->SetColorVertex(ColorArray, 4); + IGraphics::CQuadItem QuadItem(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 * pEditor->UI()->Scale(), HuePicker.w, pEditor->UI()->PixelSize()); + pEditor->Graphics()->QuadsDrawTL(&QuadItemMarker, 1); + + pEditor->Graphics()->QuadsEnd(); + + static int ms_HuePicker = 0; + if(pEditor->UI()->DoPickerLogic(&ms_HuePicker, &HuePicker, &X, &Y)) + { + hsv.x = 1.0f - Y/HuePicker.h; + } + + pEditor->m_SelectedPickerColor = hsv; + + return 0; +}