summaryrefslogtreecommitdiff
path: root/my_imgui_widgets.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'my_imgui_widgets.cpp')
-rw-r--r--my_imgui_widgets.cpp1056
1 files changed, 916 insertions, 140 deletions
diff --git a/my_imgui_widgets.cpp b/my_imgui_widgets.cpp
index c5a4049..e1e9ffc 100644
--- a/my_imgui_widgets.cpp
+++ b/my_imgui_widgets.cpp
@@ -4,6 +4,72 @@
#include "imgui_helper_widgets.cpp"
static void
+ImGui_InteractSliderProperty(project_state *State, memory *Memory, property_channel *Property)
+{
+ ImGui::DragScalar(Property->Name, ImGuiDataType_Float, &Property->CurrentValue,
+ Property->ScrubVal, &Property->MinVal, &Property->MaxVal, "%f");
+ /*
+ if (ImGui::IsItemActivated()) {
+ State->InteractCache[0] = Property->CurrentValue.f;
+ }
+ if (ImGui::IsItemActive()) {
+ State->UpdateFrame = true;
+ }
+ if (ImGui::IsItemDeactivatedAfterEdit()) {
+ if (ImGui::IsKeyPressed(ImGuiKey_Escape)) {
+ Property->CurrentValue.f = State->InteractCache[0];
+ } else {
+ History_Entry_Commit(Memory, action_entry_default, "Tranforms interact");
+ History_Action_Change(Memory, &Property->CurrentValue.f, &State->InteractCache[0],
+ &Property->CurrentValue.f, action_type_change_r32);
+ History_Entry_End(Memory);
+ }
+ State->UpdateFrame = true;
+ }
+ */
+}
+
+static void
+ImGui_PropertiesPanel(project_data *File, project_state *State, ui *UI, memory *Memory, ImGuiIO io)
+{
+ bool32 Display = 1;
+ block_layer *Layer = NULL;
+ if (State->MostRecentlySelectedLayer > -1) {
+ Layer = (block_layer *)Memory_Block_AddressAtIndex(Memory, F_Layers, State->MostRecentlySelectedLayer);
+ if (!Layer->Occupied)
+ Display = 0;
+ } else {
+ Display = 0;
+ }
+ if (Display) {
+ block_string *String = (block_string *)Memory_Block_AddressAtIndex(Memory, F_Strings, Layer->Block_String_Index);
+ char buf[256];
+ sprintf(buf, "Properties: %s###Properties", String->Char);
+ ImGui::Begin(buf);
+ if (ImGui::IsWindowFocused(ImGuiFocusedFlags_ChildWindows))
+ UI->FocusedWindow = focus_properties;
+ ImGui::Text("Transform");
+ for (int h = 0; h < AmountOf(Layer->Property); h++) {
+ property_channel *Property = &Layer->Property[h];
+ ImGui::PushID(Property);
+ ImGui::Button("K");
+ // if (ImGui::Button("K"))
+ // Keyframe_Insert(Property, Memory, File->CurrentFrame, Property->CurrentValue.f);
+ ImGui::SameLine();
+ ImGui_InteractSliderProperty(State, Memory, Property);
+ ImGui::PopID();
+ }
+ ImGui::End();
+ } else {
+ ImGui::Begin("Properties: empty###Properties");
+ if (ImGui::IsWindowFocused(ImGuiFocusedFlags_ChildWindows))
+ UI->FocusedWindow = focus_properties;
+ ImGui::End();
+ }
+}
+
+#if DEBUG
+static void
ImGui_DebugMemoryViewer(memory *Memory, project_state *State)
{
ImGui::Begin("Memory viewer");
@@ -53,23 +119,103 @@ ImGui_DebugMemoryViewer(memory *Memory, project_state *State)
}
static void
-ImGui_File(project_data *File, project_state *State, memory *Memory, ImGuiIO io)
+ImGui_DebugUndoTree(memory *Memory, project_state *State)
+{
+ ImGui::Begin("undotree");
+ for (int i = 0; i < Memory->History.NumberOfEntries; i++) {
+ history_entry Entry = Memory->History.Entry[i];
+ bool32 CurrentPos = (i < Memory->History.EntryPlayhead);
+ ImGui::MenuItem(Entry.Name, NULL, CurrentPos);
+ }
+ ImGui::End();
+}
+#endif
+
+static void
+ImGui_File(project_data *File, project_state *State, memory *Memory, ImGuiIO io,
+ sorted_comp_info *SortedCompArray, sorted_layer *SortedLayerArray)
{
ImGui::Begin("Files");
ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / io.Framerate, io.Framerate);
+ if (!ImGui::IsWindowFocused(ImGuiFocusedFlags_ChildWindows))
+ Source_DeselectAll(File, Memory);
+ else if (ImGui::IsKeyPressed(ImGuiKey_Backspace)) {
+
+ /*
+ uint64 SortSize = (sizeof(uint16) * File->Comp_Count);
+ void *SortedArray = Memory_PushScratch(Memory, SortSize);
+ uint16 *SelectedSourceIndex = (uint16 *)SortedArray;
+ int SelectedSourceCount = 0;
+
+ int h = 0, c = 0, i = 0;
+ int SourceCount = File->Source_Count;
+ while (Block_Loop(Memory, F_Sources, SourceCount, &h, &c, &i)) {
+ block_source *Source = (block_source *)Memory_Block_AddressAtIndex(Memory, F_Sources, i);
+ if (Source->IsSelected) {
+ SelectedSourceIndex[SelectedSourceCount] = i;
+ SelectedSourceCount++;
+ }
+ }
+
+ h = 0, c = 0, i = 0;
+ int LayerCount = File->Layer_Count;
+ while (Block_Loop(Memory, F_Layers, LayerCount, &h, &c, &i)) {
+ block_layer *Layer = (block_layer *)Memory_Block_AddressAtIndex(Memory, F_Layers, i);
+ for (int b = 0; b < SelectedSourceCount; b++) {
+ if (SelectedSourceIndex[b] == Layer->Block_Source_Index) {
+ }
+ }
+ }
+
+ Memory_PopScratch(Memory, SortSize);
+ */
+
+ /*
+ bool32 CommitAction = 0;
+ while (Block_Loop(Memory, F_Sources, SourceCount, &h, &c, &i)) {
+ block_source *Source = (block_source *)Memory_Block_AddressAtIndex(Memory, F_Sources, i);
+ if (Source->IsSelected) {
+ if (!CommitAction) {
+ History_Entry_Commit(Memory, "Delete source");
+ CommitAction = 1;
+ }
+ Source_Delete(File, Memory, i);
+ }
+ }
+ if (CommitAction)
+ History_Entry_End(Memory);
+ */
+ }
+
for (int c = 0; c < File->Comp_Count; c++) {
block_composition *Comp = (block_composition *)Memory_Block_AddressAtIndex(Memory, F_Precomps, c);
block_string *String = (block_string *)Memory_Block_AddressAtIndex(Memory, F_Strings, Comp->Name_String_Index);
ImGui::Text(String->Char);
}
- for (int c = 0; c < File->Source_Count; c++) {
- block_source *Source = (block_source *)Memory_Block_AddressAtIndex(Memory, F_Sources, c);
+ int h = 0, c = 0, i = 0;
+ while (Block_Loop(Memory, F_Sources, File->Source_Count, &h, &c, &i)) {
+ block_source *Source = (block_source *)Memory_Block_AddressAtIndex(Memory, F_Sources, i);
block_string *String = (block_string *)Memory_Block_AddressAtIndex(Memory, F_Strings, Source->Path_String_Index);
- ImGui::Text(String->Char);
+ ImGui::Selectable(String->Char, Source->IsSelected);
+ if (ImGui::IsItemClicked() || ImGui::IsItemClicked(ImGuiMouseButton_Right)) {
+ if (!io.KeyShift && !Source->IsSelected) {
+ Source_DeselectAll(File, Memory);
+ }
+ Source->IsSelected = 1;
+ }
+ ImGui::OpenPopupOnItemClick("sourcecontext", ImGuiPopupFlags_MouseButtonRight);
+ }
+
+ if (ImGui::BeginPopup("sourcecontext")) {
+ if (ImGui::MenuItem("Create layer from source")) {
+ Source_UICreateButton(File, State, Memory, SortedCompArray, SortedLayerArray);
+ }
+ ImGui::EndPopup();
}
#if DEBUG
+
for (int i = 0; i < Debug.Temp.WatchedProperties; i++) {
if (Debug.Temp.DebugPropertyType[i] == d_float) {
ImGui::Text("%s: %f", Debug.Temp.String[i], Debug.Temp.Val[i].f);
@@ -84,7 +230,410 @@ ImGui_File(project_data *File, project_state *State, memory *Memory, ImGuiIO io)
}
static void
-ImGui_Viewport(project_data *File, project_state *State, ui *UI, memory *Memory, ImGuiIO io, GLuint textureID)
+ImGui_ColorPanel(project_data *File, project_state *State, ui *UI, memory *Memory, ImGuiIO io)
+{
+ ImGuiStyle& style = ImGui::GetStyle();
+
+ ImGui::Begin("Colors");
+
+ ImGuiColorEditFlags flags_primary = ImGuiColorEditFlags_AlphaPreview |
+ ImGuiColorEditFlags_Float;
+ ImGuiColorEditFlags flags_picker = ImGuiColorEditFlags_PickerHueBar |
+ ImGuiColorEditFlags_AlphaBar |
+ ImGuiColorEditFlags_NoSmallPreview |
+ ImGuiColorEditFlags_NoSidePreview |
+ ImGuiColorEditFlags_DisplayRGB |
+ ImGuiColorEditFlags_DisplayHSV |
+ ImGuiColorEditFlags_DisplayHex;
+
+ // Dim window if it's not active so there's not a big saturation square in
+ // the corner of my vision while I'm editing. Personal preference.
+ real32 AlphaMult = (ImGui::IsWindowFocused(ImGuiFocusedFlags_ChildWindows)) ? 1.0f : 0.3f;
+ ImGui::PushStyleVar(ImGuiStyleVar_Alpha, style.Alpha * AlphaMult);
+
+ ImGui::ColorPicker4("##maincolorpicker", &UI->Color.r, flags_primary | flags_picker);
+
+ ImGui::PopStyleVar();
+
+ if (ImGui::ColorButton("##primarycolor", *(ImVec4*)&UI->Color.r, flags_primary, ImVec2(20, 20)))
+ {
+ v4 Temp = UI->Color;
+ UI->Color = UI->AltColor;
+ UI->AltColor = Temp;
+ }
+ if (ImGui::ColorButton("##secondarycolor", *(ImVec4*)&UI->AltColor.r, flags_primary, ImVec2(20, 20)))
+ {
+ v4 Temp = UI->Color;
+ UI->Color = UI->AltColor;
+ UI->AltColor = Temp;
+ }
+
+ if (State->Tool == tool_brush) {
+ real32 BrushSizeMin = 0;
+ real32 BrushSizeMax = 1024;
+ real32 BrushHardnessMin = 0.5;
+ real32 BrushHardnessMax = 100;
+ real32 BrushSpacingMin = 0.1;
+ real32 BrushSpacingMax = 100;
+ if (ImGui::DragScalar("Size", ImGuiDataType_Float, &State->Brush.Size, 1, &BrushSizeMin, &BrushSizeMax, "%.3f")) {
+ Brush_CalcBitmapAlphaFromSize(Memory, &State->Brush, 4);
+ State_BindBrushTexture(Memory, &State->Brush, 4);
+ }
+ if (ImGui::DragScalar("Hardness", ImGuiDataType_Float, &State->Brush.Hardness, 1, &BrushHardnessMin, &BrushHardnessMax, "%.3f", ImGuiSliderFlags_Logarithmic)) {
+ Brush_CalcBitmapAlphaFromSize(Memory, &State->Brush, 4);
+ State_BindBrushTexture(Memory, &State->Brush, 4);
+ }
+ if (ImGui::DragScalar("Spacing", ImGuiDataType_Float, &State->Brush.Spacing, 1, &BrushSpacingMin, &BrushSpacingMax, "%.3f", ImGuiSliderFlags_Logarithmic)) {
+ Brush_CalcBitmapAlphaFromSize(Memory, &State->Brush, 4);
+ State_BindBrushTexture(Memory, &State->Brush, 4);
+ }
+ ImGui::Button(BrushNames[State->Brush.Type]);
+ ImGui::OpenPopupOnItemClick("brush_picker", ImGuiPopupFlags_MouseButtonLeft);
+ if (ImGui::BeginPopup("brush_picker")) {
+ for (int16 b = 0; b < brush_amount; b++) {
+ if (ImGui::MenuItem(BrushNames[b], NULL, false, State->Brush.Type != b)) {
+ State->Brush.Type = (brush_type)b;
+ }
+ }
+ ImGui::EndPopup();
+ }
+ }
+
+ ImGui::End();
+}
+
+static void
+ImGui_Toolbar(project_state *State, ImDrawList *draw_list)
+{
+ ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0, 0));
+ ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(0, 0));
+ // ImGui::PushStyleColor(ImGuiCol_Button, IM_COL32(50, 50, 50, 0));
+
+ real32 IconSize = ImGui::GetFontSize() * 4;
+ int ToolCount = (int)tool_count;
+ ImVec2 ButtonSize(IconSize, IconSize);
+ ImVec2 WindowSize(IconSize, IconSize * ToolCount);
+ ImGui::BeginChild("Toolbar", WindowSize, true, ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoScrollbar);
+ for (int i = 0; i < ToolCount; i++) {
+ ImGui::PushID(i);
+ // draw_list->AddImage((void *)(intptr_t)State->ToolIconTex[i], Min, Max);
+ if ((int)State->Tool == i) {
+ ImVec2 Min = ImGui::GetCursorScreenPos();
+ ImVec2 Max = Min + ButtonSize;
+ draw_list->AddRectFilled(Min, Max, IM_COL32(255, 255, 255, 128));
+ }
+ ImGui::Button(ToolName[i], ButtonSize);
+ if (ImGui::IsItemActivated()) {
+ State->Tool = (tool)i;
+ }
+ ImGui::PopID();
+ }
+ ImGui::EndChild();
+
+ // ImGui::PopStyleColor();
+ ImGui::PopStyleVar(2);
+}
+
+static void
+ImGui_RenderUIBrush(project_state *State, memory *Memory, ImVec2 ViewportMin, ImVec2 ViewportMax, ImVec2 CompZoom, ImGuiIO io, uint16 Width, uint16 Height)
+{
+
+ ImDrawList* draw_list = ImGui::GetWindowDrawList();
+ if (State->Tool == tool_brush) {
+
+ if (ImGui::IsKeyPressed(ImGuiKey_ModAlt, false)) {
+ State->Brush.UIPos = io.MousePos;
+ }
+
+ ImVec2 CompScale = CompZoom / ImVec2(Width, Height);
+ ImVec2 BrushSize = CompScale * State->Brush.Size;
+ ImVec2 MinBounds = State->Brush.UIPos - BrushSize/2;
+ ImVec2 MaxBounds = MinBounds + BrushSize;
+
+ if (io.KeyAlt) {
+ draw_list->PushClipRect(ViewportMin, ViewportMax, true);
+ draw_list->AddImage((void *)(intptr_t)State->Brush.GLTexture, MinBounds, MaxBounds, ImVec2(0, 0), ImVec2(1, 1), 1);
+ draw_list->PopClipRect();
+ ImGui::SetCursorScreenPos(State->Brush.UIPos);
+ char buf[256];
+ sprintf(buf, "Size: %.1f, Hardness: %.1f", State->Brush.Size, State->Brush.Hardness);
+ ImGui::Text(buf);
+ if (io.MouseDelta.x || io.MouseDelta.y) {
+ ImVec2 Delta = io.MouseDelta;
+ State->Brush.Size += Delta.x;
+ State->Brush.Hardness += Delta.y*State->Brush.Hardness/100;
+ if (State->Brush.Size < 0)
+ State->Brush.Size = 0;
+ if (State->Brush.Size > 1024)
+ State->Brush.Size = 1024;
+ if (State->Brush.Hardness < 0.5)
+ State->Brush.Hardness = 0.5;
+ if (State->Brush.Hardness > 100)
+ State->Brush.Hardness = 100;
+ Brush_CalcBitmapAlphaFromSize(Memory, &State->Brush, 4);
+ State_BindBrushTexture(Memory, &State->Brush, 4);
+ }
+ }
+ }
+}
+
+static void
+ImGui_TransformUI(project_data *File, project_state *State, memory *Memory, ui *UI, ImDrawList *draw_list, ImGuiIO &io, interact_transform *Interact, ImVec2 ViewportMin, uint32 CompWidth, uint32 CompHeight)
+{
+ v2 InteractMin = Interact->Min + Interact->Position;
+ v2 InteractMax = Interact->Max + Interact->Position;
+
+ v2 BoxLength = InteractMax - InteractMin;
+ v2 Center = InteractMax - (BoxLength/2);
+
+ real32 Point0X = Center.x - InteractMin.x;
+ real32 Point0Y = Center.y - InteractMin.y;
+
+ real32 Rad = Interact->Radians;
+
+ v2 XAxis = (Point0X * Interact->Scale)*V2(cos(Rad), sin(Rad));
+ v2 YAxis = (Point0Y * -Interact->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)(Interact->Radians / (PI / 180)), Interact->Scale };
+ v2 LayerPoint = Transform_ScreenSpaceToLocal(BoxTransforms, CompWidth, CompHeight, BoxLength.x, BoxLength.y, *UI, 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) {
+ UI->InteractTransformMode = 1;
+ }
+
+ if (UI->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)
+ UI->InteractTransformMode = 1;
+ else
+ UI->InteractTransformMode = 2;
+ }
+
+ // Scale part
+ if (UI->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 (UI->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 (!UI->InteractTransformMode && ImGui::IsMouseClicked(ImGuiMouseButton_Left) && InBounds && !OtherActions)
+ UI->InteractTransformMode = 3;
+
+ if (UI->InteractTransformMode == 3) {
+ Interact->Position.x += (real32)io.MouseDelta.x/CompScale.x;
+ Interact->Position.y += (real32)io.MouseDelta.y/CompScale.y;
+ }
+
+ if (UI->InteractTransformMode)
+ {
+ if (io.MouseDelta.x || io.MouseDelta.y)
+ State->UpdateFrame = true;
+ if (!ImGui::IsMouseDown(ImGuiMouseButton_Left))
+ UI->InteractTransformMode = 0;
+ }
+
+ if (ImGui::IsKeyPressed(ImGuiKey_Escape)) {
+ State->UpdateFrame = true;
+ }
+
+ // 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;
+ 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) {
+ History_Action_Swap(Memory, F_File, sizeof(Layer->x.CurrentValue), &Layer->x.CurrentValue);
+ History_Action_Swap(Memory, F_File, sizeof(Layer->y.CurrentValue), &Layer->y.CurrentValue);
+ History_Action_Swap(Memory, F_File, sizeof(Layer->scale.CurrentValue), &Layer->scale.CurrentValue);
+ History_Action_Swap(Memory, F_File, 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;
+ State->UpdateFrame = true;
+ }
+
+ if (InBounds == true) {
+ ImGui::PopStyleColor();
+ }
+
+}
+
+static void
+ImGui_Viewport(project_data *File, project_state *State, ui *UI, memory *Memory, ImGuiIO io, GLuint textureID,
+ sorted_comp_info *SortedCompArray, sorted_layer *SortedLayerArray)
{
bool open = true;
ImGui::Begin("Viewport", &open, ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoScrollWithMouse);
@@ -119,6 +668,42 @@ ImGui_Viewport(project_data *File, project_state *State, ui *UI, memory *Memory,
draw_list->AddImage((void *)(intptr_t)textureID, CompPosMin, CompPosMax);
draw_list->PopClipRect();
+ ImU32 wcol = ImGui::GetColorU32(ImGuiCol_Text);
+ // UI+interaction for layer
+ if (State->MostRecentlySelectedLayer > -1)
+ {
+ int h = 0, c = 0, i = 0;
+ 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) {
+ block_source *Source = (block_source *)Memory_Block_AddressAtIndex(Memory, F_Sources, Layer->Block_Source_Index);
+
+ // Anchor point UI
+ v2 CenterPoint = V2(Source->Width*Layer->ax.CurrentValue, Source->Height*Layer->ay.CurrentValue);
+ ImVec2 ScreenAP = Layer_LocalToScreenSpace(State, Layer, UI, Source->Width, Source->Height, MainComp->Width, MainComp->Height, CenterPoint);
+ draw_list->AddNgon(ScreenAP, 20, wcol, 8, 10.0f);
+
+ // Bounding box UI
+ ImVec2 P1 = Layer_LocalToScreenSpace(State, Layer, UI, Source->Width, Source->Height, MainComp->Width, MainComp->Height, V2(0, 0));
+ ImVec2 P2 = Layer_LocalToScreenSpace(State, Layer, UI, Source->Width, Source->Height, MainComp->Width, MainComp->Height, V2(Source->Width, 0));
+ ImVec2 P3 = Layer_LocalToScreenSpace(State, Layer, UI, Source->Width, Source->Height, MainComp->Width, MainComp->Height, V2(0, Source->Height));
+ ImVec2 P4 = Layer_LocalToScreenSpace(State, Layer, UI, Source->Width, Source->Height, MainComp->Width, MainComp->Height, V2(Source->Width, Source->Height));
+ draw_list->AddLine(P1, P2, wcol, 2.0f);
+ draw_list->AddLine(P2, P4, wcol, 2.0f);
+ draw_list->AddLine(P1, P3, wcol, 2.0f);
+ draw_list->AddLine(P3, P4, wcol, 2.0f);
+
+ }
+ }
+
+ if (State->Interact_Active == interact_type_viewport_transform) {
+ ImGui_TransformUI(File, State, Memory, UI, draw_list, io, (interact_transform *)&State->Interact_Offset[0], ViewportMin, MainComp->Width, MainComp->Height);
+ }
+ }
+
+
+
// Interactions for dragging and zooming
ImGui::SetCursorScreenPos(ViewportMin);
@@ -133,29 +718,83 @@ ImGui_Viewport(project_data *File, project_state *State, ui *UI, memory *Memory,
// Point to zoom in on if Z is held
UI->TempZoomRatio = ImGui_ScreenPointToCompUV(ViewportMin, UI->CompPos, UI->CompZoom, io.MousePos);
+ if (State->Tool == tool_brush && File->Layer_Count != 2) {
+ State->Interact_Active = interact_type_newlayer_paint;
+ History_Entry_Commit(Memory,"Paint new layer");
+ uint16 SourceIndex = Source_Generate_Blank(File, State, Memory, MainComp->Width, MainComp->Height, MainComp->BytesPerPixel);
+ Assert(0);
+ // Layer_CreateFromSource(File, State, Memory, SourceIndex, MainComp->Frame_End);
+ History_Entry_End(Memory);
+ }
+
// Layer selection
- /*
- if (!ImGui::IsKeyDown(ImGuiKey_Z) || !State->Pen.IsActive) {
- for (int i = File.NumberOfLayers - 1; i >= 0; i--) {
- project_layer *Layer = File.Layer[i];
- if (!io.KeyShift) DeselectAllLayers(&File, State);
- v2 LayerUV = CompUVToLayerUV(Layer, &CompBuffer, UI->TempZoomRatio);
- if (TestUV(LayerUV) && !Layer->IsSelected)
- {
- SelectLayer(Layer, State, i);
- break;
- }
- }
+ if (!ImGui::IsKeyDown(ImGuiKey_Z) && State->Tool == tool_default && State->Interact_Active == interact_type_none) {
+ int32 Selection = Layer_TestSelection(Memory, State, UI, SortedCompArray, SortedLayerArray, File->PrincipalCompIndex);
+ if (!io.KeyShift && State->Interact_Active == interact_type_none)
+ Layer_DeselectAll(Memory, File->Layer_Count);
+ if (Selection != -1)
+ Layer_Select(Memory, State, Selection);
}
- */
}
+ /*
+ if (State->Interact_Active == interact_type_viewport_transform) {
+ interact_transform *Interact = (interact_transform *)&State->Interact_Offset[0];
+ ImVec2 DragDelta = io.MousePos - Interact->OGPos;
+ Interact->Position = V2(DragDelta.x, DragDelta.y);
+ if (io.MouseDelta.x || io.MouseDelta.y)
+ State->UpdateFrame = true;
+ }
+ */
+
if (IsActive && ImGui::IsMouseDragging(ImGuiMouseButton_Right, -1.0f))
{
UI->CompPos.x += io.MouseDelta.x;
UI->CompPos.y += io.MouseDelta.y;
}
+ bool32 OtherActions = ImGui::IsKeyDown(ImGuiKey_Z) || ImGui::IsMouseDown(ImGuiMouseButton_Right);
+ if (State->Tool == tool_brush) {
+ if (IsActive && !OtherActions) {
+ block_layer *Layer = (block_layer *)Memory_Block_AddressAtIndex(Memory, F_Layers, 0);
+ layer_transforms T_Layer = Layer_GetTransforms(Layer);
+ block_source *Source = (block_source *)Memory_Block_AddressAtIndex(Memory, F_Sources, Layer->Block_Source_Index);
+ void *SourceBitmapAddress = Memory_Block_AddressAtIndex(Memory, F_PrincipalBitmaps, Source->Bitmap_Index);
+ ImVec2 MouseDelta = io.MouseDelta;
+ real32 Delta = MouseDelta.x + MouseDelta.y;
+ if (Delta != 0.0f) {
+ real32 DeltaDistance = sqrt(MouseDelta.x * MouseDelta.x + MouseDelta.y * MouseDelta.y);
+ real32 DeltaSlope = MouseDelta.y / MouseDelta.x;
+ for (real32 i = 0; i < DeltaDistance; i += State->Brush.Spacing) {
+ ImVec2 MousePos;
+ if (State->Brush.Type == brush_normal) {
+ MousePos = io.MousePos - (MouseDelta * (i / DeltaDistance));
+ } else if (State->Brush.Type == brush_wacky1) {
+ MousePos = io.MousePos + (io.MousePos * (i / MouseDelta));
+ } else if (State->Brush.Type == brush_wacky2) {
+ MousePos = io.MousePos - (MouseDelta / (i / DeltaDistance));
+ } else if (State->Brush.Type == brush_wacky3) {
+ MousePos = io.MousePos - (MouseDelta * (i / ImVec2(MouseDelta.y, MouseDelta.x)));
+ } else {
+ Assert(0);
+ }
+ v2 LayerPos = Transform_ScreenSpaceToLocal(T_Layer, MainComp->Width, MainComp->Height, Source->Width, Source->Height, *UI, ViewportMin, MousePos);
+ PaintTest(Memory, Source, &State->Brush, SourceBitmapAddress, LayerPos, 4, UI->Color);
+ }
+ } else if (IsActivated) {
+ ImVec2 MousePos = io.MousePos;
+ v2 LayerPos = Transform_ScreenSpaceToLocal(T_Layer, MainComp->Width, MainComp->Height, Source->Width, Source->Height, *UI, ViewportMin, MousePos);
+ PaintTest(Memory, Source, &State->Brush, SourceBitmapAddress, LayerPos, 4, UI->Color);
+ }
+ Memory_Cache_Invalidate(State, Memory, cache_entry_type_comp, Layer->Block_Composition_Index, 0);
+ State->UpdateFrame = true;
+ }
+
+ if (IsDeactivated) {
+ State->Interact_Active = interact_type_none;
+ }
+ }
+
if (IsActive && ImGui::IsMouseDragging(ImGuiMouseButton_Left, -1.0f) && ImGui::IsKeyDown(ImGuiKey_Z))
{
real32 Distance = io.MouseDelta.x + io.MouseDelta.y;
@@ -175,8 +814,12 @@ ImGui_Viewport(project_data *File, project_state *State, ui *UI, memory *Memory,
State->MsgTime--;
}
- ImGui::End();
+ ImGui::SetCursorScreenPos(ViewportMin);
+ ImGui_Toolbar(State, draw_list);
+ ImGui_RenderUIBrush(State, Memory, ViewportMin, ViewportMax, UI->CompPos, io, MainComp->Width, MainComp->Height);
+
+ ImGui::End();
/*
for (int i = 0; i < AmountOf(Layer->Property); i++) {
@@ -192,10 +835,11 @@ ImGui_Viewport(project_data *File, project_state *State, ui *UI, memory *Memory,
}
static void
-ImGui_TimelineHorizontalIncrementDraw(ui *UI, ImDrawList *draw_list, ImVec2 TimelineSizeWithBorder, ImVec2 TimelineAbsolutePos, block_composition MainComp,
+ImGui_TimelineHorizontalIncrementDraw(project_state *State, ui *UI, ImDrawList *draw_list, ImVec2 TimelineSizeWithBorder, ImVec2 TimelineAbsolutePos, block_composition MainComp,
ImVec2 TimelineZoomSize, ImVec2 TimelineMoveSize)
{
uint32 LineColor = IM_COL32(200, 200, 200, 40);
+ uint32 PlayheadColor = IM_COL32(000, 000, 200, 160);
Assert(TimelineZoomSize.x > 0.0f);
@@ -226,6 +870,10 @@ ImGui_TimelineHorizontalIncrementDraw(ui *UI, ImDrawList *draw_list, ImVec2 Time
RightmostEdge = true;
}
}
+
+ ImVec2 Min = ImVec2(TimelineAbsolutePos.x + TimelineMoveSize.x + ((real32)State->Frame_Current / MainComp.Frame_Count)*TimelineZoomSize.x, TimelineAbsolutePos.y);
+ ImVec2 Max = ImVec2(Min.x + 2, TimelineAbsolutePos.y + TimelineSizeWithBorder.y);
+ draw_list->AddLine(Min, Max, PlayheadColor);
}
@@ -235,16 +883,17 @@ ImGui_GraphInfo(project_data *File, project_state *State, memory *Memory, ui *UI
bool open = true;
ImGui::Begin("Graph info", &open, ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoScrollWithMouse);
- for (int a = 0; a < File->Layer_Count; a++)
+ int h = 0, c = 0, i = 0;
+ while (Block_Loop(Memory, F_Layers, File->Layer_Count, &h, &c, &i))
{
- block_layer *Layer = (block_layer *)Memory_Block_AddressAtIndex(Memory, F_Layers, a);
+ block_layer *Layer = (block_layer *)Memory_Block_AddressAtIndex(Memory, F_Layers, i);
if (!Layer->IsSelected)
continue;
block_string *String = (block_string *)Memory_Block_AddressAtIndex(Memory, F_Strings, Layer->Block_String_Index);
ImGui::Text(String->Char);
- ImGui::PushID(a);
+ ImGui::PushID(i);
for (int h = 0; h < AmountOf(Layer->Property); h++) {
property_channel *Property = &Layer->Property[h];
if (Property->Block_Bezier_Count) {
@@ -267,9 +916,10 @@ ImGui_Timeline_DrawGraph(project_data *File, project_state *State, memory *Memor
{
UI->Test.Split(draw_list, 2);
- for (int a = 0; a < File->Layer_Count; a++)
+ int h = 0, c = 0, i = 0;
+ while (Block_Loop(Memory, F_Layers, File->Layer_Count, &h, &c, &i))
{
- block_layer *Layer = (block_layer *)Memory_Block_AddressAtIndex(Memory, F_Layers, a);
+ block_layer *Layer = (block_layer *)Memory_Block_AddressAtIndex(Memory, F_Layers, i);
if (!Layer->IsSelected)
continue;
@@ -285,7 +935,7 @@ ImGui_Timeline_DrawGraph(project_data *File, project_state *State, memory *Memor
ImVec2 Layer_ScreenPos_Max = TimelineAbsolutePos + TimelineMoveSize + ((Layer_LocalPos_Ratio + Layer_LocalSize_Ratio) * TimelineZoomSize);
ImVec2 Layer_ScreenSize = Layer_ScreenPos_Max - Layer_ScreenPos_Min;
- ImGui::PushID(a);
+ ImGui::PushID(i);
ImU32 col = IM_COL32(255, 255, 255, 255);
@@ -304,6 +954,8 @@ ImGui_Timeline_DrawGraph(project_data *File, project_state *State, memory *Memor
State->Interact_Active == interact_type_keyframe_rotate ||
State->Interact_Active == interact_type_keyframe_scale))
{
+ Assert(0);
+ // Memory_Cache_Invalidate(State, Memory, cache_entry_type_comp, Lay
}
for (int h = 0; h < AmountOf(Layer->Property); h++) {
@@ -445,9 +1097,9 @@ ImGui_Timeline_DrawPrecomp(project_data *File, project_state *State, memory *Mem
int32 Frame_Start = Layer->Frame_Start;
int32 Frame_End = Layer->Frame_End;
- real32 Vertical_Offset = Layer->Vertical_Offset;
- if (Layer->IsSelected)
- Layer_Interact_Evaluate(Memory, State, Index_Physical, SortedCompInfo, SortedLayerInfo, &Frame_Start, &Frame_End, &Vertical_Offset);
+ real32 Vertical_Offset = SortEntry.SortedOffset;
+ // if (Layer->IsSelected)
+ // Layer_Interact_Evaluate(Memory, State, Index_Physical, SortedCompInfo, SortedLayerInfo, &Frame_Start, &Frame_End, &Vertical_Offset);
ImVec2 Layer_LocalPos = ImVec2(Frame_Start, Vertical_Offset);
ImVec2 Layer_LocalSize = ImVec2(Frame_End - Frame_Start, Layer->Vertical_Height);
@@ -489,8 +1141,7 @@ ImGui_Timeline_DrawPrecomp(project_data *File, project_state *State, memory *Mem
if (ImGui::IsItemActivated()) {
if (!Layer->IsSelected) {
if (!io.KeyShift) Layer_DeselectAll(Memory, File->Layer_Count);
- State->MostRecentlySelectedLayer = i;
- Layer->IsSelected = true;
+ Layer_Select(Memory, State, Index_Physical);
}
}
if (ImGui::IsItemActive()) {
@@ -506,15 +1157,19 @@ ImGui_Timeline_DrawPrecomp(project_data *File, project_state *State, memory *Mem
}
if (ImGui::IsItemDeactivated()) {
if (State->Interact_Active == interact_type_layer_timeadjust) {
- for (int a = 0; a < File->Layer_Count; a++) {
- block_layer *Layer = (block_layer *)Memory_Block_AddressAtIndex(Memory, F_Layers, a);
- if (Layer->IsSelected) {
- Layer_Interact_Evaluate(Memory, State, Index_Physical, SortedCompInfo, SortedLayerInfo, &Layer->Frame_Start, &Layer->Frame_End, &Layer->Vertical_Offset);
- }
+ Assert(0);
+ /*
+ int h = 0, c = 0, i = 0;
+ 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) {
+ // Layer_Interact_Evaluate(Memory, State, Index_Physical, SortedCompInfo, SortedLayerInfo, &Layer->Frame_Start, &Layer->Frame_End, &Layer->Vertical_Offset);
+ // }
}
State->Interact_Active = interact_type_none;
State->Interact_Offset[0] = 0;
State->Interact_Offset[1] = 0;
+ */
}
}
@@ -527,8 +1182,7 @@ ImGui_Timeline_DrawPrecomp(project_data *File, project_state *State, memory *Mem
if (ImGui::IsItemActivated()) {
if (!Layer->IsSelected) {
if (!io.KeyShift) Layer_DeselectAll(Memory, File->Layer_Count);
- State->MostRecentlySelectedLayer = i;
- Layer->IsSelected = true;
+ Layer_Select(Memory, State, Index_Physical);
}
}
@@ -544,32 +1198,32 @@ ImGui_Timeline_DrawPrecomp(project_data *File, project_state *State, memory *Mem
ImVec2 DragDelta = ImGui::GetMouseDragDelta();
DragDelta = DragDelta + (ImVec2(UI->Warp_X, UI->Warp_Y) * TimelineSize);
- State->Interact_Offset[0] = (DragDelta.x / TimelineSizeWithBorder.x * UI->TimelinePercentZoomed.x) * Comp->Frame_Count;
- State->Interact_Offset[1] = (DragDelta.y / TimelineSizeWithBorder.y * UI->TimelinePercentZoomed.y) * LayerIncrement;
+ ImVec2 Offset_Old = ImVec2(State->Interact_Offset[0], State->Interact_Offset[1]);
+ ImVec2 Offset_New = (DragDelta / TimelineSizeWithBorder * UI->TimelinePercentZoomed) * ImVec2(Comp->Frame_Count, -LayerIncrement);
- /*
- if (UI->DragDelta_Prev.x != 0) {
- ImVec2 Offset_Old = (UI->DragDelta_Prev / TimelineSizeWithBorder * UI->TimelinePercentZoomed) * ImVec2(MainComp->Frame_Count, LayerIncrement);
- if ((int32)State->Interact_Offset[1] != (int32)Offset_Old.y)
- State->UpdateFrame = true;
- }
+ // if (((int32)Offset_Old.x != (int32)Offset_New.x) || ((int32)Offset_Old.y != (int32)Offset_New.y))
+ State->UpdateFrame = true;
- UI->DragDelta_Prev = DragDelta;
- */
+ State->Interact_Offset[0] = Offset_New.x;
+ State->Interact_Offset[1] = Offset_New.y;
}
}
if (ImGui::IsItemDeactivated()) {
if (State->Interact_Active == interact_type_layer_move) {
- for (int a = 0; a < File->Layer_Count; a++) {
- block_layer *Layer = (block_layer *)Memory_Block_AddressAtIndex(Memory, F_Layers, a);
+ History_Entry_Commit(Memory, "Move layers");
+ for (int i = 0; i < SortedCompInfo.LayerCount; i++)
+ {
+ sorted_layer SortEntry = SortedLayerInfo[i];
+ uint32 Index_Physical = SortEntry.Block_Layer_Index;
+ block_layer *Layer = (block_layer *)Memory_Block_AddressAtIndex(Memory, F_Layers, Index_Physical);
if (Layer->IsSelected) {
- Layer_Interact_Evaluate(Memory, State, Index_Physical, SortedCompInfo, SortedLayerInfo, &Layer->Frame_Start, &Layer->Frame_End, &Layer->Vertical_Offset);
+ History_Action_Swap(Memory, F_File, sizeof(Layer->Vertical_Offset), &Layer->Vertical_Offset);
+ Layer->Vertical_Offset = SortEntry.SortedOffset;
}
}
State->Interact_Active = interact_type_none;
- State->Interact_Offset[0] = 0;
- State->Interact_Offset[1] = 0;
+ History_Entry_End(Memory);
}
}
ImGui::PopID();
@@ -588,9 +1242,9 @@ ImGui_Timeline_DrawPrecomp(project_data *File, project_state *State, memory *Mem
int32 Frame_Start = Layer->Frame_Start;
int32 Frame_End = Layer->Frame_End;
- real32 Vertical_Offset = Layer->Vertical_Offset;
- if (Layer->IsSelected)
- Layer_Interact_Evaluate(Memory, State, Index_Physical, SortedCompInfo, SortedLayerInfo, &Frame_Start, &Frame_End, &Vertical_Offset);
+ real32 Vertical_Offset = SortEntry.SortedOffset;
+ // if (Layer->IsSelected)
+ // Layer_Interact_Evaluate(Memory, State, Index_Physical, SortedCompInfo, SortedLayerInfo, &Frame_Start, &Frame_End, &Vertical_Offset);
ImVec2 Layer_LocalPos = ImVec2(Frame_Start, Vertical_Offset);
ImVec2 Layer_LocalSize = ImVec2(Frame_End - Frame_Start, Layer->Vertical_Height);
@@ -643,9 +1297,9 @@ ImGui_Timeline_DrawPrecomp(project_data *File, project_state *State, memory *Mem
int32 Frame_Start = Layer->Frame_Start;
int32 Frame_End = Layer->Frame_End;
- real32 Vertical_Offset = Layer->Vertical_Offset;
- if (Layer->IsSelected)
- Layer_Interact_Evaluate(Memory, State, Index_Physical, SortedCompInfo, SortedLayerInfo, &Frame_Start, &Frame_End, &Vertical_Offset);
+ real32 Vertical_Offset = SortEntry.SortedOffset;
+ // if (Layer->IsSelected)
+ // Layer_Interact_Evaluate(Memory, State, Index_Physical, SortedCompInfo, SortedLayerInfo, &Frame_Start, &Frame_End, &Vertical_Offset);
ImVec2 Layer_LocalPos = ImVec2(Frame_Start, Vertical_Offset);
ImVec2 Layer_LocalSize = ImVec2(Frame_End - Frame_Start, Layer->Vertical_Height);
@@ -658,10 +1312,10 @@ ImGui_Timeline_DrawPrecomp(project_data *File, project_state *State, memory *Mem
ImU32 LayerColor = 0;
ImU32 BorderColor = 0;
if (UI->TimelineMode == timeline_mode_graph) {
- LayerColor = ImColor(Layer->Col[0], Layer->Col[1], Layer->Col[2], 0.2f);
+ LayerColor = ImColor(UI->LayerColors[Layer->ColIndex]);
BorderColor = ImColor(0.3, 0.3, 0.3, 1.0f);
} else {
- LayerColor = ImColor(Layer->Col[0], Layer->Col[1], Layer->Col[2], 1.0f);
+ LayerColor = ImColor(UI->LayerColors[Layer->ColIndex]);
BorderColor = ImColor(0.2, 0.2, 0.2, 1.0f);
}
@@ -680,7 +1334,7 @@ ImGui_Timeline_DrawPrecomp(project_data *File, project_state *State, memory *Mem
}
static void
-ImGui_Timeline(project_data *File, project_state *State, memory *Memory, ui *UI, ImGuiIO io)
+ImGui_Timeline(project_data *File, project_state *State, memory *Memory, ui *UI, ImGuiIO io, sorted_comp_info *SortedCompArray, sorted_layer *SortedLayerArray)
{
if (UI->TimelineMode == timeline_mode_graph)
ImGui_GraphInfo(File, State, Memory, UI, io);
@@ -745,16 +1399,10 @@ ImGui_Timeline(project_data *File, project_state *State, memory *Memory, ui *UI,
ImVec2 TimelineZoomSize = TimelineSizeWithBorder / UI->TimelinePercentZoomed;
ImVec2 TimelineMoveSize = TimelineSizeWithBorder * UI->TimelinePercentOffset / UI->TimelinePercentZoomed;
- ImGui_TimelineHorizontalIncrementDraw(UI, draw_list, TimelineSizeWithBorder, TimelineAbsolutePos, *MainComp, TimelineZoomSize, TimelineMoveSize);
+ ImGui_TimelineHorizontalIncrementDraw(State, UI, draw_list, TimelineSizeWithBorder, TimelineAbsolutePos, *MainComp, TimelineZoomSize, TimelineMoveSize);
ImVec2 Increment = ImVec2((real32)1 / MainComp->Frame_Count, (real32)1 / LayerIncrement);
- uint64 SortSize = (sizeof(sorted_comp_info) * File->Comp_Count) + (sizeof(sorted_layer) * File->Layer_Count);
- void *SortedArray = Memory_PushScratch(Memory, SortSize);
- Arbitrary_Zero((uint8 *)SortedArray, SortSize);
- sorted_comp_info *SortedCompArray = (sorted_comp_info *)SortedArray;
- sorted_layer *SortedLayerArray = (sorted_layer *)((uint8 *)SortedArray + (sizeof(sorted_comp_info) * File->Comp_Count));
- Layer_SortAll(Memory, SortedLayerArray, SortedCompArray, File->Layer_Count, File->Comp_Count);
ImGui_Timeline_DrawPrecomp(File, State, Memory, UI, io, draw_list, File->PrincipalCompIndex,
Increment, TimelineAbsolutePos, TimelineMoveSize, TimelineZoomSize,
@@ -772,8 +1420,6 @@ ImGui_Timeline(project_data *File, project_state *State, memory *Memory, ui *UI,
// Memory_PopScratch(Memory, Keyframe_SortSize);
}
- Memory_PopScratch(Memory, SortSize);
-
ImVec2 MouseDelta = io.MouseDelta / TimelineSize;
real32 BarHandleSize = FontHeight;
@@ -912,6 +1558,23 @@ ImGui_Timeline(project_data *File, project_state *State, memory *Memory, ui *UI,
bool32 LeftClick = ImGui::IsMouseDown(ImGuiMouseButton_Left);
bool32 RightClick = ImGui::IsMouseDown(ImGuiMouseButton_Right);
+ ImGui::OpenPopupOnItemClick("layercolor", ImGuiPopupFlags_MouseButtonRight);
+ if (ImGui::BeginPopup("layercolor")) {
+ ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(0.0f, 0.0f));
+ for (int c = 0; c < AmountOf(UI->LayerColors); c++) {
+ ImGui::PushID(c);
+ ImGui::PushStyleColor(ImGuiCol_Button, UI->LayerColors[c]);
+ real32 Size = ImGui::GetFontSize() * 2;
+ ImVec2 ColSize(Size, Size);
+ ImGui::Button("##test", ColSize);
+ if ((c+1) % 4) { ImGui::SameLine(); }
+ ImGui::PopStyleColor();
+ ImGui::PopID();
+ }
+ ImGui::PopStyleVar();
+ ImGui::EndPopup();
+ }
+
if (IsHovered && io.MouseWheel) {
real32 Increment = 0.1;
bool32 Direction = (io.MouseWheel > 0) ? 1 : -1;
@@ -936,8 +1599,9 @@ ImGui_Timeline(project_data *File, project_state *State, memory *Memory, ui *UI,
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);
+ int h = 0, c = 0, i = 0;
+ 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)
continue;
for (int h = 0; h < AmountOf(Layer->Property); h++) {
@@ -998,9 +1662,31 @@ ImGui_ProcessInputs(project_data *File, project_state *State, ui *UI, memory *Me
if (ImGui::IsKeyPressed(ImGuiKey_Q)) {
State->IsRunning = false;
}
- if (ImGui::IsKeyPressed(ImGuiKey_A)) {
+ if (ImGui::IsKeyPressed(ImGuiKey_W)) {
+ block_composition *MainComp = (block_composition *)Memory_Block_AddressAtIndex(Memory, F_Precomps, File->PrincipalCompIndex);
+ State->Frame_Current = ((State->Frame_Current - 1) < 0) ? 0 : State->Frame_Current - 1;
State->UpdateFrame = true;
}
+ if (ImGui::IsKeyPressed(ImGuiKey_E)) {
+ block_composition *MainComp = (block_composition *)Memory_Block_AddressAtIndex(Memory, F_Precomps, File->PrincipalCompIndex);
+ State->Frame_Current = ((State->Frame_Current + 1) >= MainComp->Frame_Count) ? 0 : State->Frame_Current + 1;
+ State->UpdateFrame = true;
+ }
+ if (ImGui::IsKeyPressed(ImGuiKey_X)) {
+ v4 Temp = UI->Color;
+ UI->Color = UI->AltColor;
+ UI->AltColor = Temp;
+ }
+
+ if (ImGui::IsKeyPressed(ImGuiKey_V)) {
+ State->Tool = tool_default;
+ }
+ if (ImGui::IsKeyPressed(ImGuiKey_B)) {
+ State->Tool = tool_brush;
+ }
+ if (ImGui::IsKeyPressed(ImGuiKey_T)) {
+ Interact_Transform_Begin(File, Memory, State, io.MousePos);
+ }
if (UI->TimelineMode == timeline_mode_graph) {
if (ImGui::IsKeyPressed(ImGuiKey_G)) {
State->Interact_Offset[2] = io.MousePos.x;
@@ -1031,22 +1717,174 @@ ImGui_ProcessInputs(project_data *File, project_state *State, ui *UI, memory *Me
State->IsPlaying ^= 1;
}
if (ImGui::IsKeyPressed(ImGuiKey_T)) {
- for (int a = 0; a < File->Layer_Count; a++) {
- block_layer *Layer = (block_layer *)Memory_Block_AddressAtIndex(Memory, F_Layers, a);
+ int h = 0, c = 0, i = 0;
+ 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 && Layer->IsPrecomp) {
Layer->Precomp_Toggled ^= 1;
}
}
}
+
+ if (ImGui::IsKeyPressed(ImGuiKey_Delete))
+ {
+ bool32 CommitAction = 0;
+ int h = 0, c = 0, i = 0;
+ int LayerCount = File->Layer_Count;
+ while (Block_Loop(Memory, F_Layers, LayerCount, &h, &c, &i)) {
+ block_layer *Layer = (block_layer *)Memory_Block_AddressAtIndex(Memory, F_Layers, i);
+ if (Layer->IsSelected) {
+ if (!CommitAction) {
+ History_Entry_Commit(Memory, "Delete source");
+ CommitAction = 1;
+ }
+ Layer_Delete(File, Memory, i);
+ }
+ }
+ if (CommitAction) {
+ History_Entry_End(Memory);
+ State->UpdateFrame = true;
+ State->MostRecentlySelectedLayer = -1;
+ }
+ }
+
#if DEBUG
- if (ImGui::IsKeyPressed(ImGuiKey_W))
+ if (ImGui::IsKeyPressed(ImGuiKey_1))
{
Debug.ToggleWindow ^= 1;
}
#endif
+ bool32 mod_key = io.ConfigMacOSXBehaviors ? io.KeySuper : io.KeyCtrl;
+ if (mod_key) {
+ /*
+ if (ImGui::IsKeyPressed(ImGuiKey_S)) {
+ if (io.KeyShift) {
+ State->ImGuiPopups = popup_saveas;
+ } else {
+ if (State->Context[0].Filename[0] == '\0') {
+ State->ImGuiPopups = popup_saveas;
+ } else {
+ if (File_SaveAs(State, Memory, 0, State->Context[0].Filename)) {
+ PostMsg(State, "File saved!");
+ } else {
+ PostMsg(State, "File save failed...");
+ }
+ }
+ }
+ }
+ if (ImGui::IsKeyPressed(ImGuiKey_N)) {
+ if (io.KeyShift)
+ State->ImGuiPopups = popup_newfile;
+ else
+ State->ImGuiPopups = popup_newlayer;
+ }
+ */
+ if (ImGui::IsKeyPressed(ImGuiKey_Z)) {
+ if (io.KeyShift) {
+ History_Redo(Memory);
+ State->UpdateFrame = true;
+ } else {
+ History_Undo(Memory);
+ State->UpdateFrame = true;
+ }
+ }
+ }
+
+}
+
+static void
+ImGui_Menu(project_data *File, project_state *State, ui *UI, memory *Memory, ImGuiIO io)
+{
+ bool open = true;
+ ImGui::Begin("Menu", &open, ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_MenuBar);
+ if (ImGui::BeginMenuBar())
+ {
+ if (ImGui::BeginMenu("File"))
+ {
+ if (ImGui::MenuItem("Save", "Ctrl+S"))
+ {
+ // if (File_SaveAs(State, Memory, 0, State->Context[0].Filename)) {
+ if (0) {
+ PostMsg(State, "File saved!");
+ } else {
+ PostMsg(State, "File save failed...");
+ }
+ }
+ /*
+ if (ImGui::MenuItem("New project file", "Ctrl+Shift+N"))
+ {
+ State->ImGuiPopups = popup_newfile;
+ }
+ if (ImGui::BeginMenu("Open file"))
+ {
+ ImGui::InputText("Filename", State->DummyName, 512);
+ if (ImGui::IsItemDeactivated() && ImGui::IsKeyPressed(ImGuiKey_Enter)) {
+ File_Open(State, Memory, State->DummyName);
+ State->Context[Index].UpdateFrame = true;
+ }
+ ImGui::EndMenu();
+ }
+ if (ImGui::MenuItem("Save as", "Ctrl+Shift+S"))
+ {
+ State->ImGuiPopups = popup_saveas;
+ }
+ */
+ ImGui::EndMenu();
+ }
+ if (ImGui::BeginMenu("Layer"))
+ {
+ if (ImGui::BeginMenu("Import source from file"))
+ {
+ ImGui::InputText("Path to image", State->DummyName2, 512);
+ if (ImGui::IsItemDeactivated() && ImGui::IsKeyPressed(ImGuiKey_Enter)) {
+ int SourceIndex = Source_Generate(File, State, Memory, (void *)State->DummyName2);
+ State->UpdateFrame = true;
+ }
+ ImGui::EndMenu();
+ }
+ /*
+ if (ImGui::MenuItem("New layer", "Ctrl+N"))
+ {
+ State->ImGuiPopups = popup_newlayer;
+ }
+ if (ImGui::BeginMenu("Layer from image path"))
+ {
+ ImGui::InputText("Path to image", State->DummyName2, 512);
+ if (ImGui::IsItemDeactivated() && ImGui::IsKeyPressed(ImGuiKey_Enter)) {
+ Layer_CreateFromFile(State, Memory, Index, State->DummyName2);
+ Layer_DeselectAll(State, File, &Context->UI);
+ layer_sorted Sorts = Layer_GetSortedList(State, File);
+ file_layer *Layer = (file_layer *)Sorts.Location[File->NumberOfLayers - 1];
+ Layer_Select(Layer, &Context->UI, File->NumberOfLayers - 1);
+ State->Context[Index].UpdateFrame = true;
+ }
+ ImGui::EndMenu();
+ }
+ if (ImGui::MenuItem("New adjustment layer", "Ctrl+Shift+Y"))
+ {
+ Layer_CreateAdjustment(State, Memory, Index);
+ }
+ if (ImGui::MenuItem("Duplicate layer", "Ctrl+Shift+Y"))
+ {
+ if (State->Context[Index].UI.MostRecentlySelectedLayer > -1)
+ Layer_Duplicate(State, Memory, Index, State->Context[Index].UI.MostRecentlySelectedLayer);
+ }
+ */
+ ImGui::EndMenu();
+ }
+ ImGui::EndMenuBar();
+ }
+
+ ImGui::End();
+}
+
+static void
+ImGui_Popups(project_state *State, ui *UI, memory *Memory, ImGuiIO io)
+{
}
+
#if 0
real32 MaxVal_Y = -10000;
real32 MinVal_Y = 10000;
@@ -1931,7 +2769,7 @@ ImGui_PropertiesPanel(project_data *File, project_state *State, ui *UI, memory *
static void
ImGui_Viewport(project_data File, project_state *State, ui *UI, memory *Memory, comp_buffer CompBuffer,
- ImGuiIO io, GLuint textureID)
+ ImGuiIO io, GLuint textureID, sorted_comp_info *SortedCompArray, sorted_layer *SortedLayerArray)
{
bool open = true;
ImGui::Begin("Viewport", &open, ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoScrollWithMouse);
@@ -2358,68 +3196,6 @@ ImGui_SlidingLayer(project_layer *Layer, real32 *DraggingThreshold, real32 Delta
}
static void
-ImGui_File(project_data *File, project_state *State, memory *Memory, ui *UI, ImGuiIO io)
-{
- ImGui::Begin("Files");
- ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / io.Framerate, io.Framerate);
-#if DEBUG
- if (State->DemoButton) {
- if (ImGui::Button("Generate demo scene")) {
- CreateDemoScene(File, State, Memory);
- State->UpdateKeyframes = true;
- State->UpdateFrame = true;
- State->DemoButton = false;
- }
- }
- if (State->GridButton) {
- ImGui::SameLine();
- if (ImGui::Button("Generate square grid")) {
- // CreateGrid(File, Memory);
- State->UpdateKeyframes = true;
- State->UpdateFrame = true;
- State->GridButton = false;
- }
- }
-#endif
- ImGui::Text("Sources:");
- for (int i = 0; i < File->NumberOfSources; i++) {
- 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[File->SourceSelected]);
- }
- ImGui::EndPopup();
- }
- static char Input[1024];
- ImGui::InputTextWithHint("##sourceinput", "Input file path of source...", Input, STRING_SIZE);
- if (ImGui::IsItemDeactivated() && ImGui::IsKeyPressed(ImGuiKey_Enter)) {
- Source_Generate(File, State, Memory, Input);
- }
-#if DEBUG
- for (int i = 0; i < Debug.Temp.WatchedProperties; i++) {
- if (Debug.Temp.DebugPropertyType[i] == d_float) {
- ImGui::Text("%s: %f", Debug.Temp.String[i], Debug.Temp.Val[i].f);
- } else if (Debug.Temp.DebugPropertyType[i] == d_int) {
- ImGui::Text("%s: %i", Debug.Temp.String[i], Debug.Temp.Val[i].i);
- } else if (Debug.Temp.DebugPropertyType[i] == d_uint) {
- ImGui::Text("%s: %u", Debug.Temp.String[i], Debug.Temp.Val[i].u);
- }
- }
- Debug.Temp = {};
-#endif
- ImGui::End();
-}
-
-static void
ImGui_EffectsPanel(project_data *File, project_state *State, memory *Memory, ui *UI, ImGuiIO io)
{
ImGui::Begin("Effects list", NULL);