168 lines
6.5 KiB
C++
168 lines
6.5 KiB
C++
|
//
|
||
|
// Created by Matty on 2022-01-28.
|
||
|
//
|
||
|
|
||
|
#define IMGUI_DEFINE_MATH_OPERATORS
|
||
|
|
||
|
#include "imgui_neo_internal.h"
|
||
|
#include "imgui_internal.h"
|
||
|
#include <cstdint>
|
||
|
|
||
|
namespace ImGui {
|
||
|
void RenderNeoSequencerBackground(const ImVec4 &color, const ImVec2 & cursor, const ImVec2 &size, ImDrawList * drawList, float sequencerRounding) {
|
||
|
if(!drawList) drawList = ImGui::GetWindowDrawList();
|
||
|
|
||
|
const ImRect area = {cursor, cursor + size};
|
||
|
|
||
|
drawList->AddRectFilled(area.Min, area.Max, ColorConvertFloat4ToU32(color), sequencerRounding);
|
||
|
}
|
||
|
|
||
|
void RenderNeoSequencerTopBarBackground(const ImVec4 &color, const ImVec2 &cursor, const ImVec2 &size,
|
||
|
ImDrawList *drawList, float sequencerRounding) {
|
||
|
if(!drawList) drawList = ImGui::GetWindowDrawList();
|
||
|
|
||
|
const ImRect barArea = {cursor, cursor + size};
|
||
|
|
||
|
drawList->AddRectFilled(barArea.Min, barArea.Max, ColorConvertFloat4ToU32(color), sequencerRounding);
|
||
|
}
|
||
|
|
||
|
void
|
||
|
RenderNeoSequencerTopBarOverlay(float zoom, float valuesWidth,uint32_t startFrame, uint32_t endFrame, uint32_t offsetFrame, const ImVec2 &cursor, const ImVec2 &size,
|
||
|
ImDrawList *drawList, bool drawFrameLines,
|
||
|
bool drawFrameText, float maxPixelsPerTick) {
|
||
|
if(!drawList) drawList = ImGui::GetWindowDrawList();
|
||
|
|
||
|
const auto & style = GetStyle();
|
||
|
|
||
|
const ImRect barArea = {cursor + ImVec2{style.FramePadding.x + valuesWidth,style.FramePadding.y}, cursor + size };
|
||
|
|
||
|
const uint32_t viewEnd = endFrame + offsetFrame;
|
||
|
const uint32_t viewStart = startFrame + offsetFrame;
|
||
|
|
||
|
if(drawFrameLines) {
|
||
|
const auto count = (int32_t)((float)((viewEnd + 1) - viewStart) / zoom);
|
||
|
|
||
|
int32_t counter = 0;
|
||
|
uint32_t primaryFrames = pow(10, counter++);
|
||
|
uint32_t secondaryFrames = pow(10, counter);
|
||
|
|
||
|
float perFrameWidth = GetPerFrameWidth(size.x, valuesWidth, endFrame, startFrame, zoom);
|
||
|
|
||
|
if(perFrameWidth <= 0.0f) return;
|
||
|
|
||
|
while (perFrameWidth < maxPixelsPerTick)
|
||
|
{
|
||
|
primaryFrames = pow(10, counter++);
|
||
|
secondaryFrames = pow(10, counter);
|
||
|
|
||
|
perFrameWidth *= (float)primaryFrames;
|
||
|
}
|
||
|
|
||
|
if(primaryFrames == 0 || secondaryFrames == 0) {
|
||
|
primaryFrames = 1;
|
||
|
secondaryFrames = 10;
|
||
|
}
|
||
|
|
||
|
for(int32_t i = 0; i < count; i++) {
|
||
|
|
||
|
const auto primaryFrame = ((viewStart + i) % primaryFrames == 0);
|
||
|
const auto secondaryFrame = ((viewStart + i) % secondaryFrames == 0);
|
||
|
|
||
|
if(!primaryFrame && !secondaryFrame) continue;
|
||
|
|
||
|
const auto lineHeight = secondaryFrame ? barArea.GetSize().y : barArea.GetSize().y / 2.0f;
|
||
|
|
||
|
const ImVec2 p1 = {barArea.Min.x + (float)i * (perFrameWidth / (float)primaryFrames), barArea.Max.y};
|
||
|
const ImVec2 p2 = {barArea.Min.x + (float)i * (perFrameWidth / (float)primaryFrames), barArea.Max.y - lineHeight};
|
||
|
|
||
|
drawList->AddLine(p1,p2, IM_COL32_WHITE, 1.0f);
|
||
|
|
||
|
if(drawFrameText && secondaryFrame) {
|
||
|
char text[10];
|
||
|
const auto printRes = snprintf(text, sizeof(text), "%i", viewStart + i);
|
||
|
if(printRes > 0) {
|
||
|
drawList->AddText(NULL, 0, {p1.x + 2.0f, barArea.Min.y }, IM_COL32_WHITE,text);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void RenderNeoTimelineLabel(const char * label,const ImVec2 & cursor,const ImVec2 & size, const ImVec4& color,bool isGroup, bool isOpen, ImDrawList *drawList)
|
||
|
{
|
||
|
const auto& imStyle = GetStyle();
|
||
|
|
||
|
if(!drawList) drawList = ImGui::GetWindowDrawList();
|
||
|
|
||
|
auto c = cursor;
|
||
|
|
||
|
if(isGroup) {
|
||
|
RenderArrow(drawList,c,IM_COL32_WHITE,isOpen ? ImGuiDir_Down : ImGuiDir_Right);
|
||
|
c.x += size.y + imStyle.ItemSpacing.x;
|
||
|
}
|
||
|
|
||
|
drawList->AddText(c,ColorConvertFloat4ToU32(color),label, FindRenderedTextEnd(label));
|
||
|
}
|
||
|
|
||
|
void RenderNeoTimelinesBorder(const ImVec4 &color, const ImVec2 &cursor, const ImVec2 &size, ImDrawList *drawList,
|
||
|
float rounding, float borderSize)
|
||
|
{
|
||
|
if(!drawList) drawList = ImGui::GetWindowDrawList();
|
||
|
|
||
|
drawList->AddRect(cursor,cursor + size,ColorConvertFloat4ToU32(color),rounding, 0, borderSize);
|
||
|
}
|
||
|
|
||
|
void RenderNeoTimelane(bool selected,const ImVec2 & cursor, const ImVec2& size, const ImVec4& highlightColor, ImDrawList *drawList) {
|
||
|
if(!drawList) drawList = ImGui::GetWindowDrawList();
|
||
|
|
||
|
if(selected) {
|
||
|
const ImRect area = {cursor, cursor + size};
|
||
|
drawList->AddRectFilled(area.Min, area.Max, ColorConvertFloat4ToU32(highlightColor));
|
||
|
}
|
||
|
}
|
||
|
|
||
|
float GetPerFrameWidth(float totalSizeX, float valuesWidth, uint32_t endFrame, uint32_t startFrame, float zoom) {
|
||
|
const auto& imStyle = GetStyle();
|
||
|
|
||
|
const auto size = totalSizeX - valuesWidth - imStyle.FramePadding.x;
|
||
|
|
||
|
auto count = (endFrame + 1) - startFrame;
|
||
|
|
||
|
return ((size / (float)count) * zoom);
|
||
|
}
|
||
|
|
||
|
struct Vec2Pair {
|
||
|
ImVec2 a;
|
||
|
ImVec2 b;
|
||
|
};
|
||
|
|
||
|
static Vec2Pair getCurrentFrameLine(const ImRect & pointerBB, float timelineHeight) {
|
||
|
const auto center = ImVec2{pointerBB.Min.x, pointerBB.Max.y} + ImVec2{pointerBB.GetSize().x / 2.0f, 0};
|
||
|
|
||
|
return Vec2Pair{ center, center + ImVec2{0, timelineHeight} };
|
||
|
}
|
||
|
|
||
|
void RenderNeoSequencerCurrentFrame(const ImVec4 &color, const ImVec4 &topColor, const ImRect &pointerBB,
|
||
|
float timelineHeight, float lineWidth, ImDrawList *drawList) {
|
||
|
if(!drawList) drawList = ImGui::GetWindowDrawList();
|
||
|
|
||
|
const auto pair = getCurrentFrameLine(pointerBB, timelineHeight);
|
||
|
|
||
|
drawList->AddLine(pair.a, pair.b, ColorConvertFloat4ToU32(color), lineWidth);
|
||
|
|
||
|
drawList->PopClipRect();
|
||
|
|
||
|
{ //Top pointer has custom shape, we have to create it
|
||
|
const auto size = pointerBB.GetSize();
|
||
|
ImVec2 pts[5];
|
||
|
pts[0] = pointerBB.Min;
|
||
|
pts[1] = pointerBB.Min + ImVec2{size.x, 0};
|
||
|
pts[2] = pointerBB.Min + ImVec2{size.x, size.y * 0.85f};
|
||
|
pts[3] = pointerBB.Min + ImVec2{size.x / 2, size.y};
|
||
|
pts[4] = pointerBB.Min + ImVec2{0, size.y * 0.85f};
|
||
|
|
||
|
drawList->AddConvexPolyFilled(pts, sizeof(pts) / sizeof(*pts), ColorConvertFloat4ToU32(topColor));
|
||
|
}
|
||
|
}
|
||
|
}
|