From 7435ce70153572e9f2dec316406e6ebb53334b51 Mon Sep 17 00:00:00 2001 From: Fox Caminiti Date: Wed, 26 Oct 2022 22:20:09 -0400 Subject: graph work --- my_imgui_widgets.cpp | 203 +++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 188 insertions(+), 15 deletions(-) (limited to 'my_imgui_widgets.cpp') diff --git a/my_imgui_widgets.cpp b/my_imgui_widgets.cpp index 545af4e..c5a4049 100644 --- a/my_imgui_widgets.cpp +++ b/my_imgui_widgets.cpp @@ -4,16 +4,51 @@ #include "imgui_helper_widgets.cpp" static void -ImGui_DebugMemoryViewer(project_state *State) +ImGui_DebugMemoryViewer(memory *Memory, project_state *State) { ImGui::Begin("Memory viewer"); + + ImVec2 ViewportMin = ImGui::GetCursorScreenPos(); + ImVec2 ViewportScale = ImGui::GetContentRegionAvail(); + ImVec2 ViewportMax = ImVec2(ViewportMin.x + ViewportScale.x, ViewportMin.y + ViewportScale.y); + + // ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0, 0)); + // ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(0, 0)); + cache_entry *EntryArray = State->Render.Entry; char *Type[4] = { "unassigned", "comp", "source", "layer" }; int c = 0; - while (EntryArray[c].CycleTime != 0) { - ImGui::Text("Type - %s, Start - %i, Info - %i", Type[EntryArray[c].Type], EntryArray[c].Block_StartIndex, EntryArray[c].TypeInfo); + uint32 Blocks_Total = Memory->Slot[B_CachedBitmaps].Size / BitmapBlockSize; + uint32 PerRow = sqrt(Blocks_Total); + real32 BlockSize = ViewportScale.x / PerRow; + while (EntryArray[c+1].CycleTime != 0) { + ImGui::PushID(c); + cache_entry Entry = EntryArray[c]; + cache_entry NextEntry = EntryArray[c+1]; + uint32 BlockSpan = NextEntry.Block_StartIndex - Entry.Block_StartIndex; + ImVec2 ButtonPos = ViewportMin + ImVec2((Entry.Block_StartIndex % PerRow) * BlockSize, BlockSize * (Entry.Block_StartIndex / PerRow)); + ImVec2 ButtonSize = ImVec2(BlockSpan * BlockSize, BlockSize); + ImGui::SetCursorScreenPos(ButtonPos); + char size[20]; + sprintf(size, "%lu##uimemoryblock", EntryArray[c].CycleTime); + if (ButtonPos.x + ButtonSize.x > ViewportMax.x) { + real32 ButtonSizeSplit = ViewportMax.x - ButtonPos.x; + ImGui::Button(size, ImVec2(ButtonSizeSplit, ButtonSize.y)); + ImVec2 ButtonPos2 = ImVec2(ViewportMin.x, ButtonPos.y + BlockSize); + ImGui::SetCursorScreenPos(ButtonPos2); + ImGui::Button("##uimemoryblockpad", ImVec2(ButtonSize.x - ButtonSizeSplit, ButtonSize.y)); + } else { + ImGui::Button(size, ButtonSize); + } + if (ImGui::IsItemHovered()) { + ImGui::BeginTooltip(); + ImGui::Text("Type - %s, Start - %i, Info - %i, %i", Type[EntryArray[c].Type], EntryArray[c].Block_StartIndex, EntryArray[c].TypeInfo, EntryArray[c].TypeInfo_Sub); + ImGui::EndTooltip(); + } c++; + ImGui::PopID(); } + // ImGui::PopStyleVar(2); ImGui::End(); } @@ -212,7 +247,7 @@ ImGui_GraphInfo(project_data *File, project_state *State, memory *Memory, ui *UI ImGui::PushID(a); for (int h = 0; h < AmountOf(Layer->Property); h++) { property_channel *Property = &Layer->Property[h]; - if (Property->Keyframe_Count) { + if (Property->Block_Bezier_Count) { ImGui::PushID(Property); ImGui::Text(Property->Name); ImGui::PopID(); @@ -254,39 +289,117 @@ ImGui_Timeline_DrawGraph(project_data *File, project_state *State, memory *Memor ImU32 col = IM_COL32(255, 255, 255, 255); + if (State->Interact_Active == interact_type_keyframe_move) { + ImVec2 DragDelta = io.MousePos - ImVec2(State->Interact_Offset[2], State->Interact_Offset[3]); + State->Interact_Offset[0] = (DragDelta.x / TimelineSizeWithBorder.x * UI->TimelinePercentZoomed.x) / Increment.x; + State->Interact_Offset[1] = -1 * (DragDelta.y / TimelineSizeWithBorder.y * UI->TimelinePercentZoomed.y) * ((GraphInfo.MaxVal - GraphInfo.MinVal)); + } else if (State->Interact_Active == interact_type_keyframe_scale) { + ImVec2 DragDelta = io.MousePos - ImVec2(State->Interact_Offset[2], State->Interact_Offset[3]); + State->Interact_Offset[0] = (DragDelta.x / TimelineSizeWithBorder.x * UI->TimelinePercentZoomed.x) / Increment.x; + // TODO(fox): Pass min/max to sort to calculate this better! + } + + if ((io.MouseDelta.x || io.MouseDelta.y) && + (State->Interact_Active == interact_type_keyframe_move || + State->Interact_Active == interact_type_keyframe_rotate || + State->Interact_Active == interact_type_keyframe_scale)) + { + } + for (int h = 0; h < AmountOf(Layer->Property); h++) { property_channel *Property = &Layer->Property[h]; ImGui::PushID(Property); - if (Property->Keyframe_Count) { + if (Property->Block_Bezier_Count) { property_info PropertyInfo = Property_GetInfo(Memory, Property); real32 Y_Increment = 1 / (GraphInfo.MaxVal - GraphInfo.MinVal); bezier_point *PointAddress[2] = {}; ImVec2 Keyframe_ScreenPos[6] = {}; - for (int k = 0; k < Property->Keyframe_Count; k++) { + int k = 0; + for (;;) { int Idx = (k % 2); int NewIdx = Idx * 3; int OldIdx = (NewIdx == 3) ? 0 : 3; PointAddress[Idx] = Bezier_Lookup(Memory, Property, k); bezier_point *Point = PointAddress[Idx]; - ImVec2 Keyframe_LocalPos[3] = { V2(Point->Pos[0]), V2(Point->Pos[0] + Point->Pos[1]), V2(Point->Pos[0] + Point->Pos[2]) }; + if (!Point->Occupied) + break; + + v2 Keyframe_LocalPos_[3] = { Point->Pos[0], Point->Pos[1], Point->Pos[2] }; + + if (Point->IsSelected) { + if (State->Interact_Active == interact_type_keyframe_rotate) { + ImVec2 Keyframe_LocalPos_Ratio = (V2(Keyframe_LocalPos_[0]) - ImVec2(0, GraphInfo.MinVal)) * ImVec2(Increment.x, Y_Increment); + ImVec2 Keyframe_ScreenPos = Layer_ScreenPos_Min + ((ImVec2(1, -1) * Keyframe_LocalPos_Ratio + ImVec2(0, 0.5)) * TimelineZoomSize) + ImVec2(0, Layer_ScreenSize.y/2); + real32 Slope_Old = (Keyframe_ScreenPos.y - State->Interact_Offset[3]) / (Keyframe_ScreenPos.x - State->Interact_Offset[2]); + real32 Slope_New = (Keyframe_ScreenPos.y - io.MousePos.y) / (Keyframe_ScreenPos.x - io.MousePos.x); + State->Interact_Offset[0] = atan((Slope_Old - Slope_New) / (1 + Slope_Old * Slope_New)); + DebugWatchVar("Rotation: ", &State->Interact_Offset[0], d_float); + } + Keyframe_Interact_Evaluate(Memory, State, Point->IsSelected, Point->Pos, Keyframe_LocalPos_); + } + ImVec2 Keyframe_LocalPos[3] = { V2(Keyframe_LocalPos_[0]), V2(Keyframe_LocalPos_[0] + Keyframe_LocalPos_[1]), V2(Keyframe_LocalPos_[0] + Keyframe_LocalPos_[2]) }; + ImVec2 Keyframe_LocalPos_Ratio[3]; for (int b = 0; b < 3; b++) { Keyframe_LocalPos_Ratio[b] = (Keyframe_LocalPos[b] - ImVec2(0, GraphInfo.MinVal)) * ImVec2(Increment.x, Y_Increment); Keyframe_ScreenPos[NewIdx + b] = Layer_ScreenPos_Min + ((ImVec2(1, -1) * Keyframe_LocalPos_Ratio[b] + ImVec2(0, 0.5)) * TimelineZoomSize) + ImVec2(0, Layer_ScreenSize.y/2); } + if (UI->BoxSelect) { + real32 Y_Top = (io.MouseClickedPos[0].y < io.MousePos.y) ? io.MouseClickedPos[0].y : io.MousePos.y; + real32 Y_Bottom = (io.MouseClickedPos[0].y > io.MousePos.y) ? io.MouseClickedPos[0].y : io.MousePos.y; + real32 X_Left = (io.MouseClickedPos[0].x < io.MousePos.x) ? io.MouseClickedPos[0].x : io.MousePos.x; + real32 X_Right = (io.MouseClickedPos[0].x > io.MousePos.x) ? io.MouseClickedPos[0].x : io.MousePos.x; + + if (Keyframe_ScreenPos[NewIdx].y >= Y_Top && Keyframe_ScreenPos[NewIdx].y <= Y_Bottom && + Keyframe_ScreenPos[NewIdx].x >= X_Left && Keyframe_ScreenPos[NewIdx].x <= X_Right) + { + if (!Point->IsSelected) { + Point->IsSelected = 1; + } + } else if (!io.KeyShift) { + Point->IsSelected = 0; + } + } + UI->Test.SetCurrentChannel(draw_list, 1); - ImU32 PointCol = (Point->IsSelected) ? IM_COL32(255, 128, 0, 255) : IM_COL32(25 ,25, 25, 255); - draw_list->AddCircleFilled(Keyframe_ScreenPos[NewIdx], 4, PointCol); + ImVec2 ButtonSize(16, 16); - if (Point->IsSelected) { - draw_list->AddCircleFilled(Keyframe_ScreenPos[NewIdx+1], 4, PointCol); - draw_list->AddCircleFilled(Keyframe_ScreenPos[NewIdx+2], 4, PointCol); - draw_list->AddLine(Keyframe_ScreenPos[NewIdx], Keyframe_ScreenPos[NewIdx+1], PointCol, 1.0f); - draw_list->AddLine(Keyframe_ScreenPos[NewIdx], Keyframe_ScreenPos[NewIdx+2], PointCol, 1.0f); + ImGui::PushID(k); + int Max = (Point->IsSelected) ? 2 : 0; + for (int b = Max; b >= 0; b--) { + ImU32 PointCol = ((Point->IsSelected - 1) == b) ? ImColor(0.8f, 0.5f, 0.0f, 1.0f) : ImColor(0.1f, 0.1f, 0.1f, 1.0f); + ImU32 LineCol = ((Point->IsSelected - 1) == b) ? ImColor(0.8f, 0.5f, 0.5f, 1.0f) : ImColor(0.4f, 0.4f, 0.4f, 1.0f); + ImGui::PushID(b); + ImGui::SetCursorScreenPos(Keyframe_ScreenPos[NewIdx + b] - (ButtonSize * 0.5)); + ImGui::InvisibleButton("##keyframemover", ButtonSize, 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); + + if (IsItemActivated) { + Point->IsSelected = b+1; + } + + if (b != 0 && Point->IsSelected) + draw_list->AddLine(Keyframe_ScreenPos[NewIdx], Keyframe_ScreenPos[NewIdx + b], LineCol, 2.0f); + + if (b == 0) + draw_list->AddCircleFilled(Keyframe_ScreenPos[NewIdx + b], 4, PointCol); + else + draw_list->AddCircle(Keyframe_ScreenPos[NewIdx + b], 6, PointCol, 0, 2); + + ImGui::PopID(); } + ImGui::PopID(); UI->Test.SetCurrentChannel(draw_list, 0); @@ -298,6 +411,7 @@ ImGui_Timeline_DrawGraph(project_data *File, project_state *State, memory *Memor draw_list->AddLine(Keyframe_ScreenPos[0], Keyframe_ScreenPos[3], col, 1.0f); } } + k++; } } ImGui::PopID(); @@ -648,10 +762,14 @@ ImGui_Timeline(project_data *File, project_state *State, memory *Memory, ui *UI, SortedCompArray, SortedLayerArray); if (UI->TimelineMode == timeline_mode_graph) { + // uint64 Keyframe_SortSize = (sizeof(sorted_comp_info) * File->Comp_Count) + (sizeof(sorted_layer) * File->Layer_Count); + // void *SortedArray = Memory_PushScratch(Memory, Keyframe_SortSize); + // Arbitrary_Zero((uint8 *)SortedArray, SortSize); graph_info GraphInfo = Graph_GetInfo(File, Memory); ImGui_Timeline_DrawGraph(File, State, Memory, UI, io, draw_list, GraphInfo, Increment, TimelineAbsolutePos, TimelineMoveSize, TimelineZoomSize, TimelineSize, TimelineSizeWithBorder, LayerIncrement); + // Memory_PopScratch(Memory, Keyframe_SortSize); } Memory_PopScratch(Memory, SortSize); @@ -815,6 +933,35 @@ ImGui_Timeline(project_data *File, project_state *State, memory *Memory, ui *UI, if (IsItemActivated) { if (!io.KeyShift && UI->TimelineMode == timeline_mode_default) Layer_DeselectAll(Memory, File->Layer_Count); + if (State->Interact_Active == interact_type_keyframe_move || + State->Interact_Active == interact_type_keyframe_rotate || + State->Interact_Active == interact_type_keyframe_scale) { + for (int a = 0; a < File->Layer_Count; a++) { + block_layer *Layer = (block_layer *)Memory_Block_AddressAtIndex(Memory, F_Layers, a); + if (!Layer->IsSelected) + continue; + for (int h = 0; h < AmountOf(Layer->Property); h++) { + property_channel *Property = &Layer->Property[h]; + if (Property->Block_Bezier_Count) { + int k = 0; + for (;;) { + bezier_point *Point = Bezier_Lookup(Memory, Property, k); + if (!Point->Occupied) + break; + if (Point->IsSelected) { + Keyframe_Interact_Evaluate(Memory, State, Point->IsSelected, Point->Pos, Point->Pos); + } + k++; + } + } + } + } + State->Interact_Offset[0] = 0; + State->Interact_Offset[1] = 0; + State->Interact_Offset[2] = 0; + State->Interact_Offset[3] = 0; + State->Interact_Active = interact_type_none; + } UI->BoxSelect = true; } if (IsItemActive) { @@ -846,7 +993,7 @@ ImGui_Timeline(project_data *File, project_state *State, memory *Memory, ui *UI, } static void -ImGui_ProcessInputs(project_data *File, project_state *State, memory *Memory, ImGuiIO io) +ImGui_ProcessInputs(project_data *File, project_state *State, ui *UI, memory *Memory, ImGuiIO io) { if (ImGui::IsKeyPressed(ImGuiKey_Q)) { State->IsRunning = false; @@ -854,6 +1001,32 @@ ImGui_ProcessInputs(project_data *File, project_state *State, memory *Memory, Im if (ImGui::IsKeyPressed(ImGuiKey_A)) { State->UpdateFrame = true; } + if (UI->TimelineMode == timeline_mode_graph) { + if (ImGui::IsKeyPressed(ImGuiKey_G)) { + State->Interact_Offset[2] = io.MousePos.x; + State->Interact_Offset[3] = io.MousePos.y; + State->Interact_Active = interact_type_keyframe_move; + } else if (ImGui::IsKeyPressed(ImGuiKey_R)) { + State->Interact_Offset[2] = io.MousePos.x; + State->Interact_Offset[3] = io.MousePos.y; + State->Interact_Active = interact_type_keyframe_rotate; + } else if (ImGui::IsKeyPressed(ImGuiKey_S)) { + State->Interact_Offset[2] = io.MousePos.x; + State->Interact_Offset[3] = io.MousePos.y; + State->Interact_Active = interact_type_keyframe_scale; + } + } + if (ImGui::IsKeyPressed(ImGuiKey_Escape)) { + if (State->Interact_Active == interact_type_keyframe_move || + State->Interact_Active == interact_type_keyframe_rotate || + State->Interact_Active == interact_type_keyframe_scale) { + State->Interact_Offset[0] = 0; + State->Interact_Offset[1] = 0; + State->Interact_Offset[2] = 0; + State->Interact_Offset[3] = 0; + State->Interact_Active = interact_type_none; + } + } if (ImGui::IsKeyPressed(ImGuiKey_Space)) { State->IsPlaying ^= 1; } -- cgit v1.2.3