summaryrefslogtreecommitdiff
path: root/my_imgui_widgets.cpp
diff options
context:
space:
mode:
authorFox Caminiti <fox@foxcam.net>2022-08-08 13:50:34 -0400
committerFox Caminiti <fox@foxcam.net>2022-08-08 13:50:34 -0400
commit635576972024319c15141645d3304db8cd1d1e19 (patch)
tree425bcebd621449cd89973fbf4803c22a9b83a335 /my_imgui_widgets.cpp
parentbccb1d61907fea45c5e84b29499989f7cee104a5 (diff)
basic bezier path system added
Diffstat (limited to 'my_imgui_widgets.cpp')
-rw-r--r--my_imgui_widgets.cpp293
1 files changed, 260 insertions, 33 deletions
diff --git a/my_imgui_widgets.cpp b/my_imgui_widgets.cpp
index b4114e7..cb981c2 100644
--- a/my_imgui_widgets.cpp
+++ b/my_imgui_widgets.cpp
@@ -192,14 +192,27 @@ ImGui_PropertiesPanel(project_data *File, project_state *State, ui *UI, memory *
}
for (int h = 0; h < Layer->NumberOfEffects; h++) {
effect *Effect = Layer->Effect[h];
- ImGui::Button("V"); ImGui::SameLine();
+ ImGui::PushID(Effect);
+ // this is stupid
+ if (Effect->IsActive)
+ ImGui::PushStyleColor(ImGuiCol_Button, ImGui::GetColorU32(ImGuiCol_ButtonHovered));
+ else
+ ImGui::PushStyleColor(ImGuiCol_Button, ImGui::GetColorU32(ImGuiCol_Button));
+ if (ImGui::Button("V")) {
+ SwitchBool(Effect->IsActive);
+ State->UpdateFrame = true;
+ }
+ ImGui::SameLine();
+ ImGui::PopStyleColor();
+ ImGui::Button("R"); ImGui::SameLine();
ImGui::Text(Effect->Name);
if (Effect->DisplayType == standard) {
for (int i = 0; i < Effect->NumberOfProperties; i++) {
property_channel *Property = &Effect->Property[i];
ImGui::PushID(Property);
if (Property->VarType == type_real)
- ImGui::DragScalar(Property->Name, ImGuiDataType_Float, &Property->CurrentValue.f, 0.005f, &Property->MaxVal.f, &Property->MaxVal.f, "%f");
+ if (ImGui::DragScalar(Property->Name, ImGuiDataType_Float, &Property->CurrentValue.f, 0.005f, &Property->MaxVal.f, &Property->MaxVal.f, "%f"))
+ State->UpdateFrame = true;
if (Property->VarType == type_color)
if (ImGui::ColorEdit4("color 1", &Property->CurrentValue.f, ImGuiColorEditFlags_Float))
State->UpdateFrame = true;
@@ -226,11 +239,76 @@ ImGui_PropertiesPanel(project_data *File, project_state *State, ui *UI, memory *
ImGui::PopID();
}
} else if (Effect->DisplayType == levels) {
- real32 *Min = &Effect->Property[0].CurrentValue.f;
- real32 *Mid = &Effect->Property[1].CurrentValue.f;
- real32 *Max = &Effect->Property[2].CurrentValue.f;
- ImGui::SliderLevels("f", Mid, Min, Max);
+ source *Source = Layer->Source;
+ layer_bitmap_info *BitmapInfo = &Layer->BitmapInfo;
+
+ if (!BitmapInfo->HistogramVals) {
+ uint64 Size = Bitmap_CalcUnpackedBytes(Source->Info.Width, Source->Info.Height, Source->Info.BytesPerPixel);
+ BitmapInfo->HistogramVals = AllocateMemory(Memory, (sizeof(uint32) * 5 * 256), P_MiscCache);
+ Bitmap_CalcHistogram(BitmapInfo->HistogramVals, BitmapInfo->BitmapBuffer, Source->Info.BytesPerPixel, Size);
+ }
+
+ char *LevelsButtons[5] = { "All", "Red", "Green", "Blue", "Alpha" };
+ for (int i = 0; i < 5; i++) {
+ if (ImGui::Button(LevelsButtons[i])) {
+ BitmapInfo->LevelsSelector = i;
+ }
+ if (i != 4) { ImGui::SameLine(); }
+ }
+
+ real32 *Min, *Mid, *Max;
+ if (BitmapInfo->LevelsSelector == 0) {
+ Min = &Effect->Property[0].CurrentValue.f;
+ Mid = &Effect->Property[1].CurrentValue.f;
+ Max = &Effect->Property[2].CurrentValue.f;
+ } else {
+ Min = &Effect->Property[3].CurrentValue.col.E[BitmapInfo->LevelsSelector - 1];
+ Mid = &Effect->Property[4].CurrentValue.col.E[BitmapInfo->LevelsSelector - 1];
+ Max = &Effect->Property[5].CurrentValue.col.E[BitmapInfo->LevelsSelector - 1];
+ }
+
+ if (BitmapInfo->LevelsSelector == 0) {
+ ImGui::PushStyleColor(ImGuiCol_PlotHistogram, ImVec4(0.6f, 0.6f, 0.6f, 1.0f));
+ ImGui::PushStyleColor(ImGuiCol_PlotHistogramHovered, ImVec4(0.6f, 0.6f, 0.6f, 1.0f));
+ } else if (BitmapInfo->LevelsSelector == 1) {
+ ImGui::PushStyleColor(ImGuiCol_PlotHistogram, ImVec4(0.9f, 0.6f, 0.6f, 1.0f));
+ ImGui::PushStyleColor(ImGuiCol_PlotHistogramHovered, ImVec4(0.9f, 0.6f, 0.6f, 1.0f));
+ } else if (BitmapInfo->LevelsSelector == 2) {
+ ImGui::PushStyleColor(ImGuiCol_PlotHistogram, ImVec4(0.6f, 0.9f, 0.6f, 1.0f));
+ ImGui::PushStyleColor(ImGuiCol_PlotHistogramHovered, ImVec4(0.6f, 0.9f, 0.6f, 1.0f));
+ } else if (BitmapInfo->LevelsSelector == 3) {
+ ImGui::PushStyleColor(ImGuiCol_PlotHistogram, ImVec4(0.6f, 0.6f, 0.9f, 1.0f));
+ ImGui::PushStyleColor(ImGuiCol_PlotHistogramHovered, ImVec4(0.6f, 0.6f, 0.9f, 1.0f));
+ } else if (BitmapInfo->LevelsSelector == 4) {
+ ImGui::PushStyleColor(ImGuiCol_PlotHistogram, ImVec4(0.9f, 0.9f, 0.9f, 1.0f));
+ ImGui::PushStyleColor(ImGuiCol_PlotHistogramHovered, ImVec4(0.9f, 0.9f, 0.9f, 1.0f));
+ }
+
+ float *values = (float *)BitmapInfo->HistogramVals + 256*BitmapInfo->LevelsSelector;
+ int values_count = 256;
+ int values_offset = 0;
+ float scale_min = FLT_MIN;
+ float scale_max = FLT_MAX;
+ ImVec2 graph_size = ImVec2(0, 250);
+ int stride = sizeof(float);
+
+ // The default histogram is good enough for what we need.
+ ImGui::PlotHistogram("##histo", values, values_count, values_offset, NULL, scale_min, scale_max, graph_size, stride);
+ // TODO(fox): Figure out the proper way to represent these IDs.
+ if (ImGui::SliderLevels("##one", "##two", "three", Mid, Min, Max))
+ State->UpdateFrame = true;
+
+ ImGui::PopStyleColor();
+ ImGui::PopStyleColor();
+
+ if (State->UpdateFrame) {
+ uint64 Size = Bitmap_CalcUnpackedBytes(Source->Info.Width, Source->Info.Height, Source->Info.BytesPerPixel);
+ Bitmap_CalcHistogram(BitmapInfo->HistogramVals, BitmapInfo->BitmapBuffer, Source->Info.BytesPerPixel, Size);
+ }
+
+ ImGui::Button("K");
}
+ ImGui::PopID();
}
} else {
char buf[256];
@@ -242,14 +320,12 @@ ImGui_PropertiesPanel(project_data *File, project_state *State, ui *UI, memory *
ImGui::End();
}
-static v2
-CalculateAnchorPointUV(project_layer *Layer, comp_buffer *Buffer);
-
static void
ImGui_Viewport(project_data File, project_state *State, ui *UI, comp_buffer CompBuffer,
ImGuiIO io, GLuint textureID)
{
- ImGui::Begin("Viewport");
+ bool open = true;
+ ImGui::Begin("Viewport", &open, ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoScrollWithMouse);
if (ImGui::IsWindowFocused(ImGuiFocusedFlags_ChildWindows))
UI->FocusedWindow = focus_viewport;
@@ -272,6 +348,164 @@ ImGui_Viewport(project_data File, project_state *State, ui *UI, comp_buffer Comp
draw_list->AddRectFilled(ViewportMin, ViewportMax, IM_COL32(50, 50, 50, 255));
draw_list->AddRect(ViewportMin, ViewportMax, IM_COL32(255, 255, 255, 255));
+ // Actual composition texture
+ draw_list->PushClipRect(ViewportMin, ViewportMax, true);
+ draw_list->AddImage((void *)(intptr_t)textureID, ImVec2(UI->CompPos.x, UI->CompPos.y),
+ ImVec2(UI->CompPos.x + UI->CompZoom.x, UI->CompPos.y + UI->CompZoom.y));
+ draw_list->PopClipRect();
+
+ // UI+interaction for layer
+ if (State->MostRecentlySelectedLayer > -1) {
+ project_layer *Layer = File.Layer[State->MostRecentlySelectedLayer];
+
+ // Anchor point
+ ImVec2 AUV = ImVec2(Layer->x.CurrentValue.f / CompBuffer.Width, Layer->y.CurrentValue.f / CompBuffer.Height);
+ ImVec2 ScreenAP = ImVec2(UI->CompPos.x + AUV.x * UI->CompZoom.x, UI->CompPos.y + AUV.y * UI->CompZoom.y);
+ draw_list->AddNgon(ScreenAP, 20, ImGui::GetColorU32(ImGuiCol_ScrollbarGrab), 8, 10.0f);
+
+ // Mask points
+ if (Layer->NumberOfMasks) {
+ for (int i = 0; i < Layer->NumberOfMasks; i++) {
+ mask *Mask = &Layer->Mask[i];
+ ImGui::PushID(i);
+ source *Source = Layer->Source;
+
+ for (int p = 0; p < Mask->NumberOfPoints; p++) {
+
+ mask_point *Point0 = &Mask->Point[p];
+ mask_point *Point1 = &Mask->Point[p+1];
+ if (p+1 == Mask->NumberOfPoints)
+ Point1 = &Mask->Point[0];
+
+ ImVec2 Point0_Pos = ImVec2(Point0->Pos.x, Point0->Pos.y);
+ ImVec2 Point0_Pos_Left = Point0_Pos + ImVec2(Point0->TangentLeft.x, Point0->TangentLeft.y);
+ ImVec2 Point0_Pos_Right = Point0_Pos + ImVec2(Point0->TangentRight.x, Point0->TangentRight.y);
+
+ ImVec2 Point1_Pos = ImVec2(Point1->Pos.x, Point1->Pos.y);
+ ImVec2 Point1_Pos_Left = Point1_Pos + ImVec2(Point1->TangentLeft.x, Point1->TangentLeft.y);
+ ImVec2 Point1_Pos_Right = Point1_Pos + ImVec2(Point1->TangentRight.x, Point1->TangentRight.y);
+
+ ImVec2 Point0_ScreenPos = Layer_LocalToScreenSpace(Layer, UI, CompBuffer, V2(Point0_Pos));
+ ImVec2 Point0_ScreenPos_Left = Layer_LocalToScreenSpace(Layer, UI, CompBuffer, V2(Point0_Pos_Left));
+ ImVec2 Point0_ScreenPos_Right = Layer_LocalToScreenSpace(Layer, UI, CompBuffer, V2(Point0_Pos_Right));
+
+ ImVec2 Point1_ScreenPos = Layer_LocalToScreenSpace(Layer, UI, CompBuffer, V2(Point1_Pos));
+ ImVec2 Point1_ScreenPos_Left = Layer_LocalToScreenSpace(Layer, UI, CompBuffer, V2(Point1_Pos_Left));
+ ImVec2 Point1_ScreenPos_Right = Layer_LocalToScreenSpace(Layer, UI, CompBuffer, V2(Point1_Pos_Right));
+
+ ImGui::PushID(p);
+
+ ImU32 col = ImGui::GetColorU32(ImGuiCol_ScrollbarGrab);
+
+ draw_list->AddNgon(Point0_ScreenPos, 10, col, 8, 5.0f);
+ draw_list->AddNgon(Point0_ScreenPos_Left, 10, col, 8, 5.0f);
+ draw_list->AddNgon(Point0_ScreenPos_Right, 10, col, 8, 5.0f);
+
+ draw_list->AddLine(Point0_ScreenPos, Point0_ScreenPos_Left, col, 2.0f);
+ draw_list->AddLine(Point0_ScreenPos, Point0_ScreenPos_Right, col, 2.0f);
+
+ ImU32 col2 = ImGui::GetColorU32(ImGuiCol_Button);
+
+
+ real32 PointSize = 40;
+
+
+ // Ratio of the point along the curve. See internal for more info.
+ float ratio;
+
+ if (ImGui::BezierInteractive(Point0_ScreenPos, Point0_ScreenPos_Right,
+ Point1_ScreenPos_Left, Point1_ScreenPos, ratio))
+ {
+ // Using a button like this may be kinda janky, but it gives us access
+ // to all of ButtonBehavior and the ID system without having to rewrite it.
+ ImGui::SetCursorScreenPos(io.MousePos - ImVec2(5,5));
+ ImGui::Button("maskbezier", ImVec2(10, 10));
+
+ if(ImGui::IsItemHovered()) {
+ ImGui::SetMouseCursor(ImGuiMouseCursor_ResizeAll);
+ draw_list->AddNgon(io.MousePos, 2, col, 8, 5.0f);
+ ImVec2 RatioLeft = ImGui::RatioToPoint(Point0_ScreenPos, Point0_ScreenPos_Right, ratio);
+ ImVec2 RatioTop = ImGui::RatioToPoint(Point0_ScreenPos_Right, Point1_ScreenPos_Left, ratio);
+ ImVec2 RatioRight = ImGui::RatioToPoint(Point1_ScreenPos_Left, Point1_ScreenPos, ratio);
+ ImVec2 TangentLeft = ImGui::RatioToPoint(RatioLeft, RatioTop, ratio);
+ ImVec2 TangentRight = ImGui::RatioToPoint(RatioTop, RatioRight, ratio);
+ draw_list->AddLine(RatioLeft, RatioTop, col, 2.0f);
+ draw_list->AddLine(RatioRight, RatioTop, col, 2.0f);
+ draw_list->AddLine(TangentLeft, TangentRight, col, 2.0f);
+ }
+ if(ImGui::IsItemActivated() && io.KeyCtrl) {
+ ImVec2 Ratio0 = ImGui::RatioToPoint(Point0_Pos, Point0_Pos_Right, ratio);
+ ImVec2 RatioTop = ImGui::RatioToPoint(Point0_Pos_Right, Point1_Pos_Left, ratio);
+ ImVec2 Ratio1 = ImGui::RatioToPoint(Point1_Pos_Left, Point1_Pos, ratio);
+ ImVec2 TangentLeft = ImGui::RatioToPoint(Ratio0, RatioTop, ratio);
+ ImVec2 TangentRight = ImGui::RatioToPoint(RatioTop, Ratio1, ratio);
+ ImVec2 Point = ImGui::RatioToPoint(TangentLeft, TangentRight, ratio);
+ Mask_AddPoint(Mask, Point, Point - TangentLeft, Point - TangentRight,
+ Point0_Pos - Ratio0, Point1_Pos - Ratio1, p);
+ }
+ }
+
+ DebugWatchVar("ratio", &ratio, d_float);
+
+ // if (ImGui::TestLine(PointScreenPos[0], PointScreenPos[1])) {
+ // }
+
+ // loops over point and handles
+ for (int b = 0; b < 3; b++)
+ {
+ ImGui::PushID(b);
+ if (b == 0) {
+ ImGui::SetCursorScreenPos(Point0_ScreenPos - ImVec2(PointSize/2, PointSize/2));
+ } else if (b == 1) {
+ ImGui::SetCursorScreenPos(Point0_ScreenPos_Left - ImVec2(PointSize/2, PointSize/2));
+ } else {
+ ImGui::SetCursorScreenPos(Point0_ScreenPos_Right - ImVec2(PointSize/2, PointSize/2));
+ }
+
+ ImGui::Button("##point", ImVec2(PointSize, PointSize));
+
+ if (ImGui::IsItemHovered()) {
+ ImGui::SetMouseCursor(ImGuiMouseCursor_ResizeEW);
+ }
+ if (ImGui::IsItemActive()) {
+ // TODO(fox): Combine this with the anchor point code.
+ ImVec2 MouseIncrement = io.MouseDelta * (ImVec2(CompBuffer.Width, CompBuffer.Height) / UI->CompZoom);
+ real32 Rad = (Layer->rotation.CurrentValue.f * (PI / 180));
+ real32 s = Layer->scale.CurrentValue.f;
+ v2 XAxis = V2(cos(Rad), sin(Rad)) * (MouseIncrement.x / s);
+ v2 YAxis = V2(sin(Rad), -cos(Rad)) * (MouseIncrement.y / -s);
+
+ if (b == 0) {
+ Point0->Pos.x += XAxis.x;
+ Point0->Pos.y -= XAxis.y;
+ Point0->Pos.x -= YAxis.x;
+ Point0->Pos.y += YAxis.y;
+ } else if (b == 1) {
+ Point0->TangentLeft.x += XAxis.x;
+ Point0->TangentLeft.y -= XAxis.y;
+ Point0->TangentLeft.x -= YAxis.x;
+ Point0->TangentLeft.y += YAxis.y;
+ } else {
+ Point0->TangentRight.x += XAxis.x;
+ Point0->TangentRight.y -= XAxis.y;
+ Point0->TangentRight.x -= YAxis.x;
+ Point0->TangentRight.y += YAxis.y;
+ }
+ }
+ ImGui::PopID();
+ }
+
+
+ ImGui::PopID();
+ }
+ ImGui::PopID();
+ }
+ }
+ }
+
+ // Interactions for dragging and zooming
+ ImGui::SetCursorScreenPos(ViewportMin);
+
ImGui::InvisibleButton("canvas", ViewportScale, ImGuiButtonFlags_MouseButtonLeft | ImGuiButtonFlags_MouseButtonRight);
bool32 IsHovered = ImGui::IsItemHovered();
bool32 IsActive = ImGui::IsItemActive();
@@ -300,10 +534,7 @@ ImGui_Viewport(project_data File, project_state *State, ui *UI, comp_buffer Comp
UI->CompPos.x += io.MouseDelta.x;
UI->CompPos.y += io.MouseDelta.y;
}
- // if (IsActive && ImGui::IsMouseDown(ImGuiMouseButton_Right))
- // {
- // Debug.ToggleRenders = true;
- // }
+
ImGui::OpenPopupOnItemClick("context", ImGuiPopupFlags_MouseButtonMiddle);
if (ImGui::BeginPopup("context")) {
if (ImGui::MenuItem("Scalar", NULL, false, InstructionMode != instruction_mode_scalar)) { InstructionMode = instruction_mode_scalar; State->UpdateFrame = true; }
@@ -311,6 +542,7 @@ ImGui_Viewport(project_data File, project_state *State, ui *UI, comp_buffer Comp
if (ImGui::MenuItem("AVX2", NULL, false, InstructionMode != instruction_mode_avx)) { InstructionMode = instruction_mode_avx; State->UpdateFrame = true; }
ImGui::EndPopup();
}
+
if (IsActive && ImGui::IsMouseDragging(ImGuiMouseButton_Left, -1.0f) && ImGui::IsKeyDown(ImGuiKey_Z))
{
real32 Distance = io.MouseDelta.x + io.MouseDelta.y;
@@ -320,19 +552,6 @@ ImGui_Viewport(project_data File, project_state *State, ui *UI, comp_buffer Comp
UI->CompPos.y -= Distance*UI->TempZoomRatio.y;
}
- draw_list->PushClipRect(ViewportMin, ViewportMax, true);
- draw_list->AddImage((void *)(intptr_t)textureID, ImVec2(UI->CompPos.x, UI->CompPos.y),
- ImVec2(UI->CompPos.x + UI->CompZoom.x, UI->CompPos.y + UI->CompZoom.y));
-
- if (State->MostRecentlySelectedLayer > -1) {
- project_layer *Layer = File.Layer[State->MostRecentlySelectedLayer];
- ImVec2 AUV = ImVec2(Layer->x.CurrentValue.f / CompBuffer.Width, Layer->y.CurrentValue.f / CompBuffer.Height);
- ImVec2 ScreenAP = ImVec2(UI->CompPos.x + AUV.x * UI->CompZoom.x, UI->CompPos.y + AUV.y * UI->CompZoom.y);
- draw_list->AddNgon(ScreenAP, 20, ImGui::GetColorU32(ImGuiCol_ScrollbarGrab), 8, 10.0f);
- }
-
- draw_list->PopClipRect();
-
ImGui::Text("%.1f", 100.0f * (UI->CompZoom.x / CompBuffer.Width));
if (State->MsgTime > 0) {
ImGui::SameLine();
@@ -402,14 +621,21 @@ ImGui_File(project_data *File, project_state *State, memory *Memory, ui *UI, ImG
}
ImGui::Text("Sources:");
for (int i = 0; i < File->NumberOfSources; i++) {
- ImGui::Text(File->Source[i].Path);
+ bool32 Test = false;
+ if (File->SourceSelected == i)
+ Test = true;
+ ImGui::Selectable(File->Source[i].Path, Test);
+ if (ImGui::IsItemClicked())
+ File->SourceSelected = i;
+ if (ImGui::IsItemClicked(ImGuiMouseButton_Right))
+ File->SourceSelected = i;
ImGui::OpenPopupOnItemClick("sourcecontext", ImGuiPopupFlags_MouseButtonRight);
- if (ImGui::BeginPopup("sourcecontext")) {
- if (ImGui::MenuItem("Create layer from source")) {
- Layer_CreateFromSource(File, State, Memory, &File->Source[i]);
- }
- ImGui::EndPopup();
+ }
+ if (ImGui::BeginPopup("sourcecontext")) {
+ if (ImGui::MenuItem("Create layer from source")) {
+ Layer_CreateFromSource(File, State, Memory, &File->Source[File->SourceSelected]);
}
+ ImGui::EndPopup();
}
// static char Input[1024];
// ImGui::InputText("##sourceinput", Input, STRING_SIZE);
@@ -427,6 +653,7 @@ ImGui_File(project_data *File, project_state *State, memory *Memory, ui *UI, ImG
ImGui::Text("%s: %u", Debug.String[i], Debug.Val[i].u);
}
}
+ Debug = {};
#endif
ImGui::End();
}