117 lines
4.4 KiB
C++
117 lines
4.4 KiB
C++
|
// https://github.com/CedricGuillemet/ImGuizmo
|
||
|
// v 1.89 WIP
|
||
|
//
|
||
|
// The MIT License(MIT)
|
||
|
//
|
||
|
// Copyright(c) 2021 Cedric Guillemet
|
||
|
//
|
||
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||
|
// of this software and associated documentation files(the "Software"), to deal
|
||
|
// in the Software without restriction, including without limitation the rights
|
||
|
// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
|
||
|
// copies of the Software, and to permit persons to whom the Software is
|
||
|
// furnished to do so, subject to the following conditions :
|
||
|
//
|
||
|
// The above copyright notice and this permission notice shall be included in all
|
||
|
// copies or substantial portions of the Software.
|
||
|
//
|
||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
|
||
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||
|
// SOFTWARE.
|
||
|
//
|
||
|
#include "ImGradient.h"
|
||
|
#include "imgui.h"
|
||
|
#include "imgui_internal.h"
|
||
|
|
||
|
namespace ImGradient
|
||
|
{
|
||
|
#ifndef IMGUI_DEFINE_MATH_OPERATORS
|
||
|
static inline ImVec2 operator*(const ImVec2& lhs, const float rhs) { return ImVec2(lhs.x * rhs, lhs.y * rhs); }
|
||
|
static inline ImVec2 operator/(const ImVec2& lhs, const float rhs) { return ImVec2(lhs.x / rhs, lhs.y / rhs); }
|
||
|
static inline ImVec2 operator+(const ImVec2& lhs, const ImVec2& rhs) { return ImVec2(lhs.x + rhs.x, lhs.y + rhs.y); }
|
||
|
static inline ImVec2 operator-(const ImVec2& lhs, const ImVec2& rhs) { return ImVec2(lhs.x - rhs.x, lhs.y - rhs.y); }
|
||
|
static inline ImVec2 operator*(const ImVec2& lhs, const ImVec2& rhs) { return ImVec2(lhs.x * rhs.x, lhs.y * rhs.y); }
|
||
|
static inline ImVec2 operator/(const ImVec2& lhs, const ImVec2& rhs) { return ImVec2(lhs.x / rhs.x, lhs.y / rhs.y); }
|
||
|
#endif
|
||
|
|
||
|
static int DrawPoint(ImDrawList* draw_list, ImVec4 color, const ImVec2 size, bool editing, ImVec2 pos)
|
||
|
{
|
||
|
ImGuiIO& io = ImGui::GetIO();
|
||
|
|
||
|
ImVec2 p1 = ImLerp(pos, ImVec2(pos + ImVec2(size.x - size.y, 0.f)), color.w) + ImVec2(3, 3);
|
||
|
ImVec2 p2 = ImLerp(pos + ImVec2(size.y, size.y), ImVec2(pos + size), color.w) - ImVec2(3, 3);
|
||
|
ImRect rc(p1, p2);
|
||
|
|
||
|
color.w = 1.f;
|
||
|
draw_list->AddRectFilled(p1, p2, ImColor(color));
|
||
|
if (editing)
|
||
|
draw_list->AddRect(p1, p2, 0xFFFFFFFF, 2.f, 15, 2.5f);
|
||
|
else
|
||
|
draw_list->AddRect(p1, p2, 0x80FFFFFF, 2.f, 15, 1.25f);
|
||
|
|
||
|
if (rc.Contains(io.MousePos))
|
||
|
{
|
||
|
if (io.MouseClicked[0])
|
||
|
return 2;
|
||
|
return 1;
|
||
|
}
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
bool Edit(Delegate& delegate, const ImVec2& size, int& selection)
|
||
|
{
|
||
|
bool ret = false;
|
||
|
ImGuiIO& io = ImGui::GetIO();
|
||
|
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(0, 0));
|
||
|
ImGui::BeginChildFrame(137, size);
|
||
|
|
||
|
ImDrawList* draw_list = ImGui::GetWindowDrawList();
|
||
|
const ImVec2 offset = ImGui::GetCursorScreenPos();
|
||
|
|
||
|
const ImVec4* pts = delegate.GetPoints();
|
||
|
static int currentSelection = -1;
|
||
|
static int movingPt = -1;
|
||
|
if (currentSelection >= int(delegate.GetPointCount()))
|
||
|
currentSelection = -1;
|
||
|
if (movingPt != -1)
|
||
|
{
|
||
|
ImVec4 current = pts[movingPt];
|
||
|
current.w += io.MouseDelta.x / size.x;
|
||
|
current.w = ImClamp(current.w, 0.f, 1.f);
|
||
|
delegate.EditPoint(movingPt, current);
|
||
|
ret = true;
|
||
|
if (!io.MouseDown[0])
|
||
|
movingPt = -1;
|
||
|
}
|
||
|
for (size_t i = 0; i < delegate.GetPointCount(); i++)
|
||
|
{
|
||
|
int ptSel = DrawPoint(draw_list, pts[i], size, i == currentSelection, offset);
|
||
|
if (ptSel == 2)
|
||
|
{
|
||
|
currentSelection = int(i);
|
||
|
ret = true;
|
||
|
}
|
||
|
if (ptSel == 1 && io.MouseDown[0] && movingPt == -1)
|
||
|
{
|
||
|
movingPt = int(i);
|
||
|
}
|
||
|
}
|
||
|
ImRect rc(offset, offset + size);
|
||
|
if (rc.Contains(io.MousePos) && io.MouseDoubleClicked[0])
|
||
|
{
|
||
|
float t = (io.MousePos.x - offset.x) / size.x;
|
||
|
delegate.AddPoint(delegate.GetPoint(t));
|
||
|
ret = true;
|
||
|
}
|
||
|
ImGui::EndChildFrame();
|
||
|
ImGui::PopStyleVar();
|
||
|
|
||
|
selection = currentSelection;
|
||
|
return ret;
|
||
|
}
|
||
|
}
|