From 9062e0aae9f2f576b7a237c28028aa6b09feee5e Mon Sep 17 00:00:00 2001 From: Fox Caminiti Date: Wed, 17 Aug 2022 23:41:08 -0400 Subject: undo and pen development --- my_imgui_widgets.cpp | 252 +++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 193 insertions(+), 59 deletions(-) (limited to 'my_imgui_widgets.cpp') diff --git a/my_imgui_widgets.cpp b/my_imgui_widgets.cpp index b924d55..4bf6b5e 100644 --- a/my_imgui_widgets.cpp +++ b/my_imgui_widgets.cpp @@ -76,16 +76,20 @@ ImGui_InteractSliderProperty(project_state *State, memory *Memory, property_chan ImGui::DragScalar(Property->Name, ImGuiDataType_Float, &Property->CurrentValue.f, Property->ScrubVal.f, &Property->MinVal.f, &Property->MaxVal.f, "%f"); if (ImGui::IsItemActivated()) { - Action_Entry_Begin(Memory, action_entry_default, "Tranforms interact"); State->InteractCache[0] = Property->CurrentValue.f; } if (ImGui::IsItemActive()) { State->UpdateFrame = true; } - if (ImGui::IsItemDeactivated()) { - Action_Change_Commit(Memory, &Property->CurrentValue.f, &State->InteractCache[0], - &Property->CurrentValue.f, action_change_r32); - Action_Entry_End(Memory); + if (ImGui::IsItemDeactivatedAfterEdit()) { + if (ImGui::IsKeyPressed(ImGuiKey_Escape)) { + Property->CurrentValue.f = State->InteractCache[0]; + } else { + Action_Entry_Commit(Memory, action_entry_default, "Tranforms interact"); + Action_Change_Commit(Memory, &Property->CurrentValue.f, &State->InteractCache[0], + &Property->CurrentValue.f, action_change_r32); + Action_Entry_End(Memory); + } State->UpdateFrame = true; } } @@ -105,6 +109,7 @@ static void ImGui_DebugUndoTree(project_data *File, memory *Memory) { ImGui::SetNextWindowSize(ImVec2(200, 800)); + ImGui::SetNextWindowPos(ImVec2(2498, 10)); ImGui::Begin("undotree"); for (int i = 0; i < Memory->Action.NumberOfEntries; i++) { action_entry Entry = Memory->Action.Entry[i]; @@ -361,7 +366,7 @@ ImGui_PropertiesPanel(project_data *File, project_state *State, ui *UI, memory * } static void -ImGui_Viewport(project_data File, project_state *State, ui *UI, comp_buffer CompBuffer, +ImGui_Viewport(project_data File, project_state *State, ui *UI, memory *Memory, comp_buffer CompBuffer, ImGuiIO io, GLuint textureID) { bool open = true; @@ -445,13 +450,13 @@ ImGui_Viewport(project_data File, project_state *State, ui *UI, comp_buffer Comp // The handle itself - if (Point0->IsSelected) { + // if (Point0->IsSelected || State->Tool == tool_pen) { col = ImGui::GetColorU32(ImGuiCol_ButtonHovered); 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); - } + // } draw_list->AddNgon(Point0_ScreenPos, 10, col, 8, 5.0f); @@ -478,31 +483,34 @@ ImGui_Viewport(project_data File, project_state *State, ui *UI, comp_buffer Comp ImGui::SetMouseCursor(ImGuiMouseCursor_ResizeEW); } if (ImGui::IsItemActivated() && b == 0) { + if (p == 0 && State->Pen.IsActive) { + // TODO(fox): I think we need some alternate + // Change functions to make these types of + // value sets more easy to read... + bool32 SetFalse = false; + bool32 SetTrue = true; + Action_Entry_Commit(Memory, action_entry_default, "Close mask path"); + Action_Change_Commit(Memory, &State->Pen.IsActive, + &State->Pen.IsActive, &SetFalse, action_change_i32); + Action_Change_Commit(Memory, &Mask->IsClosed, + &Mask->IsClosed, &SetTrue, action_change_i32); + Action_Entry_End(Memory); + // State->Pen.IsActive = false; + // Mask->IsClosed = true; + } Point0->IsSelected = 1; } 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; + Layer_CalcRotatedOffset(Layer, V2(MouseIncrement), V2(1, 1), + &Point0->Pos.x, &Point0->Pos.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; + Layer_CalcRotatedOffset(Layer, V2(MouseIncrement), V2(1, 1), + &Point0->TangentLeft.x, &Point0->TangentLeft.y); } else { - Point0->TangentRight.x += XAxis.x; - Point0->TangentRight.y -= XAxis.y; - Point0->TangentRight.x -= YAxis.x; - Point0->TangentRight.y += YAxis.y; + Layer_CalcRotatedOffset(Layer, V2(MouseIncrement), V2(1, 1), + &Point0->TangentRight.x, &Point0->TangentRight.y); } State->UpdateFrame = true; } @@ -511,7 +519,8 @@ ImGui_Viewport(project_data File, project_state *State, ui *UI, comp_buffer Comp // The bezier path - if (Mask->NumberOfPoints == 1) { + + if (Mask->NumberOfPoints == 1 || (p+1 == Mask->NumberOfPoints && !Mask->IsClosed)) { ImGui::PopID(); continue; } @@ -598,18 +607,19 @@ ImGui_Viewport(project_data File, project_state *State, ui *UI, comp_buffer Comp bool32 IsHovered = ImGui::IsItemHovered(); bool32 IsActive = ImGui::IsItemActive(); bool32 IsActivated = ImGui::IsItemActivated(); + bool32 IsDeactivated = ImGui::IsItemDeactivated(); - /* if (State->MostRecentlySelectedLayer > -1) { project_layer *Layer = File.Layer[State->MostRecentlySelectedLayer]; - if (IsActivated && ImGui::IsMouseDown(ImGuiMouseButton_Left)) { - if (State->Tool == tool_pen && !State->Pen.IsActive) { - State->Pen.IsActive = true; - Layer->NumberOfMasks++; + if (Layer->NumberOfMasks == 0) { + if (IsActivated && ImGui::IsMouseDown(ImGuiMouseButton_Left)) { + if (State->Tool == tool_pen && !State->Pen.IsActive) { + State->Pen.IsActive = true; + Layer->NumberOfMasks++; + } } } - if (State->Pen.IsActive && !ImGui::IsKeyDown(ImGuiKey_Z)) { if (IsActivated) { v2 LayerPos = Layer_ScreenSpaceToLocal(Layer, UI, CompBuffer, ViewportMin, io.MousePos); @@ -622,21 +632,67 @@ ImGui_Viewport(project_data File, project_state *State, ui *UI, comp_buffer Comp v2 LayerUV = CompUVToLayerUV(Layer, &CompBuffer, CompUV); v2 LayerPos = LayerUV * V2(Layer->Source->Info.Width, Layer->Source->Info.Height); v2 OffsetPos = CurrentPoint->Pos - LayerPos; + CurrentPoint->HandleBezier = true; CurrentPoint->TangentRight = -OffsetPos; CurrentPoint->TangentLeft = OffsetPos; } + if (ImGui::IsKeyPressed(ImGuiKey_Escape) && IsActive) { + mask *Mask = &Layer->Mask[Layer->NumberOfMasks-1]; + if (Mask->NumberOfPoints == 1) { + Layer->NumberOfMasks--; + Mask->NumberOfPoints = 0; + } + State->Pen.IsActive = false; + IsDeactivated = false; // just in case escape and mouse release happen simultaneously + } + if (IsDeactivated) { + mask *Mask = &Layer->Mask[Layer->NumberOfMasks-1]; + if (Mask->NumberOfPoints == 1) { + uint16 PreviousNumberOfMasks = Layer->NumberOfMasks - 1; + uint16 PreviousNumberOfPoints = Mask->NumberOfPoints - 1; + Action_Entry_Commit(Memory, action_entry_default, "Create mask"); + Action_Change_Commit(Memory, &Layer->NumberOfMasks, &PreviousNumberOfMasks, + &Layer->NumberOfMasks, action_change_u16); + Action_Change_Commit(Memory, &Mask->NumberOfPoints, &PreviousNumberOfPoints, + &Mask->NumberOfPoints, action_change_u16); + Action_Entry_End(Memory); + } else { + uint16 PreviousNumberOfPoints = Mask->NumberOfPoints - 1; + uint16 Empty = 0; + mask_point *CurrentPoint = &Mask->Point[Mask->NumberOfPoints-1]; + Action_Entry_Commit(Memory, action_entry_default, "Add point"); + Action_Change_Commit(Memory, &Mask->NumberOfPoints, &PreviousNumberOfPoints, + &Mask->NumberOfPoints, action_change_u16); + Action_Change_Commit(Memory, &CurrentPoint->Pos.x, &Empty, + &CurrentPoint->Pos.x, action_change_r32); + Action_Change_Commit(Memory, &CurrentPoint->Pos.y, &Empty, + &CurrentPoint->Pos.y, action_change_r32); + Action_Change_Commit(Memory, &CurrentPoint->TangentLeft.x, &Empty, + &CurrentPoint->TangentLeft.x, action_change_r32); + Action_Change_Commit(Memory, &CurrentPoint->TangentLeft.y, &Empty, + &CurrentPoint->TangentLeft.y, action_change_r32); + Action_Change_Commit(Memory, &CurrentPoint->TangentRight.x, &Empty, + &CurrentPoint->TangentRight.x, action_change_r32); + Action_Change_Commit(Memory, &CurrentPoint->TangentRight.y, &Empty, + &CurrentPoint->TangentRight.y, action_change_r32); + Action_Entry_End(Memory); + } + } if (State->Tool != tool_pen) { State->Pen.IsActive = false; } } } - */ 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; } +#if ARM + if (ImGui::MenuItem("NEON", NULL, false, InstructionMode != instruction_mode_neon)) { InstructionMode = instruction_mode_neon; State->UpdateFrame = true; } +#else if (ImGui::MenuItem("SSE", NULL, false, InstructionMode != instruction_mode_sse)) { InstructionMode = instruction_mode_sse; State->UpdateFrame = true; } if (ImGui::MenuItem("AVX2", NULL, false, InstructionMode != instruction_mode_avx)) { InstructionMode = instruction_mode_avx; State->UpdateFrame = true; } +#endif ImGui::EndPopup(); } @@ -644,8 +700,6 @@ ImGui_Viewport(project_data File, project_state *State, ui *UI, comp_buffer Comp { // Point to zoom in on if Z is held UI->TempZoomRatio = ImGui_ScreenPointToCompUV(ViewportMin, UI->CompPos, UI->CompZoom, io.MousePos); - DebugWatchVar("MouseScreenUV", &UI->TempZoomRatio.x, d_float); - DebugWatchVar("MouseScreenUV", &UI->TempZoomRatio.y, d_float); // Layer selection if (!ImGui::IsKeyDown(ImGuiKey_Z) || !State->Pen.IsActive) { @@ -694,6 +748,14 @@ static bool32 ImGui_SlidingLayer(project_layer *Layer, real32 *DraggingThreshold, real32 Delta, int16 TimelineZoom, int16 Side) { bool32 Result = 0; + if (ImGui::IsItemActivated()) + { + // if (Side & 1) + // Layer->StartFrame += Increment; + // if (Side & 2) + // Layer->EndFrame += Increment; + // if (Side == 3) { + } if (ImGui::IsItemActive() && ImGui::IsMouseDragging(ImGuiMouseButton_Left, -1)) { ImGui::SetMouseCursor(ImGuiMouseCursor_ResizeEW); @@ -701,19 +763,15 @@ ImGui_SlidingLayer(project_layer *Layer, real32 *DraggingThreshold, real32 Delta if (abs(*DraggingThreshold) >= TimelineZoom) { int16 Increment = *DraggingThreshold/TimelineZoom; - // TODO(fox): Properly handle the start and end points wrapping. - - if (!(Increment < 0 && Layer->StartFrame == 0 && Side & 1)) - { - if (Side & 1) - Layer->StartFrame += Increment; - if (Side & 2) - Layer->EndFrame += Increment; - if (Side == 3) { - IncrementKeyframesInLayer(Layer, Increment); - if (Layer->Source->SourceType == source_type_video) { - Layer->BitmapInfo.FrameOffset += Increment; - } + if (Side & 1) + Layer->StartFrame += Increment; + if (Side & 2) + Layer->EndFrame += Increment; + if (Side == 3) { + // TODO(fox): Make frame offset in keyframes local! + IncrementKeyframesInLayer(Layer, Increment); + if (Layer->Source->SourceType == source_type_video) { + Layer->BitmapInfo.FrameOffset += Increment; } } *DraggingThreshold += -1*Increment*TimelineZoom; @@ -1488,8 +1546,10 @@ ImGui_Timeline(project_data *File, project_state *State, memory *Memory, ui *UI, real32 ZoomAmount = io.MouseWheel*16; real32 LocalMousePos = ImGui::GetMousePos().x - TimelineStartingPos.x; real32 ZoomRatio = LocalMousePos / UI->TimelineZoom; - UI->TimelineZoom += ZoomAmount; - UI->ScrollXOffset -= ZoomAmount*ZoomRatio; + if (UI->TimelineZoom + ZoomAmount > 0) { + UI->TimelineZoom += ZoomAmount; + UI->ScrollXOffset -= ZoomAmount*ZoomRatio; + } } else if (io.KeyShift && io.MouseWheel) { UI->ScrollXOffset += io.MouseWheel*16; } else { @@ -1532,6 +1592,14 @@ ImGui_ProcessInputs(project_data *File, project_state *State, comp_buffer *CompB State->UpdateKeyframes = true; } + if (ImGui::IsKeyPressed(ImGuiKey_V)) { + if (State->Tool == tool_pen) { + State->Tool = tool_default; + } else { + State->Tool = tool_pen; + } + } + if (ImGui::IsKeyPressed(ImGuiKey_Space)) { if (io.KeyShift) { State->RerouteEffects = true; @@ -1595,33 +1663,99 @@ ImGui_ProcessInputs(project_data *File, project_state *State, comp_buffer *CompB } #endif - bool32 Ended = ImGui::IsMouseDown(ImGuiMouseButton_Left); if (State->IsInteracting) { ImVec2 MouseIncrement = io.MouseDelta * (ImVec2(CompBuffer->Width, CompBuffer->Height) / UI->CompZoom); + project_layer *Layer = File->Layer[State->MostRecentlySelectedLayer]; switch (State->TransformsHotkeyInteract) { case sliding_position: { - InteractProperty(0, File, State, Ended, MouseIncrement.x, Memory); - InteractProperty(1, File, State, Ended, MouseIncrement.y, Memory); + Layer->x.CurrentValue.f += MouseIncrement.x; + Layer->y.CurrentValue.f += MouseIncrement.y; } break; case sliding_anchorpoint: { - InteractProperty(2, File, State, Ended, MouseIncrement.x, Memory); - InteractProperty(3, File, State, Ended, MouseIncrement.y, Memory); + source *Source = Layer->Source; + Layer->x.CurrentValue.f += MouseIncrement.x; + Layer->y.CurrentValue.f += MouseIncrement.y; + Layer_CalcRotatedOffset(Layer, V2(MouseIncrement), V2(Source->Info.Width, Source->Info.Height), + &Layer->ax.CurrentValue.f, &Layer->ay.CurrentValue.f); } break; case sliding_rotation: { - InteractProperty(4, File, State, Ended, MouseIncrement.x / 10.0, Memory); + Layer->rotation.CurrentValue.f += MouseIncrement.x / 10.0; } break; case sliding_scale: { - InteractProperty(5, File, State, Ended, MouseIncrement.x / 200.0, Memory); + Layer->scale.CurrentValue.f += MouseIncrement.x / 200.0; } break; } + if (ImGui::IsKeyPressed(ImGuiKey_Escape)) { + switch (State->TransformsHotkeyInteract) + { + case sliding_position: + { + Layer->x.CurrentValue.f = State->InteractCache[0]; + Layer->y.CurrentValue.f = State->InteractCache[1]; + } break; + case sliding_anchorpoint: + { + Layer->x.CurrentValue.f = State->InteractCache[0]; + Layer->y.CurrentValue.f = State->InteractCache[1]; + Layer->ax.CurrentValue.f = State->InteractCache[2]; + Layer->ay.CurrentValue.f = State->InteractCache[3]; + } break; + case sliding_rotation: + { + Layer->rotation.CurrentValue.f = State->InteractCache[0]; + } break; + case sliding_scale: + { + Layer->scale.CurrentValue.f = State->InteractCache[0]; + } break; + } + State->IsInteracting = false; + State->UpdateFrame = true; + } + if (ImGui::IsMouseDown(ImGuiMouseButton_Left)) { + Action_Entry_Commit(Memory, action_entry_default, "Tranforms interact"); + switch (State->TransformsHotkeyInteract) + { + case sliding_position: + { + Action_Change_Commit(Memory, &Layer->x.CurrentValue.f, &State->InteractCache[0], + &Layer->x.CurrentValue.f, action_change_r32); + Action_Change_Commit(Memory, &Layer->y.CurrentValue.f, &State->InteractCache[1], + &Layer->y.CurrentValue.f, action_change_r32); + } break; + case sliding_anchorpoint: + { + Action_Change_Commit(Memory, &Layer->x.CurrentValue.f, &State->InteractCache[0], + &Layer->x.CurrentValue.f, action_change_r32); + Action_Change_Commit(Memory, &Layer->y.CurrentValue.f, &State->InteractCache[1], + &Layer->y.CurrentValue.f, action_change_r32); + Action_Change_Commit(Memory, &Layer->ax.CurrentValue.f, &State->InteractCache[2], + &Layer->ax.CurrentValue.f, action_change_r32); + Action_Change_Commit(Memory, &Layer->ay.CurrentValue.f, &State->InteractCache[3], + &Layer->ay.CurrentValue.f, action_change_r32); + } break; + case sliding_rotation: + { + Action_Change_Commit(Memory, &Layer->rotation.CurrentValue.f, &State->InteractCache[0], + &Layer->rotation.CurrentValue.f, action_change_r32); + } break; + case sliding_scale: + { + Action_Change_Commit(Memory, &Layer->scale.CurrentValue.f, &State->InteractCache[0], + &Layer->scale.CurrentValue.f, action_change_r32); + } break; + } + Action_Entry_End(Memory); + State->IsInteracting = false; + } + State->UpdateFrame = true; } - if (!ImGui::IsMouseDown(ImGuiMouseButton_Left)) { UI->DraggingLayerThreshold = 0; UI->DraggingTimelineThreshold = 0; -- cgit v1.2.3