summaryrefslogtreecommitdiff
path: root/src/imgui_ui.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/imgui_ui.cpp')
-rw-r--r--src/imgui_ui.cpp664
1 files changed, 28 insertions, 636 deletions
diff --git a/src/imgui_ui.cpp b/src/imgui_ui.cpp
index 77a6712..1feb1e5 100644
--- a/src/imgui_ui.cpp
+++ b/src/imgui_ui.cpp
@@ -7,6 +7,7 @@
#include "imgui_ui_properties.cpp"
#include "imgui_ui_timeline.cpp"
+#include "imgui_ui_viewport.cpp"
#if DEBUG
#include "imgui_ui_debug.cpp"
@@ -92,7 +93,7 @@ ImGui_File(project_data *File, project_state *State, memory *Memory, ImGuiIO io,
if (ImGui::BeginPopup("sourcecontext")) {
if (ImGui::MenuItem("Create layer from source")) {
- State->HotkeyInput = hotkey_newlayerfromsource;
+ State->HotkeyInput = hotkey_newlayer_source;
}
ImGui::EndPopup();
}
@@ -115,6 +116,27 @@ ImGui_File(project_data *File, project_state *State, memory *Memory, ImGuiIO io,
ImGui::End();
}
+
+static void
+ImGui_Opt_Shape(shape_options *Opt)
+{
+ // TODO(fox): Combine with RGBA function?
+ char *Names[3] = { "Fill only", "Stroke only", "Fill and stroke" };
+ if (ImGui::BeginListBox("Shape render type")) {
+ for (int i = 0; i < 3; i++) {
+ if (ImGui::Selectable(Names[i], (Opt->Visibility == i))) {
+ Opt->Visibility = i;
+ }
+ }
+ ImGui::EndListBox();
+ }
+ ImGui::ColorEdit4("Fill color", (real32 *)&Opt->FillCol, ImGuiColorEditFlags_Float);
+ ImGui::ColorEdit4("Stroke color", (real32 *)&Opt->StrokeCol, ImGuiColorEditFlags_Float);
+ real32 StrokeWidthMin = 0;
+ real32 StrokeWidthMax = 1024;
+ ImGui::DragScalar("Stroke width", ImGuiDataType_Float, &Opt->StrokeWidth, 1, &StrokeWidthMin, &StrokeWidthMax, "%.3f");
+}
+
static void
ImGui_ColorPanel(project_data *File, project_state *State, ui *UI, memory *Memory, ImGuiIO io)
{
@@ -173,646 +195,13 @@ ImGui_ColorPanel(project_data *File, project_state *State, ui *UI, memory *Memor
Brush_CalcBitmapAlphaFromSize(Memory, &State->Brush, 4);
State_BindBrushTexture(Memory, &State->Brush, 4);
}
+ } else if (State->Tool == tool_pen && State->MostRecentlySelectedLayer == -1) {
+ ImGui_Opt_Shape(&State->Pen.Opt);
}
ImGui::End();
}
-static void
-ImGui_Viewport_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_Viewport_BrushUI(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.KeyCtrl) {
- // ImGui::SetCursorScreenPos(State->Brush.UIPos);
- // char buf[256];
- // sprintf(buf, "RGBA: %.1f, %.1f, %.1f, %.1f", State->Brush.Size, State->Brush.Hardness);
- // }
-
- 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_Viewport_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, uint16 *SortedKeyframeArray)
-{
- 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->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;
- }
-
- // 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 (!State->InteractTransformMode && ImGui::IsMouseClicked(ImGuiMouseButton_Left) && InBounds && !OtherActions)
- 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))
- State->InteractTransformMode = 0;
- }
-
- if (ImGui::IsKeyPressed(ImGuiKey_Escape)) {
- State->Interact_Active = interact_type_none;
- State->Interact_Modifier = 0;
- State->UpdateFrame = true;
- Memory->PurgeCache = 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;
- 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 {
- 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);
- }
- }
- }
- if (!io.KeyCtrl)
- History_Entry_End(Memory);
- State->Interact_Active = interact_type_none;
- State->Interact_Modifier = 0;
- State->UncommitedKeyframe = 1;
- State->UpdateFrame = true;
- }
-
- if (InBounds == true) {
- ImGui::PopStyleColor();
- }
-
-}
-
-static void
-ImGui_Viewport_SelectedLayerUI(project_state *State, memory *Memory, ui *UI, ImDrawList *draw_list, block_composition *MainComp, uint32 CompIndex, block_layer *ParentLayer[4], uint32 Recursions,
- 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);
- for (int i = 0; i < SortedCompStart->LayerCount; i++)
- {
- sorted_layer_array SortEntry = SortedLayerStart[i];
- uint32 Index_Physical = SortEntry.Block_Layer_Index;
- block_layer *Layer = (block_layer *)Memory_Block_AddressAtIndex(Memory, F_Layers, Index_Physical);
- if (Layer->IsPrecomp) {
- ParentLayer[Recursions] = Layer;
- ImGui_Viewport_SelectedLayerUI(State, Memory, UI, draw_list, MainComp, Layer->Block_Source_Index, ParentLayer, Recursions + 1, SortedCompArray, SortedLayerArray);
- }
- if (Layer->IsSelected) {
- uint32 Width = 0, Height = 0;
- if (!Layer->IsPrecomp) {
- block_source *Source = (block_source *)Memory_Block_AddressAtIndex(Memory, F_Sources, Layer->Block_Source_Index);
- Width = Source->Width;
- Height = Source->Height;
- } else {
- block_composition *Comp = (block_composition *)Memory_Block_AddressAtIndex(Memory, F_Precomps, Layer->Block_Source_Index);
- Width = Comp->Width;
- Height = Comp->Height;
- }
-
- v2 Point[5] = { V2(Width*Layer->ax.CurrentValue, Height*Layer->ay.CurrentValue), V2(0, 0), V2(Width, 0), V2(0, Height), V2(Width, Height) };
-
- layer_transforms T = Layer_GetTransforms(Layer);
-
- if (State->Interact_Active == interact_type_viewport_transform && Layer->IsSelected == 1) {
- Transform_ApplyInteractive(*(interact_transform *)&State->Interact_Offset[0], &T.x, &T.y, &T.rotation, &T.scale);
- }
-
- v2 NewPos[5];
- for (int i = 0; i < 5; i++) {
- NewPos[i] = TransformPoint(T, Width, Height, Point[i]);
- }
-
- int i = 0;
- while (i < Recursions) {
- T = Layer_GetTransforms(ParentLayer[i]);
- block_composition *Comp = (block_composition *)Memory_Block_AddressAtIndex(Memory, F_Precomps, ParentLayer[i]->Block_Source_Index);
- Width = Comp->Width;
- Height = Comp->Height;
- for (int i = 0; i < 5; i++) {
- NewPos[i] = TransformPoint(T, Width, Height, NewPos[i]);
- }
- i++;
- }
-
- ImVec2 ScreenPoint[5];
- for (int i = 0; i < 5; i++) {
- v2 CompUV = NewPos[i] / V2(MainComp->Width, MainComp->Height);
-
- ScreenPoint[i] = ImVec2(UI->CompPos.x + CompUV.x * UI->CompZoom.x,
- UI->CompPos.y + CompUV.y * UI->CompZoom.y);
-
- }
- if (State->Tool != tool_brush) {
- ImU32 wcol2 = IM_COL32(10, 10, 10, 255);
- 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, 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);
- }
- }
-}
-
-static void
-ImGui_Viewport(project_data *File, project_state *State, ui *UI, memory *Memory, ImGuiIO io, GLuint textureID,
- sorted_comp_array *SortedCompArray, sorted_layer_array *SortedLayerArray, uint16 *SortedKeyframeArray)
-{
- bool open = true;
- ImGui::Begin("Viewport", &open, ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoScrollWithMouse);
-
-
- if (ImGui::IsWindowHovered(ImGuiFocusedFlags_ChildWindows)) {
- State->FocusedWindow = focus_viewport;
- }
-
- block_composition *MainComp = (block_composition *)Memory_Block_AddressAtIndex(Memory, F_Precomps, File->PrincipalCompIndex);
-
- ImVec2 ViewportMin = ImGui::GetCursorScreenPos();
- ImVec2 ViewportScale = ImGui::GetContentRegionAvail();
- ImVec2 ViewportMax = ImVec2(ViewportMin.x + ViewportScale.x, ViewportMin.y + ViewportScale.y);
-
- if (ViewportScale.x < 50 || ViewportScale.y < 50) {
- ImGui::End();
- return;
- }
-
- if (State->Initializing) {
- UI->CompZoom = ImVec2(MainComp->Width, MainComp->Height);
- UI->CompPos = ImVec2(ViewportMin.x + ((ViewportMax.x - ViewportMin.x)/2 - UI->CompZoom.x/2),
- ViewportMin.y + ((ViewportMax.y - ViewportMin.y)/2 - UI->CompZoom.y/2));
- }
-
- ImVec2 CompPosMin = ImVec2(UI->CompPos.x, UI->CompPos.y);
- ImVec2 CompPosMax = ImVec2(UI->CompPos.x + UI->CompZoom.x, UI->CompPos.y + UI->CompZoom.y);
-
- ImDrawList* draw_list = ImGui::GetWindowDrawList();
- draw_list->AddRectFilled(ViewportMin, ViewportMax, IM_COL32(50, 50, 50, 255));
- draw_list->AddRect(ViewportMin, ViewportMax, IM_COL32(255, 255, 255, 255));
- draw_list->AddRect(CompPosMin, CompPosMax, IM_COL32(255, 255, 255, 55));
-
- real32 FontSize = ImGui::GetFontSize();
- ImGui::SetCursorScreenPos(ImVec2(ViewportMax.x - FontSize*2, ViewportMin.y + ViewportScale.y - FontSize*3.0));
- ImGui::PushStyleColor(ImGuiCol_Button, IM_COL32(0, 0, 0, 80));
- if (ImGui::Button("?"))
- State->ImGuiPopups = popup_keybinds;
- ImGui::PopStyleColor();
-
-
- // Actual composition texture
- draw_list->PushClipRect(ViewportMin, ViewportMax, true);
- draw_list->AddImage((void *)(intptr_t)textureID, CompPosMin, CompPosMax);
- draw_list->PopClipRect();
-
- // UI+interaction for layer
- if (State->MostRecentlySelectedLayer > -1)
- {
- block_layer *ParentLayer[4];
- ImGui_Viewport_SelectedLayerUI(State, Memory, UI, draw_list, MainComp, File->PrincipalCompIndex, ParentLayer, 0, SortedCompArray, SortedLayerArray);
- if (State->Interact_Active == interact_type_viewport_transform) {
- ImGui_Viewport_TransformUI(File, State, Memory, UI, draw_list, io, (interact_transform *)&State->Interact_Offset[0], ViewportMin, MainComp->Width, MainComp->Height, SortedKeyframeArray);
- }
- }
-
-
-
- // Interactions for dragging and zooming
- ImGui::SetCursorScreenPos(ViewportMin);
-
- ImGui::InvisibleButton("canvas", ViewportScale, ImGuiButtonFlags_MouseButtonLeft | ImGuiButtonFlags_MouseButtonRight);
- bool32 IsHovered = ImGui::IsItemHovered();
-#if 1
- bool32 IsActive = ImGui::IsItemActive();
- bool32 IsActivated = ImGui::IsItemActivated();
- bool32 IsDeactivated = ImGui::IsItemDeactivated();
-#else
- bool32 IsActive = ImGui::IsKeyDown(ImGuiKey_3);
- bool32 IsActivated = ImGui::IsKeyPressed(ImGuiKey_3);
- bool32 IsDeactivated = ImGui::IsKeyReleased(ImGuiKey_3);
-#endif
-
- if (IsHovered && IsActivated && !ImGui::IsMouseDown(ImGuiMouseButton_Right))
- {
- // Point to zoom in on if Z is held
- State->TempZoomRatio = ImGui_ScreenPointToCompUV(ViewportMin, UI->CompPos, UI->CompZoom, io.MousePos);
-
- if (State->Tool == tool_brush && State->Interact_Active != interact_type_brush && !ImGui::IsKeyDown(ImGuiKey_Z)) {
- if (!io.KeyCtrl) {
- 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->IsPrecomp) {
- block_source *Source = (block_source *)Memory_Block_AddressAtIndex(Memory, F_Sources, Layer->Block_Source_Index);
- if (Layer->IsSelected && Source->Type == source_type_principal) {
- Assert(Source->BytesPerPixel == 4);
- Arbitrary_Zero((uint8 *)State->Brush.TransientBitmap, 2048*2048*4);
- State->Interact_Active = interact_type_brush;
- State->Brush.LayerToPaint_Index = i;
- break;
- }
- }
- }
- }
- if (State->Brush.LayerToPaint_Index == -1) {
- State->HotkeyInput = hotkey_newpaintlayer;
- }
- }
-
- // Layer selection
- 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(File, State, Memory);
- 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 && State->Interact_Active == interact_type_brush) {
- Assert(State->Brush.LayerToPaint_Index != -1);
- if (IsActive && !OtherActions) {
- block_layer *Layer = (block_layer *)Memory_Block_AddressAtIndex(Memory, F_Layers, State->Brush.LayerToPaint_Index);
- layer_transforms T_Layer = Layer_GetTransforms(Layer);
- block_source *Source = (block_source *)Memory_Block_AddressAtIndex(Memory, F_Sources, Layer->Block_Source_Index);
- ImVec2 MouseDelta = io.MouseDelta;
- real32 Delta = MouseDelta.x + MouseDelta.y;
- v2 PrincipalCompUV = ImGui_ScreenPointToCompUV(ViewportMin, UI->CompPos, UI->CompZoom, io.MousePos);
- v2 LayerPos = Layer_TraverseForPoint(File, State, Memory, PrincipalCompUV, SortedCompArray, SortedLayerArray);
- if (IsActivated) {
- RenderQueue_AddBrush(State, LayerPos);
- } else if (Delta != 0.0f) {
- v2 PrevPos = State->Brush.PrevPos;
- v2 Delta = PrevPos - LayerPos;
- real32 Dist = sqrt(LengthSq(Delta));
- if (Dist > State->Brush.Spacing) {
- RenderQueue_AddBrush(State, LayerPos);
- }
- }
- State->UpdateFrame = true;
- }
-
- if (IsDeactivated) {
- RenderQueue_AddBlit(State);
- }
- }
-
- if (ImGui::IsKeyDown(ImGuiKey_Z) && ImGui::IsWindowHovered()) {
- if (IsActive)
- ImGui::SetMouseCursor(ImGuiMouseCursor_ResizeAll);
- else
- ImGui::SetMouseCursor(ImGuiMouseCursor_Hand);
- }
-
- real32 Distance = 0;
- if (IsActive) {
- if (ImGui::IsMouseDragging(ImGuiMouseButton_Left, -1.0f))
- Distance = io.MouseDelta.x + io.MouseDelta.y;
- if (ImGui::IsMouseDoubleClicked(ImGuiMouseButton_Left))
- Distance = 200;
- }
- if (Distance && ImGui::IsKeyDown(ImGuiKey_Z))
- {
- if (io.KeyShift)
- Distance *= -1;
- UI->CompZoom.x += (Distance)*(real32)MainComp->Width/MainComp->Height;
- UI->CompZoom.y += (Distance);
- UI->CompPos.x -= ((Distance)*(real32)MainComp->Width/MainComp->Height)*State->TempZoomRatio.x;
- UI->CompPos.y -= Distance*State->TempZoomRatio.y;
- }
-
- ImGui::SetCursorScreenPos(ImVec2(ViewportMin.x, ViewportMin.y + ViewportScale.y - FontSize*1.5));
-
- ImGui::Text("%.1f", 100.0f * (UI->CompZoom.x / MainComp->Width));
- if (State->MsgTime > 0) {
- ImGui::SameLine();
- ImGui::SetCursorPosX((ViewportScale.x / 5)*4);
- ImGui::Text(State->Msg);
- State->MsgTime--;
- }
-
- ImGui::SetCursorScreenPos(ViewportMin);
- ImGui_Viewport_Toolbar(State, draw_list);
- ImGui_Viewport_BrushUI(State, Memory, ViewportMin, ViewportMax, UI->CompPos, io, MainComp->Width, MainComp->Height);
-
- ImGui::End();
-}
-
#include "keybinds.h"
static void
@@ -1051,6 +440,9 @@ ImGui_ProcessInputs(project_data *File, project_state *State, ui *UI, memory *Me
if (ImGui::IsKeyPressed(ImGuiKey_B)) {
State->Tool = tool_brush;
}
+ if (ImGui::IsKeyPressed(ImGuiKey_D)) {
+ State->Tool = tool_pen;
+ }
// NOTE(fox): File data not tracked on undo tree!
if (ImGui::IsKeyPressed(ImGuiKey_N)) {
if (io.KeyShift) {