summaryrefslogtreecommitdiff
path: root/src/imgui_ui_viewport.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/imgui_ui_viewport.cpp')
-rw-r--r--src/imgui_ui_viewport.cpp556
1 files changed, 513 insertions, 43 deletions
diff --git a/src/imgui_ui_viewport.cpp b/src/imgui_ui_viewport.cpp
index f3e124e..2012354 100644
--- a/src/imgui_ui_viewport.cpp
+++ b/src/imgui_ui_viewport.cpp
@@ -1,3 +1,4 @@
+#include "imgui.h"
#if SPECIAL
#include "main.h"
#endif
@@ -221,6 +222,456 @@ ImGui_Viewport_BrushUI(project_state *State, memory *Memory, ImVec2 ViewportMin,
}
}
+#if 0
+static void
+ImGui_Viewport_TransformUI2(project_data *File, project_state *State, memory *Memory, ui *UI, ImGuiIO &io, ImDrawList *draw_list,
+ v2 Min, v2 Max, ImVec2 ViewportMin, uint32 CompWidth, uint32 CompHeight, uint16 *SortedKeyframeArray)
+{
+ interact_transform *Interact = (interact_transform *)&State->Interact_Offset[0];
+
+ v2 InteractMin = Min;
+ v2 InteractMax = Max;
+ real32 Rad = 0;
+ real32 Scale = 1;
+
+
+ if (State->Interact_Active == interact_type_viewport_transform_gizmo) {
+ InteractMin = Interact->Min + Interact->Position;
+ InteractMax = Interact->Max + Interact->Position;
+ Rad = Interact->Radians;
+ Scale = Interact->Scale;
+ }
+
+ v2 BoxLength = InteractMax - InteractMin;
+ v2 Center = InteractMax - (BoxLength/2);
+
+ real32 Point0X = Center.x - InteractMin.x;
+ real32 Point0Y = Center.y - InteractMin.y;
+
+ v2 XAxis = (Point0X * Scale)*V2(cos(Rad), sin(Rad));
+ v2 YAxis = (Point0Y * -Scale)*V2(sin(Rad), -cos(Rad));
+
+ // Points are clockwise starting from the top left.
+ real32 X0 = -XAxis.x - YAxis.x + Center.x;
+ real32 Y0 = -XAxis.y - YAxis.y + Center.y;
+ real32 X1 = X0 + XAxis.x*2;
+ real32 Y1 = Y0 + XAxis.y*2;
+ real32 X2 = X1 + YAxis.x*2;
+ real32 Y2 = Y1 + YAxis.y*2;
+ real32 X3 = X2 - XAxis.x*2;
+ real32 Y3 = Y2 - XAxis.y*2;
+
+ // Midway points.
+ real32 Mid_X0 = X0 + XAxis.x;
+ real32 Mid_Y0 = Y0 + XAxis.y;
+ real32 Mid_X1 = X1 + YAxis.x;
+ real32 Mid_Y1 = Y1 + YAxis.y;
+ real32 Mid_X2 = X2 - XAxis.x;
+ real32 Mid_Y2 = Y2 - XAxis.y;
+ real32 Mid_X3 = X3 - YAxis.x;
+ real32 Mid_Y3 = Y3 - YAxis.y;
+
+ ImVec2 CompScale = UI->CompZoom / ImVec2(CompWidth, CompHeight);
+
+ ImVec2 P[4];
+ P[0] = ImVec2(X0, Y0)*CompScale + UI->CompPos;
+ P[1] = ImVec2(X1, Y1)*CompScale + UI->CompPos;
+ P[2] = ImVec2(X2, Y2)*CompScale + UI->CompPos;
+ P[3] = ImVec2(X3, Y3)*CompScale + UI->CompPos;
+
+ ImVec2 Mid_P[4];
+ Mid_P[0] = ImVec2(Mid_X0, Mid_Y0)*CompScale + UI->CompPos;
+ Mid_P[1] = ImVec2(Mid_X1, Mid_Y1)*CompScale + UI->CompPos;
+ Mid_P[2] = ImVec2(Mid_X2, Mid_Y2)*CompScale + UI->CompPos;
+ Mid_P[3] = ImVec2(Mid_X3, Mid_Y3)*CompScale + UI->CompPos;
+
+ if (State->Interact_Active == interact_type_viewport_transform_gizmo) {
+ ImU32 wcol = ImGui::GetColorU32(ImGuiCol_Text);
+ draw_list->AddLine(P[0], P[1], wcol, 2.0f);
+ draw_list->AddLine(P[1], P[2], wcol, 2.0f);
+ draw_list->AddLine(P[2], P[3], wcol, 2.0f);
+ draw_list->AddLine(P[3], P[0], wcol, 2.0f);
+ }
+
+ v2 XAxis2 = (BoxLength*CompScale.x)*V2(cos(Rad), sin(Rad));
+ v2 YAxis2 = (BoxLength*CompScale.y)*V2(sin(Rad), -cos(Rad));
+
+ v2 XAxisPerp = (1.0f / LengthSq(XAxis))*XAxis;
+ v2 YAxisPerp = (1.0f / LengthSq(YAxis))*YAxis;
+
+ // real32 LocalX = ((io.MousePos.x - UI->CompPos.x) - Center.x) ;
+ // real32 LocalY = ((io.MousePos.y - UI->CompPos.y) - Center.y) ;
+ layer_transforms BoxTransforms = { Center.x, Center.y, 0.5, 0.5, (real32)(Rad / (PI / 180)), Scale };
+ v2 LayerPoint = Transform_ScreenSpaceToLocal(BoxTransforms, CompWidth, CompHeight, BoxLength.x, BoxLength.y, UI->CompPos, UI->CompZoom, ViewportMin, io.MousePos);
+
+ real32 U = LayerPoint.x / BoxLength.x;
+ real32 V = LayerPoint.y / BoxLength.y;
+
+ bool32 OtherActions = ImGui::IsKeyDown(ImGuiKey_Z);
+ real32 FontSize = ImGui::GetFontSize() * 3;
+ real32 Delta = io.MouseDelta.x + io.MouseDelta.y;
+
+ ImVec2 Screen_Center = IV2(Center)*CompScale + UI->CompPos;
+
+ char *Buttons[] = { "##position", "##rotation", "##scale" };
+ for (int i = 0; i < 3; i++) {
+ ImGui::SetCursorScreenPos(Screen_Center + ImVec2(i*FontSize, i*FontSize));
+ ImGui::Button(Buttons[i], ImVec2(FontSize, FontSize));
+ bool32 IsActivated = ImGui::IsItemActivated();
+ bool32 IsActive = ImGui::IsItemActive();
+ bool32 IsDeactivated = ImGui::IsItemDeactivated();
+ if (IsActivated) {
+ State->Interact_Active = interact_type_viewport_transform_gizmo;
+ *Interact = {};
+ Interact->Min = Min;
+ Interact->Max = Max;
+ }
+ if (IsActive && Delta != 0.0f) {
+ v2 Increase = V2(io.MousePos - io.MouseClickedPos[0]);
+ if (i == 0) {
+ Interact->Position = Increase;
+ } else if (i == 1) {
+ real32 LocalX = (io.MousePos.x - UI->CompPos.x)/CompScale.x - InteractMin.x - (BoxLength.x/2);
+ real32 LocalY = (io.MousePos.y - UI->CompPos.y)/CompScale.y - InteractMin.y - (BoxLength.y/2);
+ v2 SlopeDot = V2(BoxLength.x, BoxLength.y);
+
+ real32 Slope_Mouse = LocalY/LocalX;
+
+ real32 Slope_Corner = BoxLength.y / BoxLength.x;
+ real32 Slope_Flipped = -BoxLength.x / BoxLength.y;
+ real32 Dot = LocalX * SlopeDot.x + LocalY * SlopeDot.y;
+
+ Interact->Radians = atan((Slope_Mouse - Slope_Corner) / (1 + Slope_Mouse * Slope_Corner));
+ real32 ExtraRadians2 = atan((Slope_Mouse - Slope_Flipped) / (1 + Slope_Mouse * Slope_Flipped));
+
+ if (Dot < 0) {
+ if (Interact->Radians < 0) {
+ Interact->Radians = (90 * (PI / 180)) + ExtraRadians2;
+ } else {
+ Interact->Radians = (-90 * (PI / 180)) + ExtraRadians2;
+ }
+ }
+ } else if (i == 2) {
+ real32 StartX = (io.MouseClickedPos[0].x - UI->CompPos.x)/CompScale.x - InteractMin.x - (BoxLength.x/2);
+ real32 StartY = (io.MouseClickedPos[0].y - UI->CompPos.y)/CompScale.y - InteractMin.y - (BoxLength.y/2);
+ real32 LocalX = (io.MousePos.x - UI->CompPos.x)/CompScale.x - InteractMin.x - (BoxLength.x/2);
+ real32 LocalY = (io.MousePos.y - UI->CompPos.y)/CompScale.y - InteractMin.y - (BoxLength.y/2);
+ real32 Normalized = LocalX / StartX;
+ if (Normalized < 0.0f)
+ Normalized = 0.0f;
+ Interact->Scale = Normalized;
+ // printf("Local X: %.2f\n", Normalized);
+ } else {
+ Assert(0);
+ }
+ }
+ if (IsDeactivated) {
+ Assert(State->Interact_Active == interact_type_viewport_transform_gizmo);
+ int h = 0, c = 0, i = 0;
+ History_Entry_Commit(Memory, "Transform layers");
+ while (Block_Loop(Memory, F_Layers, File->Layer_Count, &h, &c, &i)) {
+ block_layer *Layer = (block_layer *)Memory_Block_AddressAtIndex(Memory, F_Layers, i);
+ if (Layer->IsSelected == 1) {
+ History_Action_Swap(Memory, F_Layers, sizeof(Layer->x.CurrentValue), &Layer->x.CurrentValue);
+ History_Action_Swap(Memory, F_Layers, sizeof(Layer->y.CurrentValue), &Layer->y.CurrentValue);
+ History_Action_Swap(Memory, F_Layers, sizeof(Layer->scale.CurrentValue), &Layer->scale.CurrentValue);
+ History_Action_Swap(Memory, F_Layers, sizeof(Layer->rotation.CurrentValue), &Layer->rotation.CurrentValue);
+ Transform_ApplyInteractive(*(interact_transform *)&State->Interact_Offset[0], &Layer->x.CurrentValue, &Layer->y.CurrentValue, &Layer->rotation.CurrentValue, &Layer->scale.CurrentValue);
+ }
+ }
+ History_Entry_End(Memory);
+ State->Interact_Active = interact_type_none;
+ *Interact = {};
+ State->UpdateFrame = true;
+ }
+ }
+}
+#endif
+
+static void
+ImGui_Viewport_TransformUI2(project_data *File, project_state *State, memory *Memory, ui *UI, ImGuiIO &io, ImDrawList *draw_list,
+ v2 Min, v2 Max, ImVec2 ViewportMin, uint32 CompWidth, uint32 CompHeight, uint16 *SortedKeyframeArray)
+{
+ interact_transform *Interact = (interact_transform *)&State->Interact_Offset[0];
+
+ v2 InteractMin = Min;
+ v2 InteractMax = Max;
+ real32 Rad = 0;
+ real32 Scale = 1;
+
+ if (Interact->Min.x != 0.0f) {
+ InteractMin = Interact->Min + Interact->Position;
+ InteractMax = Interact->Max + Interact->Position;
+ Rad = Interact->Radians;
+ Scale = Interact->Scale;
+ }
+
+ DebugWatchVar("Rad", &Interact->Radians, d_float);
+
+ v2 BoxLength = InteractMax - InteractMin;
+ v2 Center = InteractMax - (BoxLength/2);
+
+ real32 Point0X = Center.x - InteractMin.x;
+ real32 Point0Y = Center.y - InteractMin.y;
+
+ v2 XAxis = (Point0X * Scale)*V2(cos(Rad), sin(Rad));
+ v2 YAxis = (Point0Y * -Scale)*V2(sin(Rad), -cos(Rad));
+
+ // Points are clockwise starting from the top left.
+ real32 X0 = -XAxis.x - YAxis.x + Center.x;
+ real32 Y0 = -XAxis.y - YAxis.y + Center.y;
+ real32 X1 = X0 + XAxis.x*2;
+ real32 Y1 = Y0 + XAxis.y*2;
+ real32 X2 = X1 + YAxis.x*2;
+ real32 Y2 = Y1 + YAxis.y*2;
+ real32 X3 = X2 - XAxis.x*2;
+ real32 Y3 = Y2 - XAxis.y*2;
+
+ // Midway points.
+ real32 Mid_X0 = X0 + XAxis.x;
+ real32 Mid_Y0 = Y0 + XAxis.y;
+ real32 Mid_X1 = X1 + YAxis.x;
+ real32 Mid_Y1 = Y1 + YAxis.y;
+ real32 Mid_X2 = X2 - XAxis.x;
+ real32 Mid_Y2 = Y2 - XAxis.y;
+ real32 Mid_X3 = X3 - YAxis.x;
+ real32 Mid_Y3 = Y3 - YAxis.y;
+
+ ImVec2 CompScale = UI->CompZoom / ImVec2(CompWidth, CompHeight);
+
+ ImVec2 P[4];
+ P[0] = ImVec2(X0, Y0)*CompScale + UI->CompPos;
+ P[1] = ImVec2(X1, Y1)*CompScale + UI->CompPos;
+ P[2] = ImVec2(X2, Y2)*CompScale + UI->CompPos;
+ P[3] = ImVec2(X3, Y3)*CompScale + UI->CompPos;
+
+ ImVec2 Mid_P[4];
+ Mid_P[0] = ImVec2(Mid_X0, Mid_Y0)*CompScale + UI->CompPos;
+ Mid_P[1] = ImVec2(Mid_X1, Mid_Y1)*CompScale + UI->CompPos;
+ Mid_P[2] = ImVec2(Mid_X2, Mid_Y2)*CompScale + UI->CompPos;
+ Mid_P[3] = ImVec2(Mid_X3, Mid_Y3)*CompScale + UI->CompPos;
+
+ ImU32 wcol = ImGui::GetColorU32(ImGuiCol_Text);
+ draw_list->AddLine(P[0], P[1], wcol, 2.0f);
+ draw_list->AddLine(P[1], P[2], wcol, 2.0f);
+ draw_list->AddLine(P[2], P[3], wcol, 2.0f);
+ draw_list->AddLine(P[3], P[0], wcol, 2.0f);
+
+ v2 XAxis2 = (BoxLength*CompScale.x)*V2(cos(Rad), sin(Rad));
+ v2 YAxis2 = (BoxLength*CompScale.y)*V2(sin(Rad), -cos(Rad));
+
+ v2 XAxisPerp = (1.0f / LengthSq(XAxis))*XAxis;
+ v2 YAxisPerp = (1.0f / LengthSq(YAxis))*YAxis;
+
+ // real32 LocalX = ((io.MousePos.x - UI->CompPos.x) - Center.x) ;
+ // real32 LocalY = ((io.MousePos.y - UI->CompPos.y) - Center.y) ;
+ layer_transforms BoxTransforms = { Center.x, Center.y, 0.5, 0.5, (real32)(Rad / (PI / 180)), Scale };
+ v2 LayerPoint = Transform_ScreenSpaceToLocal(BoxTransforms, CompWidth, CompHeight, BoxLength.x, BoxLength.y, UI->CompPos, UI->CompZoom, ViewportMin, io.MousePos);
+
+ real32 U = LayerPoint.x / BoxLength.x;
+ real32 V = LayerPoint.y / BoxLength.y;
+
+ ImVec2 ScaleHandleSize(50, 50);
+
+ bool32 OtherActions = ImGui::IsKeyDown(ImGuiKey_Z);
+
+ /*
+ // First do the halfway scale points, since they don't need UVs considered:
+ for (int i = 0; i < 4; i++) {
+ ImGui::SetCursorScreenPos(Mid_P[i] - ScaleHandleSize/2);
+ ImGui::PushID(i);
+
+ ImGui::PushStyleColor(ImGuiCol_ButtonHovered, ImGui::ColorConvertFloat4ToU32(ImVec4(0.6f, 0.0f, 0.3f, 1.0f)));
+ ImGui::Button("##ScaleMids", ScaleHandleSize);
+ ImGui::PopStyleColor();
+
+ if (ImGui::IsItemActivated() && !OtherActions) {
+ State->InteractTransformMode = 1;
+ }
+
+ if (State->InteractTransformMode == 1 && ImGui::IsItemActive())
+ {
+ uint32 side = i;
+ if (side == 0) {
+ Interact->Scale -= io.MouseDelta.y / BoxLength.y;
+ Interact->Position.y += io.MouseDelta.y / 2;
+ } else if (side == 1) {
+ Interact->Scale += io.MouseDelta.x / BoxLength.x;
+ Interact->Position.x += io.MouseDelta.x / 2;
+ } else if (side == 2) {
+ Interact->Scale += io.MouseDelta.y / BoxLength.y;
+ Interact->Position.y += io.MouseDelta.y / 2;
+ } else if (side == 3) {
+ Interact->Scale -= io.MouseDelta.x / BoxLength.x;
+ Interact->Position.x += io.MouseDelta.x / 2;
+ }
+ }
+ ImGui::PopID();
+ }
+ */
+
+ bool32 InBounds = false;
+ // Scale if cursor is on button within the UV, rotate if outside UV, and position if a non-button is dragged.
+ if (U >= 0.0f && U <= 1.0f && V >= 0.0f && V <= 1.0f)
+ {
+ ImGui::PushStyleColor(ImGuiCol_ButtonHovered, ImGui::ColorConvertFloat4ToU32(ImVec4(0.6f, 0.0f, 0.3f, 1.0f)));
+ InBounds = true;
+ }
+
+ for (int i = 0; i < 4; i++) {
+ ImGui::SetCursorScreenPos(P[i] - ScaleHandleSize/2);
+ ImGui::PushID(i);
+ ImGui::Button("##ScaleRotateCorners", ScaleHandleSize);
+
+ if (ImGui::IsItemActivated() && !OtherActions) {
+ if (InBounds)
+ State->InteractTransformMode = 1;
+ else
+ State->InteractTransformMode = 2;
+ State->Interact_Active = interact_type_viewport_transform_gizmo;
+ if (Interact->Max.x == 0) {
+ *Interact = {};
+ Interact->Min = Min;
+ Interact->Max = Max;
+ }
+ }
+
+ // Scale part
+ if (State->InteractTransformMode == 1 && ImGui::IsItemActive())
+ {
+ // TODO(fox): Corner dragging scale only works in the X
+ // axis. Mostly feels right when dragged how you expect,
+ // but I'll fix it if someone complains.
+ uint32 side = i;
+ if (side == 0) {
+ Interact->Scale -= io.MouseDelta.x / BoxLength.x;
+ Interact->Position.x += io.MouseDelta.x / 2;
+ Interact->Position.y += io.MouseDelta.x*(BoxLength.y/BoxLength.x) / 2;
+ } else if (side == 1) {
+ Interact->Scale += io.MouseDelta.x / BoxLength.x;
+ Interact->Position.x += io.MouseDelta.x / 2;
+ Interact->Position.y -= io.MouseDelta.x*(BoxLength.y/BoxLength.x) / 2;
+ } else if (side == 2) {
+ Interact->Scale += io.MouseDelta.x / BoxLength.x;
+ Interact->Position.x += io.MouseDelta.x / 2;
+ Interact->Position.y += io.MouseDelta.x*(BoxLength.y/BoxLength.x) / 2;
+ } else if (side == 3) {
+ Interact->Scale -= io.MouseDelta.x / BoxLength.x;
+ Interact->Position.x += io.MouseDelta.x / 2;
+ Interact->Position.y -= io.MouseDelta.x*(BoxLength.y/BoxLength.x) / 2;
+ }
+ }
+
+ // Rotation part
+ if (State->InteractTransformMode == 2 && ImGui::IsItemActive())
+ {
+ real32 LocalX = (io.MousePos.x - UI->CompPos.x)/CompScale.x - InteractMin.x - (BoxLength.x/2);
+ real32 LocalY = (io.MousePos.y - UI->CompPos.y)/CompScale.y - InteractMin.y - (BoxLength.y/2);
+
+ real32 Slope_Mouse = LocalY/LocalX;
+ real32 Slope_Corner = 0;
+ real32 Slope_Flipped = 0;
+ real32 Dot = 0;
+
+ // TODO(fox) learn basic geometry to do this properly
+
+ // We find the angle between the direction of whichever corner the
+ // mouse is grabbing (Slope_Corner) and the mouse's current
+ // position (Slope_Mouse) to get ExtraRadians. The calculation only
+ // works between -90 and 90, so I take the dot product of the
+ // opposite edge of the corner and add the extra degrees when it's negative.
+
+ v2 SlopeDot = V2(BoxLength.x, BoxLength.y);
+ // top left clockwise
+ uint32 side = i;
+ if (side == 0) {
+ Slope_Corner = BoxLength.y / BoxLength.x;
+ Slope_Flipped = -BoxLength.x / BoxLength.y;
+ Dot = LocalX * -SlopeDot.x + LocalY * -SlopeDot.y;
+ } else if (side == 1) {
+ Slope_Corner = -BoxLength.y / BoxLength.x;
+ Slope_Flipped = BoxLength.x / BoxLength.y;
+ Dot = LocalX * SlopeDot.x + LocalY * -SlopeDot.y;
+ } else if (side == 2) {
+ Slope_Corner = BoxLength.y / BoxLength.x;
+ Slope_Flipped = -BoxLength.x / BoxLength.y;
+ Dot = LocalX * SlopeDot.x + LocalY * SlopeDot.y;
+ } else if (side == 3) {
+ Slope_Corner = -BoxLength.y / BoxLength.x;
+ Slope_Flipped = BoxLength.x / BoxLength.y;
+ Dot = LocalX * -SlopeDot.x + LocalY * SlopeDot.y;
+ }
+
+ Interact->Radians = atan((Slope_Mouse - Slope_Corner) / (1 + Slope_Mouse * Slope_Corner));
+ real32 ExtraRadians2 = atan((Slope_Mouse - Slope_Flipped) / (1 + Slope_Mouse * Slope_Flipped));
+
+ if (Dot < 0) {
+ if (Interact->Radians < 0) {
+ Interact->Radians = (90 * (PI / 180)) + ExtraRadians2;
+ } else {
+ Interact->Radians = (-90 * (PI / 180)) + ExtraRadians2;
+ }
+ }
+ }
+
+ ImGui::PopID();
+ }
+
+ if (InBounds && !io.KeyAlt) {
+ ImGui::SetCursorScreenPos(io.MousePos - ScaleHandleSize/2);
+ ImGui::Button("##mover", ScaleHandleSize);
+ if (!State->InteractTransformMode && ImGui::IsItemActivated() && !OtherActions) {
+ State->Interact_Active = interact_type_viewport_transform_gizmo;
+ if (Interact->Max.x == 0) {
+ *Interact = {};
+ Interact->Min = Min;
+ Interact->Max = Max;
+ }
+ State->InteractTransformMode = 3;
+ }
+ }
+
+ if (State->InteractTransformMode == 3) {
+ Interact->Position.x += (real32)io.MouseDelta.x/CompScale.x;
+ Interact->Position.y += (real32)io.MouseDelta.y/CompScale.y;
+ }
+
+ if (State->InteractTransformMode)
+ {
+ if (io.MouseDelta.x || io.MouseDelta.y)
+ State->UpdateFrame = true;
+ if (!ImGui::IsMouseDown(ImGuiMouseButton_Left))
+ {
+ Assert(State->Interact_Active == interact_type_viewport_transform_gizmo);
+ int h = 0, c = 0, i = 0;
+ History_Entry_Commit(Memory, "Transform layers");
+ while (Block_Loop(Memory, F_Layers, File->Layer_Count, &h, &c, &i)) {
+ block_layer *Layer = (block_layer *)Memory_Block_AddressAtIndex(Memory, F_Layers, i);
+ if (Layer->IsSelected == 1) {
+ History_Action_Swap(Memory, F_Layers, sizeof(Layer->x.CurrentValue), &Layer->x.CurrentValue);
+ History_Action_Swap(Memory, F_Layers, sizeof(Layer->y.CurrentValue), &Layer->y.CurrentValue);
+ History_Action_Swap(Memory, F_Layers, sizeof(Layer->scale.CurrentValue), &Layer->scale.CurrentValue);
+ History_Action_Swap(Memory, F_Layers, sizeof(Layer->rotation.CurrentValue), &Layer->rotation.CurrentValue);
+ Transform_ApplyInteractive(*(interact_transform *)&State->Interact_Offset[0], &Layer->x.CurrentValue, &Layer->y.CurrentValue, &Layer->rotation.CurrentValue, &Layer->scale.CurrentValue);
+ }
+ }
+ History_Entry_End(Memory);
+ State->Interact_Active = interact_type_none;
+ // *Interact = {};
+ State->UpdateFrame = true;
+ State->InteractTransformMode = 0;
+ State->Interact_Modifier = 0;
+ State->UncommitedKeyframe = 1;
+ State->UpdateFrame = true;
+ }
+ }
+
+ if (InBounds == true) {
+ ImGui::PopStyleColor();
+ }
+
+}
+
static void
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)
@@ -457,26 +908,27 @@ ImGui_Viewport_TransformUI(project_data *File, project_state *State, memory *Mem
// Second condition so you don't have to reach for Enter.
if (ImGui::IsKeyPressed(ImGuiKey_Enter) || (ImGui::IsMouseClicked(ImGuiMouseButton_Left) && io.KeyCtrl)) {
int h = 0, c = 0, i = 0;
- if (!io.KeyCtrl)
- History_Entry_Commit(Memory, "Transform layers");
+ // if (!io.KeyCtrl)
+ History_Entry_Commit(Memory, "Transform layers");
while (Block_Loop(Memory, F_Layers, File->Layer_Count, &h, &c, &i)) {
block_layer *Layer = (block_layer *)Memory_Block_AddressAtIndex(Memory, F_Layers, i);
if (Layer->IsSelected == 1) {
- if (io.KeyCtrl) {
- layer_transforms T = Layer_GetTransforms(Layer);
- Transform_ApplyInteractive(*(interact_transform *)&State->Interact_Offset[0], &T.x, &T.y, &T.rotation, &T.scale);
- property_channel *Property[4] = { &Layer->x, &Layer->y, &Layer->rotation, &Layer->scale };
- real32 Val[4] = { T.x, T.y, T.rotation, T.scale };
- for (int a = 0; a < 4; a++) {
- if (Property[a]->CurrentValue != Val[a]) {
- History_Entry_Commit(Memory, "Add keyframe");
- bezier_point Point = { 1, {(real32)State->Frame_Current, Val[a], -1, 0, 1, 0}, interpolation_type_linear, 0, {0, 0, 0}, 0 };
- uint16 *ArrayLocation = Property_GetSortedArray(SortedKeyframeArray, State->MostRecentlySelectedLayer, h);
- Bezier_Add(Memory, F_Layers, Property[a], Point, ArrayLocation);
- History_Entry_End(Memory);
- }
- }
- } else {
+ // if (io.KeyCtrl) {
+ // layer_transforms T = Layer_GetTransforms(Layer);
+ // Transform_ApplyInteractive(*(interact_transform *)&State->Interact_Offset[0], &T.x, &T.y, &T.rotation, &T.scale);
+ // property_channel *Property[4] = { &Layer->x, &Layer->y, &Layer->rotation, &Layer->scale };
+ // real32 Val[4] = { T.x, T.y, T.rotation, T.scale };
+ // for (int a = 0; a < 4; a++) {
+ // if (Property[a]->CurrentValue != Val[a]) {
+ // History_Entry_Commit(Memory, "Add keyframe");
+ // bezier_point Point = { 1, {(real32)State->Frame_Current, Val[a], -1, 0, 1, 0}, interpolation_type_linear, 0, {0, 0, 0}, 0 };
+ // uint16 *ArrayLocation = Property_GetSortedArray(SortedKeyframeArray, State->MostRecentlySelectedLayer, h);
+ // Bezier_Add(Memory, F_Layers, Property[a], Point, ArrayLocation);
+ // History_Entry_End(Memory);
+ // }
+ // }
+ // } else {
+ {
History_Action_Swap(Memory, F_Layers, sizeof(Layer->x.CurrentValue), &Layer->x.CurrentValue);
History_Action_Swap(Memory, F_Layers, sizeof(Layer->y.CurrentValue), &Layer->y.CurrentValue);
History_Action_Swap(Memory, F_Layers, sizeof(Layer->scale.CurrentValue), &Layer->scale.CurrentValue);
@@ -485,8 +937,8 @@ ImGui_Viewport_TransformUI(project_data *File, project_state *State, memory *Mem
}
}
}
- if (!io.KeyCtrl)
- History_Entry_End(Memory);
+ // if (!io.KeyCtrl)
+ History_Entry_End(Memory);
State->Interact_Active = interact_type_none;
State->Interact_Modifier = 0;
State->UncommitedKeyframe = 1;
@@ -500,12 +952,11 @@ ImGui_Viewport_TransformUI(project_data *File, project_state *State, memory *Mem
}
static void
-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,
+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, v2 *Min, v2 *Max,
sorted_comp_array *SortedCompArray, sorted_layer_array *SortedLayerArray)
{
sorted_comp_array *SortedCompStart = &SortedCompArray[CompIndex];
sorted_layer_array *SortedLayerStart = Sorted_GetLayerStart(SortedLayerArray, SortedCompArray, CompIndex);
- ImU32 wcol = ImGui::GetColorU32(ImGuiCol_Text);
int LayerCount = SortedCompStart->LayerCount + SortedCompStart->FakeLayerCount;
for (int i = 0; i < LayerCount; i++)
{
@@ -514,7 +965,7 @@ ImGui_Viewport_SelectedLayerUI(project_state *State, memory *Memory, ui *UI, ImG
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, io, 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, Min, Max, SortedCompArray, SortedLayerArray);
}
if (Layer->IsSelected) {
uint32 Width = 0, Height = 0;
@@ -546,7 +997,8 @@ ImGui_Viewport_SelectedLayerUI(project_state *State, memory *Memory, ui *UI, ImG
layer_transforms T = Layer_GetTransforms(Layer);
- if (State->Interact_Active == interact_type_viewport_transform && Layer->IsSelected == 1) {
+ if ((State->Interact_Active == interact_type_viewport_transform ||
+ State->Interact_Active == interact_type_viewport_transform_gizmo) && Layer->IsSelected == 1) {
Transform_ApplyInteractive(*(interact_transform *)&State->Interact_Offset[0], &T.x, &T.y, &T.rotation, &T.scale);
}
if (State->Interact_Active == interact_type_viewport_duplicate && SortEntry.IsFake) {
@@ -604,6 +1056,14 @@ ImGui_Viewport_SelectedLayerUI(project_state *State, memory *Memory, ui *UI, ImG
i++;
}
+ for (int i = 0; i < 4; i++) {
+ v2 Pos = NewPos[i+1];
+ if (Pos.x < Min->x) { Min->x = Pos.x; }
+ if (Pos.y < Min->y) { Min->y = Pos.y; }
+ if (Pos.x > Max->x) { Max->x = Pos.x; }
+ if (Pos.y > Max->y) { Max->y = Pos.y; }
+ }
+
ImVec2 ScreenPoint[5];
for (int i = 0; i < 5; i++) {
v2 CompUV = NewPos[i] / V2(MainComp->Width, MainComp->Height);
@@ -612,15 +1072,18 @@ ImGui_Viewport_SelectedLayerUI(project_state *State, memory *Memory, ui *UI, ImG
UI->CompPos.y + CompUV.y * UI->CompZoom.y);
}
- if (State->Tool != tool_brush) {
- ImU32 wcol2 = IM_COL32(10, 10, 10, 128);
- draw_list->AddNgon(ScreenPoint[0], 10, wcol2, 8, 9.0f);
- draw_list->AddNgon(ScreenPoint[0], 10, wcol, 8, 5.0f);
+ ImU32 wcol = IM_COL32(200, 200, 255, 255);
+ if (State->Interact_Active != interact_type_viewport_transform_gizmo) {
+ if (State->Tool != tool_brush) {
+ ImU32 wcol2 = IM_COL32(10, 10, 10, 128);
+ draw_list->AddNgon(ScreenPoint[0], 10, wcol2, 8, 9.0f);
+ draw_list->AddNgon(ScreenPoint[0], 10, wcol, 8, 5.0f);
+ }
+ draw_list->AddLine(ScreenPoint[1], ScreenPoint[2], wcol, 1.0f);
+ draw_list->AddLine(ScreenPoint[2], ScreenPoint[4], wcol, 1.0f);
+ draw_list->AddLine(ScreenPoint[1], ScreenPoint[3], wcol, 1.0f);
+ draw_list->AddLine(ScreenPoint[3], ScreenPoint[4], wcol, 1.0f);
}
- draw_list->AddLine(ScreenPoint[1], ScreenPoint[2], wcol, 2.0f);
- draw_list->AddLine(ScreenPoint[2], ScreenPoint[4], wcol, 2.0f);
- draw_list->AddLine(ScreenPoint[1], ScreenPoint[3], wcol, 2.0f);
- draw_list->AddLine(ScreenPoint[3], ScreenPoint[4], wcol, 2.0f);
}
}
}
@@ -693,9 +1156,13 @@ 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, io, draw_list, MainComp, File->PrincipalCompIndex, ParentLayer, 0, SortedCompArray, SortedLayerArray);
+ // NOTE(fox): This min and max val is affected by interactive transforms!
+ v2 Min = V2(10000, 10000), Max = V2(-10000, -10000);
+ ImGui_Viewport_SelectedLayerUI(State, Memory, UI, io, draw_list, MainComp, File->PrincipalCompIndex, ParentLayer, 0, &Min, &Max, SortedCompArray, SortedLayerArray);
if (State->Interact_Active == interact_type_viewport_transform) {
ImGui_Viewport_TransformUI(File, State, Memory, UI, io, draw_list, (interact_transform *)&State->Interact_Offset[0], ViewportMin, MainComp->Width, MainComp->Height, SortedKeyframeArray);
+ } else {
+ ImGui_Viewport_TransformUI2(File, State, Memory, UI, io, draw_list, Min, Max, ViewportMin, MainComp->Width, MainComp->Height, SortedKeyframeArray);
}
}
@@ -784,7 +1251,9 @@ ImGui_Viewport(project_data *File, project_state *State, ui *UI, memory *Memory,
}
}
- if (IsHovered && IsDeactivated && !io.KeyCtrl && !io.KeyAlt && !ImGui::IsMouseDown(ImGuiMouseButton_Right && !ImGui::IsKeyDown(ImGuiKey_Z)))
+ if (((io.KeyAlt && IsActivated && State->MostRecentlySelectedLayer == -1) ||
+ (IsHovered && IsDeactivated && !io.KeyCtrl && !io.KeyAlt)) &&
+ !ImGui::IsMouseDown(ImGuiMouseButton_Right) && !ImGui::IsKeyDown(ImGuiKey_Z))
{
// Layer selection
if (State->Tool == tool_default && State->Interact_Active == interact_type_none) {
@@ -883,6 +1352,7 @@ ImGui_Viewport(project_data *File, project_state *State, ui *UI, memory *Memory,
real32 Delta = io.MouseDelta.x + io.MouseDelta.y;
if (Delta && IsActive) {
State->Interact_Active = interact_type_viewport_slide;
+ Slide_Init(File, State, Memory);
}
}
@@ -891,10 +1361,13 @@ ImGui_Viewport(project_data *File, project_state *State, ui *UI, memory *Memory,
Assert(0);
} else {
Assert(IsActive);
+ v2 PrevMouseCompPos = ImGui_ScreenPointToCompUV(ViewportMin, UI->CompPos, UI->CompZoom, io.MousePosPrev);
v2 MouseCompPos = ImGui_ScreenPointToCompUV(ViewportMin, UI->CompPos, UI->CompZoom, io.MousePos);
- v2 DragDelta = MouseCompPos - State->LastClickedPoint;
- State->Interact_Offset[0] = DragDelta.x * MainComp->Width;
- State->Interact_Offset[1] = DragDelta.y * MainComp->Height;
+ State->Interact_Offset[0] = MouseCompPos.x;
+ State->Interact_Offset[1] = MouseCompPos.y;
+ State->Interact_Offset[3] = PrevMouseCompPos.x;
+ State->Interact_Offset[4] = PrevMouseCompPos.y;
+ Slide_Test(File, State, Memory, SortedCompArray, SortedLayerArray);
}
}
@@ -913,16 +1386,13 @@ ImGui_Viewport(project_data *File, project_state *State, ui *UI, memory *Memory,
}
if (Shape->Point_Count == 0 && IsDeactivated && !OtherActions && !ImGui::IsMouseReleased(ImGuiMouseButton_Right)) {
ImVec2 ScreenPoint[4] = { ScreenPointStart, ImVec2(ScreenPointStart.x, MousePos.y), MousePos, ImVec2(MousePos.x, ScreenPointStart.y) };
- History_Entry_Commit(Memory, "Add rectangle");
+ v2 *CompPoint = (v2 *)&State->Interact_Offset[0];
for (int i = 0; i < 4; i++) {
- v2 CompPoint = ImGui_ScreenPointToCompUV(ViewportMin, UI->CompPos, UI->CompZoom, ScreenPoint[i]);
- CompPoint = CompPoint * V2(MainComp->Width, MainComp->Height);
- bezier_point PointData = { 1, { CompPoint, V2(0, 0), V2(0, 0) }, interpolation_type_linear, 0 };
- Bezier_Add(Memory, F_File, Shape->Block_Bezier_Index, &Shape->Block_Bezier_Count, &Shape->Point_Count, PointData);
+ CompPoint[i] = ImGui_ScreenPointToCompUV(ViewportMin, UI->CompPos, UI->CompZoom, ScreenPoint[i]);
+ CompPoint[i] = CompPoint[i] * V2(MainComp->Width, MainComp->Height);
}
- Shape->IsClosed = true;
- History_Entry_End(Memory);
State->HotkeyInput = hotkey_newlayer_shape;
+ State->Interact_Modifier = 1;
}
}