diff options
Diffstat (limited to 'src/imgui_ui_viewport.cpp')
-rw-r--r-- | src/imgui_ui_viewport.cpp | 211 |
1 files changed, 163 insertions, 48 deletions
diff --git a/src/imgui_ui_viewport.cpp b/src/imgui_ui_viewport.cpp index 9563d63..fae7bd4 100644 --- a/src/imgui_ui_viewport.cpp +++ b/src/imgui_ui_viewport.cpp @@ -32,7 +32,7 @@ ImGui_Viewport_Toolbar(project_state *State, ImDrawList *draw_list) } static void -ImGui_Viewport_ShapeUI(project_state *State, memory *Memory, ui *UI, shape_layer *Shape, block_composition *MainComp, ImDrawList *draw_list) +ImGui_Viewport_ShapeUI(project_state *State, memory *Memory, ui *UI, ImGuiIO &io, block_layer *Layer, int Width, int Height, shape_layer *Shape, block_composition *MainComp, ImDrawList *draw_list) { if (Shape->Point_Count) { uint32 wcol = IM_COL32(00, 00, 80, 255); @@ -48,33 +48,166 @@ ImGui_Viewport_ShapeUI(project_state *State, memory *Memory, ui *UI, shape_layer ImVec2 ScreenPoint_0[3]; ImVec2 ScreenPoint_1[3]; + if (ImGui::IsKeyPressed(ImGuiKey_Escape)) { + Point_1->IsSelected = false; + } + for (int i = 0; i < 3; i++) { ImVec2 Point = (i == 0) ? ImVec2_(Point_0->Pos[0]) : ImVec2_(Point_0->Pos[0] + Point_0->Pos[i]); + if (Layer != NULL) { + layer_transforms T = Layer_GetTransforms(Layer); + Point = ImVec2_(TransformPoint(T, Width, Height, *(v2 *)&Point)); + } + if (State->Interact_Active == interact_type_keyframe_move && Point_0->IsSelected) { + Point.x += State->Interact_Offset[0]; + Point.y += State->Interact_Offset[1]; + } ImVec2 Point_Ratio = Point / CompDimensions; ScreenPoint_0[i] = UI->CompPos + Point_Ratio * UI->CompZoom; } for (int i = 0; i < 3; i++) { ImVec2 Point = (i == 0) ? ImVec2_(Point_1->Pos[0]) : ImVec2_(Point_1->Pos[0] + Point_1->Pos[i]); + if (Layer != NULL) { + layer_transforms T = Layer_GetTransforms(Layer); + Point = ImVec2_(TransformPoint(T, Width, Height, *(v2 *)&Point)); + } + if (State->Interact_Active == interact_type_keyframe_move && Point_1->IsSelected) { + Point.x += State->Interact_Offset[0]; + Point.y += State->Interact_Offset[1]; + } ImVec2 Point_Ratio = Point / CompDimensions; ScreenPoint_1[i] = UI->CompPos + Point_Ratio * UI->CompZoom; } if (Point_1->Type == interpolation_type_bezier) draw_list->AddLine(ScreenPoint_0[1], ScreenPoint_0[2], wcol, 2.0f); - draw_list->AddNgon(ScreenPoint_0[0], 2, wcol, 8, 2.0f); + ImU32 PointCol = (Point_1->IsSelected) ? ImColor(0.8f, 0.5f, 0.0f, 1.0f) : ImColor(0.1f, 0.1f, 0.1f, 1.0f); ImGui::PushID(i); for (int a = 0; a < 3; a++) { ImGui::PushID(a); - ImGui::SetCursorScreenPos(ScreenPoint_1[a]); - if (ImGui::Button("##bezhandle")) { - if (a == 0 && i == 0) { + real32 FontSize = ImGui::GetFontSize(); + ImGui::SetCursorScreenPos(ScreenPoint_1[a] - ImVec2(FontSize / 2, FontSize / 2)); + ImGui::InvisibleButton("##bezhandle", ImVec2(FontSize, FontSize), ImGuiMouseButton_Left); + bool32 IsHovered = ImGui::IsItemHovered(); + bool32 IsItemActive = ImGui::IsItemActive(); + bool32 IsItemActivated = ImGui::IsItemActivated(); + bool32 IsItemDeactivated = ImGui::IsItemDeactivated(); + bool32 LeftClick = ImGui::IsMouseDown(ImGuiMouseButton_Left); + bool32 RightClick = ImGui::IsMouseDown(ImGuiMouseButton_Right); + if (IsHovered) { + PointCol = ImColor(1.0f, 0.8f, 0.8f, 1.0f); + ImGui::SetMouseCursor(ImGuiMouseCursor_Hand); + } + if (IsItemActivated) { + Point_1->IsSelected = 1; + } + if (IsItemActive) { + if (State->Interact_Active == interact_type_none) { + State->Interact_Offset[2] = io.MousePos.x; + State->Interact_Offset[3] = io.MousePos.y; + State->Interact_Active = interact_type_keyframe_move; + } else { + Assert(State->Interact_Active == interact_type_keyframe_move); + ImVec2 DragDelta = io.MousePos - ImVec2(State->Interact_Offset[2], State->Interact_Offset[3]); + if (io.MouseDelta.x || io.MouseDelta.y) { + State->UpdateFrame = true; + } + if (State->Interact_Active == interact_type_keyframe_move) { + State->Interact_Offset[0] = DragDelta.x * (MainComp->Width / UI->CompZoom.x); + State->Interact_Offset[1] = DragDelta.y * (MainComp->Height / UI->CompZoom.y); + } + } + } + if (IsItemDeactivated) { + if (Layer == NULL && a == 0 && i == 0 && Shape->IsClosed == false) { History_Entry_Commit(Memory, "Close shape"); History_Action_Swap(Memory, F_File, sizeof(Shape->IsClosed), &Shape->IsClosed); Shape->IsClosed = true; History_Entry_End(Memory); + } else if (Layer != NULL) { + layer_transforms T = Layer_GetTransforms(Layer); + History_Entry_Commit(Memory, "Move point"); + void *Data = Memory_PushScratch(Memory, sizeof(nvg_point) * 128); + v2 Min_Old = {}, Max_Old = {}; + NVG_FlattenPath(Memory, Shape, (nvg_point *)Data, State, T, 0, 0, Width, Height, 0, &Min_Old, &Max_Old); + v2 TestMin = Min_Old, TestMax = Max_Old; + for (int p = 0; p < Shape->Point_Count; p++) { + bezier_point *Point = Bezier_LookupAddress(Memory, Shape->Block_Bezier_Index, p, 1); + if (Point->IsSelected) { + v2 *Pos = &Point->Pos[Point->IsSelected-1]; + History_Action_Swap(Memory, F_Bezier, sizeof(*Pos), Pos); + Pos->x += State->Interact_Offset[0]; + Pos->y += State->Interact_Offset[1]; + if (Pos->x < TestMin.x) { + TestMin.x = Pos->x; + } + if (Pos->y < TestMin.y) { + TestMin.y = Pos->y; + } + if (Pos->x > TestMax.x) { + TestMax.x = Pos->x; + } + if (Pos->y > TestMax.y) { + TestMax.y = Pos->y; + } + } + } + v2 MinDiff = TestMin - Min_Old; + v2 MaxDiff = TestMax - Max_Old; + for (int p = 0; p < Shape->Point_Count; p++) { + bezier_point *Point = Bezier_LookupAddress(Memory, Shape->Block_Bezier_Index, p, 1); + v2 *Pos = &Point->Pos[0]; + History_Action_Swap(Memory, F_Bezier, sizeof(*Pos), Pos); + if (MinDiff.x) + Pos->x -= State->Interact_Offset[0]; + if (MinDiff.y) + Pos->y -= State->Interact_Offset[1]; + if (MaxDiff.x) + // Pos->x -= State->Interact_Offset[0]; + if (MaxDiff.y) + // Pos->y += State->Interact_Offset[1]; + int FU = 0; + } + State->Interact_Active = interact_type_none; + v2 Min_New = {}, Max_New = {}; + NVG_FlattenPath(Memory, Shape, (nvg_point *)Data, State, T, Shape->Width, Shape->Height, Width, Height, 1, &Min_New, &Max_New); + + Memory_PopScratch(Memory, sizeof(nvg_point) * 128); + + int Width_Old = Max_Old.x - Min_Old.x; + int Width_New = Max_New.x - Min_New.x; + int Height_New = Max_New.y - Min_New.y; + if (MinDiff.x) { + History_Action_Swap(Memory, F_Layers, sizeof(Layer->ax.CurrentValue), &Layer->ax.CurrentValue); + Layer->ax.CurrentValue -= (real32)(State->Interact_Offset[0]) * (1.0f - Layer->ax.CurrentValue) / Width_New; + } if (MinDiff.y) { + History_Action_Swap(Memory, F_Layers, sizeof(Layer->ay.CurrentValue), &Layer->ay.CurrentValue); + Layer->ay.CurrentValue -= (real32)(State->Interact_Offset[1]) * (1.0f - Layer->ay.CurrentValue) / Height_New; + } if (MaxDiff.x) { + History_Action_Swap(Memory, F_Layers, sizeof(Layer->ax.CurrentValue), &Layer->ax.CurrentValue); + Layer->ax.CurrentValue -= (real32)(State->Interact_Offset[0]) * (Layer->ax.CurrentValue) / Width_New; + } if (MaxDiff.y) { + History_Action_Swap(Memory, F_Layers, sizeof(Layer->ay.CurrentValue), &Layer->ay.CurrentValue); + Layer->ay.CurrentValue -= (real32)(State->Interact_Offset[1]) * (Layer->ay.CurrentValue) / Height_New; + } + /* + if (Min_New.y < Min_Old.y) { + Layer->y.CurrentValue += Min_New.y - Min_Old.y; + } + if (Max_New.x > Max_Old.x) { + Layer->x.CurrentValue += Max_New.x - Max_Old.x; + } + if (Max_New.y > Max_Old.y) { + Layer->y.CurrentValue += Max_New.y - Max_Old.y; + } + */ + Shape->Width = Width_New; + Shape->Height = Height_New; + History_Entry_End(Memory); } } + draw_list->AddNgon(ScreenPoint_1[a], 4, PointCol, 8, 5.0f); ImGui::PopID(); } ImGui::PopID(); @@ -141,7 +274,7 @@ ImGui_Viewport_BrushUI(project_state *State, memory *Memory, ImVec2 ViewportMin, } static void -ImGui_Viewport_TransformUI(project_data *File, project_state *State, memory *Memory, ui *UI, ImDrawList *draw_list, ImGuiIO &io, +ImGui_Viewport_TransformUI(project_data *File, project_state *State, memory *Memory, ui *UI, ImGuiIO &io, ImDrawList *draw_list, interact_transform *Interact, ImVec2 ViewportMin, uint32 CompWidth, uint32 CompHeight, uint16 *SortedKeyframeArray) { v2 InteractMin = Interact->Min + Interact->Position; @@ -419,7 +552,7 @@ ImGui_Viewport_TransformUI(project_data *File, project_state *State, memory *Mem } static void -ImGui_Viewport_SelectedLayerUI(project_state *State, memory *Memory, ui *UI, ImDrawList *draw_list, block_composition *MainComp, uint32 CompIndex, block_layer *ParentLayer[4], uint32 Recursions, +ImGui_Viewport_SelectedLayerUI(project_state *State, memory *Memory, ui *UI, ImGuiIO &io, ImDrawList *draw_list, block_composition *MainComp, uint32 CompIndex, block_layer *ParentLayer[4], uint32 Recursions, sorted_comp_array *SortedCompArray, sorted_layer_array *SortedLayerArray) { sorted_comp_array *SortedCompStart = &SortedCompArray[CompIndex]; @@ -432,7 +565,7 @@ ImGui_Viewport_SelectedLayerUI(project_state *State, memory *Memory, ui *UI, ImD block_layer *Layer = (block_layer *)Memory_Block_AddressAtIndex(Memory, F_Layers, Index_Physical); if (Layer->IsPrecomp) { ParentLayer[Recursions] = Layer; - ImGui_Viewport_SelectedLayerUI(State, Memory, UI, draw_list, MainComp, Layer->Block_Source_Index, ParentLayer, Recursions + 1, SortedCompArray, SortedLayerArray); + ImGui_Viewport_SelectedLayerUI(State, Memory, UI, io, draw_list, MainComp, Layer->Block_Source_Index, ParentLayer, Recursions + 1, SortedCompArray, SortedLayerArray); } if (Layer->IsSelected) { uint32 Width = 0, Height = 0; @@ -443,13 +576,22 @@ ImGui_Viewport_SelectedLayerUI(project_state *State, memory *Memory, ui *UI, ImD Width = Comp->Width; Height = Comp->Height; } else if (Layer->IsShapeLayer) { +#if DEBUG block_bezier *Bezier = (block_bezier *)Memory_Block_AddressAtIndex(Memory, F_Bezier, Layer->Shape.Block_Bezier_Index[0]); Data = Memory_PushScratch(Memory, sizeof(nvg_point) * 128); int L_Width = 0, L_Height = 0; Assert(Layer->Shape.Contiguous); - NumberOfVerts = NVG_FlattenPath(Memory, &Layer->Shape, (nvg_point *)Data, &L_Width, &L_Height); - Width = L_Width; - Height = L_Height; + + v2 Min = {}, Max = {}; + layer_transforms T = Layer_GetTransforms(Layer); + if (State->Interact_Active == interact_type_keyframe_move) { + NVG_FlattenPath(Memory, &Layer->Shape, (nvg_point *)Data, State, T, 0, 0, Width, Height, 0, &Min, &Max); + } + NumberOfVerts = NVG_FlattenPath(Memory, &Layer->Shape, (nvg_point *)Data, + State, T, Layer->Shape.Width, Layer->Shape.Height, Width, Height, 1, &Min, &Max); +#endif + Width = Layer->Shape.Width; + Height = Layer->Shape.Height; } else { block_source *Source = (block_source *)Memory_Block_AddressAtIndex(Memory, F_Sources, Layer->Block_Source_Index); Width = Source->Width; @@ -463,41 +605,12 @@ ImGui_Viewport_SelectedLayerUI(project_state *State, memory *Memory, ui *UI, ImD } if (Layer->IsShapeLayer) { - /* - block_bezier *Bezier = (block_bezier *)Memory_Block_AddressAtIndex(Memory, F_Bezier, Layer->Shape.Block_Bezier_Index[0]); - for (int i = 0; i < Layer->Shape.Point_Count; i++) { - bezier_point Point = Bezier->Point[i]; - v2 Pos = TransformPoint(T, Width, Height, Point.Pos[0]); - v2 CompUV = Pos / V2(MainComp->Width, MainComp->Height); - ImVec2 ScreenPoint = ImVec2(UI->CompPos.x + CompUV.x * UI->CompZoom.x, - UI->CompPos.y + CompUV.y * UI->CompZoom.y); - draw_list->AddNgon(ScreenPoint, 10, IM_COL32(10, 10, 10, 255), 8, 9.0f); - } - for (int i = 1; i < Layer->Shape.Point_Count; i++) { - if (Bezier->Point[i].Type == interpolation_type_bezier) { - v2 L_Pos[4] = { Bezier->Point[i-1].Pos[0], Bezier->Point[i-1].Pos[2], Bezier->Point[i].Pos[1], Bezier->Point[i].Pos[0] }; - L_Pos[1] = L_Pos[1] + L_Pos[0]; - L_Pos[2] = L_Pos[2] + L_Pos[3]; - ImVec2 ScreenPoint[4]; - for (int i = 0; i < 4; i++) { - v2 Pos = TransformPoint(T, Width, Height, L_Pos[i]); - v2 CompUV = Pos / V2(MainComp->Width, MainComp->Height); - ScreenPoint[i] = ImVec2(UI->CompPos.x + CompUV.x * UI->CompZoom.x, - UI->CompPos.y + CompUV.y * UI->CompZoom.y); - } - draw_list->AddNgon(ScreenPoint[0], 10, IM_COL32(10, 10, 10, 255), 8, 2.0f); - draw_list->AddNgon(ScreenPoint[3], 10, IM_COL32(10, 10, 10, 255), 8, 2.0f); - draw_list->AddBezierCubic(ScreenPoint[0],ScreenPoint[1],ScreenPoint[2],ScreenPoint[3], IM_COL32(10, 10, 10, 255), 1.0f, 0); - } else { - } - } - */ - ImGui_Viewport_ShapeUI(State, Memory, UI, &Layer->Shape, MainComp, draw_list); + ImGui_Viewport_ShapeUI(State, Memory, UI, io, Layer, Width, Height, &Layer->Shape, MainComp, draw_list); + // point visualization +#if DEBUG void *Data2 = Memory_PushScratch(Memory, sizeof(real32) * 3 * 256); - uint32 GL_PointCount = NVG_ExpandStroke(Memory, NumberOfVerts, Layer->Shape.Opt.StrokeWidth, Layer->Shape.IsClosed, (nvg_point *)Data, (real32 *)Data2); - - // test code + uint32 GL_PointCount = NVG_ExpandStroke(Memory, NumberOfVerts, Layer->Shape.Opt.StrokeWidth, Layer->Shape.Opt.LineCapType, Layer->Shape.Opt.LineJoinType, Layer->Shape.IsClosed, (nvg_point *)Data, (real32 *)Data2); for (int i = 0; i < NumberOfVerts; i++) { nvg_point Point = *((nvg_point *)Data + i); @@ -516,8 +629,10 @@ ImGui_Viewport_SelectedLayerUI(project_state *State, memory *Memory, ui *UI, ImD UI->CompPos.y + CompUV.y * UI->CompZoom.y); draw_list->AddNgon(ScreenPoint, 2, IM_COL32(80, 80, 10, 255), 8, 2.0f); } + Memory_PopScratch(Memory, sizeof(real32) * 3 * 256); Memory_PopScratch(Memory, sizeof(nvg_point) * 128); +#endif } v2 BoundingPoint[5] = { V2(Width*Layer->ax.CurrentValue, Height*Layer->ay.CurrentValue), V2(0, 0), V2(Width, 0), V2(0, Height), V2(Width, Height) }; @@ -613,15 +728,15 @@ ImGui_Viewport(project_data *File, project_state *State, ui *UI, memory *Memory, if (State->MostRecentlySelectedLayer > -1) { block_layer *ParentLayer[4]; - ImGui_Viewport_SelectedLayerUI(State, Memory, UI, draw_list, MainComp, File->PrincipalCompIndex, ParentLayer, 0, SortedCompArray, SortedLayerArray); + ImGui_Viewport_SelectedLayerUI(State, Memory, UI, io, draw_list, MainComp, File->PrincipalCompIndex, ParentLayer, 0, SortedCompArray, SortedLayerArray); if (State->Interact_Active == interact_type_viewport_transform) { - ImGui_Viewport_TransformUI(File, State, Memory, UI, draw_list, io, (interact_transform *)&State->Interact_Offset[0], ViewportMin, MainComp->Width, MainComp->Height, SortedKeyframeArray); + ImGui_Viewport_TransformUI(File, State, Memory, UI, io, draw_list, (interact_transform *)&State->Interact_Offset[0], ViewportMin, MainComp->Width, MainComp->Height, SortedKeyframeArray); } } shape_layer *Shape = &UI->Shape; - if (State->Tool == tool_pen && State->Interact_Active == interact_type_none && State->MostRecentlySelectedLayer == -1) - ImGui_Viewport_ShapeUI(State, Memory, UI, Shape, MainComp, draw_list); + if (State->Tool == tool_pen && State->MostRecentlySelectedLayer == -1) + ImGui_Viewport_ShapeUI(State, Memory, UI, io, NULL, 0, 0, Shape, MainComp, draw_list); // Interactions for dragging and zooming ImGui::SetCursorScreenPos(ViewportMin); |