#include "imgui.h" #if SPECIAL #include "main.h" #endif static void ImGui_File(project_data *File, project_state *State, memory *Memory, ImGuiIO io, sorted_comp_array *SortedCompArray, sorted_layer_array *SortedLayerArray) { ImGui::Begin("Files"); ImGui::Text("%s: %hu", "Layers", File->Layer_Count); if (ImGui::IsKeyPressed(ImGuiKey_Backspace)) { // TODO(fox): Delete sources code! /* 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); } 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::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")) { State->HotkeyInput = hotkey_newlayer_source; } ImGui::EndPopup(); } // if (!ImGui::IsWindowFocused(ImGuiFocusedFlags_ChildWindows)) // Source_DeselectAll(File, Memory); ImGui::End(); } static void 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; } const char *Name = (State->DuplicateMode & sortflag_up) ? "Up" : "Down"; if (ImGui::MenuItem(Name, NULL)) { State->DuplicateMode ^= sortflag_up; } Name = (State->DuplicateMode & sortflag_furthest) ? "Furthest" : "Above"; if (ImGui::MenuItem(Name, NULL)) { State->DuplicateMode ^= sortflag_furthest; } if (State->Tool == tool_default) { if (ImGui::MenuItem("All", NULL, (State->SelectionMode == 0))) { State->SelectionMode = 0; } if (ImGui::MenuItem("Exclude precomps", NULL, (State->SelectionMode == 1))) { State->SelectionMode = 1; } } if (State->Tool == tool_rectangle) { if (ImGui::MenuItem("Rect", NULL, (State->ShapeMode == 0))) { State->ShapeMode = 0; } if (ImGui::MenuItem("Ellipse", NULL, (State->ShapeMode == 1))) { State->ShapeMode = 1; } } 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); } } else if (State->Tool == tool_pen && State->MostRecentlySelectedLayer == -1) { // ImGui_Opt_Shape(&State->Pen.Opt); } #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); } } ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / io.Framerate, io.Framerate); #endif ImGui::End(); } #include "keybinds.h" static void ImGui_Key_GetUIInfo(key_entry KeyEntry, real32 KeySize, ImVec2 *Offset_ScreenPos, ImVec2 *KeyScreenSize) { ImVec2 Extra(0, 0); if (KeyEntry.Sector == 0) { if (KeyEntry.Offset.x != 0) { if (KeyEntry.Offset.y == 1) { Extra.x += 0.5; } if (KeyEntry.Offset.y == 2) { Extra.x += 0.75; } if (KeyEntry.Offset.y == 3) { Extra.x += 1.5; } } } *Offset_ScreenPos = ImVec2(KeySize, KeySize) * (SectorOffset[KeyEntry.Sector] + Extra + KeyEntry.Offset); *KeyScreenSize = (KeyEntry.WidthRatio > 0.0f) ? ImVec2(KeySize * KeyEntry.WidthRatio, KeySize) : ImVec2(KeySize, KeySize * -KeyEntry.WidthRatio); } inline void ImGui_DrawCenteredRect(ImDrawList *draw_list, ImVec2 Point, real32 Width, uint32 col) { ImVec2 MinPos = Point - ImVec2(Width/2, Width/2); ImVec2 MaxPos = Point + ImVec2(Width/2, Width/2); draw_list->AddRectFilled(MinPos, MaxPos, col); } static void ImGui_KeybindUI(project_data *File, project_state *State, ui *UI, memory *Memory, ImGuiIO io) { real32 KeySize = ImGui::GetFontSize()*2; real32 KeyboardWidth = KeySize * 23.5; real32 KeyboardHeight = KeySize * 7; ImVec2 WindowSize = ImGui::GetWindowSize(); ImVec2 WindowMinAbs = ImGui::GetWindowPos(); ImVec2 WindowMaxAbs = WindowMinAbs + WindowSize; ImVec2 KeyboardPos((WindowSize.x - KeyboardWidth) / 2, KeySize*2); ImDrawList* draw_list = ImGui::GetWindowDrawList(); ImVec2 SectorOffset[4] = { ImVec2(0, 1.25), ImVec2(0,0), ImVec2(15.25, 1.25), ImVec2(19.5, 1.25) }; ImGui::PushStyleColor(ImGuiCol_Button, IM_COL32(190, 0, 50, 180)); if (ImGui::Button("X")) ImGui::CloseCurrentPopup(); ImGui::PopStyleColor(); State->Split_KeybindUI.Split(draw_list, 2); State->Split_KeybindUI.SetCurrentChannel(draw_list, 1); // keyboard ImGui::PushStyleColor(ImGuiCol_Button, IM_COL32(0, 0, 0, 180)); for (int k = 0; k < AmountOf(KeyEntries); k++) { key_entry KeyEntry = KeyEntries[k]; ImVec2 Offset_ScreenPos(0,0); ImVec2 KeyScreenSize(0,0); ImGui_Key_GetUIInfo(KeyEntry, KeySize, &Offset_ScreenPos, &KeyScreenSize); if (KeyEntry.Name[0] != '\0') { ImGui::PushID(k); ImGui::SetCursorScreenPos(WindowMinAbs + KeyboardPos + Offset_ScreenPos); ImGui::Button(KeyEntry.Name, KeyScreenSize); ImGui::PopID(); } } ImGui::PopStyleColor(); State->Split_KeybindUI.SetCurrentChannel(draw_list, 0); // list ImVec2 SubwindowMinPos(WindowMinAbs + KeyboardPos + ImVec2(0, KeyboardHeight + KeySize)); ImVec2 SubwindowSize(KeyboardWidth, WindowSize.y - KeyboardHeight - KeySize*4); ImGui::SetCursorScreenPos(SubwindowMinPos); ImGui::BeginChild("Keybinds info", SubwindowSize); key_mode CurrentKeyMode = (key_mode)9999; for (int a = 0; a < AmountOf(ShortcutArray); a++) { shortcut_entry ShortcutEntry = ShortcutArray[a]; // header info if (CurrentKeyMode != ShortcutEntry.Mode) { ImGui::Dummy(ImVec2(1, KeySize)); CurrentKeyMode = ShortcutEntry.Mode; ImVec2 Size = ImGui::CalcTextSize(KeyModeTitles[CurrentKeyMode]); ImGui::SetCursorPosX(((SubwindowSize.x / 2) - (Size.x / 2))); ImGui::Text(KeyModeTitles[CurrentKeyMode]); ImGui::SetCursorPosX((SubwindowSize.x / 2) - (ImGui::CalcTextSize("-----").x / 2)); ImGui::TextColored(ImColor(UI->LayerColors[CurrentKeyMode]), "-----"); ImGui::Dummy(ImVec2(1, KeySize/4)); while (ShortcutEntry.Key == ImGuiKey_None) { ImVec2 Size = ImGui::CalcTextSize(ShortcutEntry.Name); ImGui::SetCursorPosX(((SubwindowSize.x / 2) - (Size.x / 2))); ImGui::Text(ShortcutEntry.Name); a++; ShortcutEntry = ShortcutArray[a]; } ImGui::Dummy(ImVec2(1, KeySize/2)); } // shortcut text + key Assert(ShortcutEntry.Key != ImGuiKey_None); key_entry KeyEntry = KeyEntries[ShortcutEntry.Key - ImGuiKey_Tab]; real32 Padding = KeySize; ImGui::Dummy(ImVec2(Padding, 1)); ImGui::SameLine(); ImGui::Text(ShortcutEntry.Name); ImGui::SameLine(); char buf[64]; if (ShortcutEntry.Mods == Mod_None) { sprintf(buf, "%s", KeyEntry.Name); } else if (ShortcutEntry.Mods == Mod_Shift) { sprintf(buf, "%s", KeyEntry.ShiftName); } else { sprintf(buf, "%s + %s", KeyModText[ShortcutEntry.Mods], KeyEntry.Name); } ImVec2 Size = ImGui::CalcTextSize(buf); ImGui::SetCursorPosX(SubwindowSize.x - Size.x - Padding*1.5); ImGui::Text(buf); // indicator on keyboard ImVec2 Offset_ScreenPos(0,0); ImVec2 KeyScreenSize(0,0); ImGui_Key_GetUIInfo(KeyEntry, KeySize, &Offset_ScreenPos, &KeyScreenSize); real32 ModeSliverSize = KeySize / key_mode_count; Offset_ScreenPos.x += (ShortcutEntry.Mode * ModeSliverSize); KeyScreenSize = ImVec2(ModeSliverSize, KeyScreenSize.y); ImVec2 MinPos = WindowMinAbs + KeyboardPos + Offset_ScreenPos; draw_list->AddRectFilled(MinPos, MinPos + KeyScreenSize, UI->LayerColors[CurrentKeyMode]); } ImGui::EndChild(); if (ImGui::IsKeyPressed(ImGuiKey_Escape)) { ImGui::CloseCurrentPopup(); } ImGui::EndPopup(); State->Split_KeybindUI.Merge(draw_list); } static void ImGui_Popups(project_data *File, project_state *State, ui *UI, memory *Memory, ImGuiIO io) { switch (State->ImGuiPopups) { case popup_none: { } break; case popup_saveas: { ImGui::OpenPopup("Save as"); ImGui::SetKeyboardFocusHere(); } break; case popup_keybinds: { ImGui::OpenPopup("Keybinds"); ImGui::SetNextWindowSize(ImVec2(700, 700)); ImGui::SetKeyboardFocusHere(); } break; default: { Assert(0); } } State->ImGuiPopups = popup_none; if (ImGui::BeginPopupModal("Save as")) { ImGui::Text("Destination path..."); ImGui::InputText("File", State->Filename, 512); if (ImGui::Button("Save file")) { ImGui::Text("Saving..."); File_SaveAs(File, State, Memory, State->Filename); ImGui::CloseCurrentPopup(); } if (ImGui::IsKeyPressed(ImGuiKey_Escape)) { ImGui::CloseCurrentPopup(); } ImGui::EndPopup(); } if (ImGui::BeginPopupModal("Keybinds")) { ImGui_KeybindUI(File, State, UI, Memory, io); } } static void ImGui_ProcessInputs(project_data *File, project_state *State, ui *UI, memory *Memory, ImGuiIO io, sorted_file Sorted) { if (ImGui::IsKeyPressed(ImGuiKey_Q)) { State->IsRunning = false; } 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; State->UpdateKeyframes = true; State->Interact_Transform = {}; if (State->UncommitedKeyframe) { Memory->PurgeCache = true; State->UncommitedKeyframe = false; } } if (ImGui::IsKeyPressed(ImGuiKey_E)) { if (!io.KeyShift) { 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; State->UpdateKeyframes = true; State->Interact_Transform = {}; if (State->UncommitedKeyframe) { Memory->PurgeCache = true; State->UncommitedKeyframe = false; } } else { State->Brush.EraseMode ^= 1; } } if (ImGui::IsKeyPressed(ImGuiKey_U)) { 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 & 0x01) { Layer_ToggleAllChannels(State, Memory, Layer, Sorted.CompArray, Sorted.LayerArray, Sorted.PropertyStart, Sorted.PropertyArray); } } } if (ImGui::IsKeyPressed(ImGuiKey_LeftBracket)) { Layer_Nudge(File, State, Memory, Sorted.CompArray, Sorted.LayerArray); } // if (ImGui::IsKeyPressed(ImGuiKey_RightBracket)) { // } if (ImGui::IsKeyPressed(ImGuiKey_GraveAccent)) { Layer_ApplyPreviousSelection(File, State, Memory); } if (ImGui::IsKeyPressed(ImGuiKey_X)) { if (State->TimelineMode == timeline_mode_graph && State->Interact_Active == interact_type_keyframe_move) { if (State->Interact_Modifier != 1) State->Interact_Modifier = 1; else State->Interact_Modifier = 0; } else if (io.KeyShift) { bool32 CommitAction = 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 & 0x01) && Layer->IsShapeLayer) { if (!CommitAction) { History_Entry_Commit(Memory, "Swap shape colors"); CommitAction = 1; } v4 Temp = Layer->ShapeOpt.FillCol; History_Action_Swap(Memory, F_Layers, sizeof(Layer->ShapeOpt.FillCol), &Layer->ShapeOpt.FillCol); Layer->ShapeOpt.FillCol = Layer->ShapeOpt.StrokeCol; History_Action_Swap(Memory, F_Layers, sizeof(Layer->ShapeOpt.StrokeCol), &Layer->ShapeOpt.StrokeCol); Layer->ShapeOpt.StrokeCol = Temp; } } if (CommitAction) { History_Entry_End(Memory); } } else { v4 Temp = UI->Color; UI->Color = UI->AltColor; UI->AltColor = Temp; } } if (ImGui::IsKeyPressed(ImGuiKey_Y)) { if (State->TimelineMode == timeline_mode_graph && State->Interact_Active == interact_type_keyframe_move) { if (State->Interact_Modifier != 2) State->Interact_Modifier = 2; else State->Interact_Modifier = 0; } } if (ImGui::IsKeyPressed(ImGuiKey_A)) { State->Tool = tool_default_pointmove; } if (ImGui::IsKeyPressed(ImGuiKey_V)) { State->Tool = tool_default; } if (ImGui::IsKeyPressed(ImGuiKey_B)) { State->Tool = tool_brush; } if (ImGui::IsKeyPressed(ImGuiKey_D)) { if (io.KeyShift && State->Interact_Active == interact_type_none) { State->HotkeyInput = hotkey_duplicatelayer; } else { State->Tool = tool_pen; } } // NOTE(fox): File data not tracked on undo tree! if (ImGui::IsKeyPressed(ImGuiKey_N)) { if (io.KeyShift) { block_composition *MainComp = (block_composition *)Memory_Block_AddressAtIndex(Memory, F_Precomps, File->PrincipalCompIndex); if (MainComp->Frame_Start < State->Frame_Current) MainComp->Frame_End = State->Frame_Current; } else { block_composition *MainComp = (block_composition *)Memory_Block_AddressAtIndex(Memory, F_Precomps, File->PrincipalCompIndex); if (MainComp->Frame_End > State->Frame_Current) MainComp->Frame_Start = State->Frame_Current; } } if (ImGui::IsKeyPressed(ImGuiKey_Tab)) { State->TimelineMode = (State->TimelineMode == timeline_mode_default) ? timeline_mode_graph : timeline_mode_default; UI->GraphZoomSize = ImVec2(0, 0); UI->GraphMoveSize = ImVec2(0, 0); } if (!io.KeyCtrl) { // NOTE(fox): Checking IsWindowHovered seems to be all we need to do to // make per-window hotkeys work; setting it as the focused window causes // problems with popups. if (State->FocusedWindow == focus_timeline) { if (State->TimelineMode == timeline_mode_default) { if (ImGui::IsKeyPressed(ImGuiKey_G)) { Layer_ToggleChannel(File, Memory, 0); Layer_ToggleChannel(File, Memory, 1); } else if (ImGui::IsKeyPressed(ImGuiKey_A)) { Layer_ToggleChannel(File, Memory, 2); Layer_ToggleChannel(File, Memory, 3); } else if (ImGui::IsKeyPressed(ImGuiKey_R)) { Layer_ToggleChannel(File, Memory, 4); } else if (ImGui::IsKeyPressed(ImGuiKey_S)) { Layer_ToggleChannel(File, Memory, 5); } else if (ImGui::IsKeyPressed(ImGuiKey_T)) { if (io.KeyShift) { Layer_ToggleChannel(File, Memory, 6); } else { Layer_ToggleChannel(File, Memory, 7); } } } else if (State->TimelineMode == timeline_mode_graph) { if (ImGui::IsKeyPressed(ImGuiKey_G)) { State->Interact_Offset[2] = io.MousePos.x; State->Interact_Offset[3] = io.MousePos.y; State->Interact_Active = interact_type_keyframe_move; } else if (ImGui::IsKeyPressed(ImGuiKey_R)) { // State->Interact_Offset[2] = io.MousePos.x; // State->Interact_Offset[3] = io.MousePos.y; // State->Interact_Active = interact_type_keyframe_rotate; } else if (ImGui::IsKeyPressed(ImGuiKey_S)) { State->Interact_Offset[2] = io.MousePos.x; State->Interact_Offset[3] = io.MousePos.y; State->Interact_Active = interact_type_keyframe_scale; } } } else if (State->FocusedWindow == focus_viewport) { /* if (ImGui::IsKeyPressed(ImGuiKey_S)) { State->Interact_Offset[1] = SDL_GetPerformanceCounter(); State->Interact_Offset[2] = io.MousePos.x; State->Interact_Offset[3] = io.MousePos.y; State->Interact_Active = interact_type_viewport_transform; } if (ImGui::IsKeyPressed(ImGuiKey_R)) { State->Interact_Offset[1] = SDL_GetPerformanceCounter(); State->Interact_Offset[2] = io.MousePos.x; State->Interact_Offset[3] = io.MousePos.y; State->Interact_Active = interact_type_viewport_transform; } */ } } if (ImGui::IsKeyPressed(ImGuiKey_Escape)) { if (State->Interact_Active == interact_type_keyframe_move || State->Interact_Active == interact_type_keyframe_rotate || State->Interact_Active == interact_type_keyframe_scale) { State->Interact_Offset[0] = 0; State->Interact_Offset[1] = 0; State->Interact_Offset[2] = 0; State->Interact_Offset[3] = 0; State->Interact_Active = interact_type_none; State->Interact_Modifier = 0; State->UpdateFrame = true; State->UpdateKeyframes = true; Memory->PurgeCache = true; } } if (ImGui::IsKeyPressed(ImGuiKey_Space) ) { if (io.KeyShift) { State->RerouteEffects = true; } else { State->IsPlaying ^= 1; State->HotFramePerf = 1; State->PlayAudio = false; State->FramePlayingCount = 0; if (State->UncommitedKeyframe) { Memory->PurgeCache = true; State->UncommitedKeyframe = false; } switch (SDL_GetAudioStatus()) { case SDL_AUDIO_STOPPED: Assert(0); break; case SDL_AUDIO_PLAYING: SDL_PauseAudio(1); break; case SDL_AUDIO_PAUSED: SDL_PauseAudio(0); break; default: Assert(0); break; } } } if (ImGui::IsKeyPressed(ImGuiKey_2)) { 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 & 0x01) || (Layer->IsSelected & 0x02)) && Layer->IsPrecomp) { Layer->Precomp_Toggled ^= 1; } } } if (ImGui::IsKeyPressed(ImGuiKey_Delete)) { State->HotkeyInput = hotkey_deletelayer; #if 0 if (State->FocusedWindow == focus_timeline) { Bezier_Delete_Selected(File, State, Memory, Sorted.LayerArray, Sorted.CompArray, Sorted.PropertyStart, Sorted.PropertyArray); } else { State->HotkeyInput = hotkey_deletelayer; } #endif } if (io.KeyShift && ImGui::IsKeyPressed(ImGuiKey_Slash)) { State->ImGuiPopups = popup_keybinds; } #if DEBUG if (ImGui::IsKeyPressed(ImGuiKey_3)) { // State->ImGuiPopups = popup_keybinds; Debug.DisableAlpha = 0; State->UpdateFrame = true; } if (ImGui::IsKeyPressed(ImGuiKey_4)) { Debug.DisableAlpha = 1; State->UpdateFrame = true; } if (ImGui::IsKeyPressed(ImGuiKey_5)) { Debug.DisableAlpha = 2; State->UpdateFrame = true; } if (ImGui::IsKeyPressed(ImGuiKey_F)) { sprintf(State->DummyName, "test2"); File_Open(File, State, Memory, State->DummyName); State->UpdateFrame = true; State->MostRecentlySelectedLayer = 0; } if (ImGui::IsKeyPressed(ImGuiKey_0)) { Debug.ReloadUI ^= 1; } 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->Filename[0] == '\0') { State->ImGuiPopups = popup_saveas; } else { File_SaveAs(File, State, Memory, State->Filename); } } } if (ImGui::IsKeyPressed(ImGuiKey_C)) { Clipboard_Store(File, State, Memory, Sorted.CompArray, Sorted.LayerArray, Sorted.PropertyStart, Sorted.PropertyArray); } if (ImGui::IsKeyPressed(ImGuiKey_V)) { Clipboard_Paste(File, State, Memory, Sorted.CompArray, Sorted.LayerArray, Sorted.PropertyArray); } if (ImGui::IsKeyPressed(ImGuiKey_Z)) { if (io.KeyShift) { State->HotkeyInput = hotkey_redo; } else { State->HotkeyInput = hotkey_undo; } } } } 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::IsWindowFocused()) { State->MenuFocused = 1; } if (ImGui::MenuItem("Save", "Ctrl+S")) { if (State->Filename[0] == '\0') State->ImGuiPopups = popup_saveas; else File_SaveAs(File, State, Memory, State->Filename); } if (ImGui::MenuItem("Save as", "Ctrl+Shift+S")) { State->ImGuiPopups = popup_saveas; } if (ImGui::BeginMenu("Open file")) { ImGui::InputText("Filename", State->DummyName, 512); if (ImGui::IsItemDeactivated() && ImGui::IsKeyPressed(ImGuiKey_Enter)) { if (File_Open(File, State, Memory, State->DummyName)) { State->UpdateFrame = true; } else { PostMsg(State, "File not found."); } } ImGui::EndMenu(); } ImGui::EndMenu(); } if (ImGui::BeginMenu("Layer")) { #if WINDOWS #else if (ImGui::BeginMenu("Import sources from directory")) { ImGui::InputText("Path to directory", State->DummyName2, 512); if (ImGui::IsItemDeactivated() && ImGui::IsKeyPressed(ImGuiKey_Enter)) { File_LoadDirectory(File, State, Memory, State->DummyName2); State->UpdateFrame = true; } ImGui::EndMenu(); } #endif 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(); } ImGui::EndMenu(); } if (ImGui::BeginMenu("Window")) { if (ImGui::BeginMenu("Background viewport color")) { ImGuiColorEditFlags flags_primary = ImGuiColorEditFlags_AlphaPreview | ImGuiColorEditFlags_Float; ImGuiColorEditFlags flags_picker = ImGuiColorEditFlags_PickerHueBar | ImGuiColorEditFlags_AlphaBar | ImGuiColorEditFlags_NoSmallPreview | ImGuiColorEditFlags_NoSidePreview | ImGuiColorEditFlags_DisplayRGB | ImGuiColorEditFlags_DisplayHSV | ImGuiColorEditFlags_DisplayHex; ImGui::ColorPicker4("##bgcolorpicker", &UI->BGColor.r, flags_primary | flags_picker); ImGui::EndMenu(); } if (ImGui::Selectable("Standard view", UI->Mode == 0)) UI->Mode = 0; if (ImGui::Selectable("Vector view", UI->Mode == 1)) UI->Mode = 1; if (ImGui::MenuItem("Clip viewport canvas", NULL, State->ViewportEnabled == 0)) State->ViewportEnabled ^= 1; #if STABLE if (ImGui::Selectable("Stable Diffusion tools", UI->StableEnabled)) UI->StableEnabled ^= 1; #endif ImGui::EndMenu(); } ImGui::EndMenuBar(); } ImGui::End(); } static void ImGui_EffectsPanel(project_data *File, project_state *State, memory *Memory, ui *UI, ImGuiIO io) { ImGui::Begin("Effects list", NULL); if (State->RerouteEffects) { ImGui::SetKeyboardFocusHere(); State->RerouteEffects = 0; } int value_changed = ImGui::InputText("Effect name...", State->filter.InputBuf, IM_ARRAYSIZE(State->filter.InputBuf), ImGuiInputTextFlags_CallbackCompletion, EffectConsoleCallback); if (Hacko) { if (!io.KeyShift) EffectSel++; else EffectSel--; Hacko = 0; } if (value_changed) { State->filter.Build(); EffectSel = -1; } // Enter conveniently deactivates the InputText field if (ImGui::IsItemDeactivated() && ImGui::IsKeyPressed(ImGuiKey_Enter)) { int32 p = 0; for (int32 i = 0; i < State->Playhead_Effect; i++) { header_effect *EffectHeader = &State->Effect[i]; if (State->filter.PassFilter(EffectHeader->Name)) { if (EffectSel == p && State->MostRecentlySelectedLayer != -1) { Effect_Add(File, State, Memory, i); State->UpdateFrame = true; } p++; } } EffectSel = -1; } int32 p = 0; for (int32 i = 0; i < State->Playhead_Effect; i++) { header_effect *EffectHeader = &State->Effect[i]; if (State->filter.PassFilter(EffectHeader->Name)) { bool t = false; if (EffectSel == p) { t = true; } ImGui::Selectable(EffectHeader->Name, &t); if (ImGui::IsItemClicked()) { if (ImGui::IsMouseDoubleClicked(ImGuiMouseButton_Left) && State->MostRecentlySelectedLayer != -1) { Effect_Add(File, State, Memory, i); State->UpdateFrame = true; } } p++; } } ImGui::End(); }