// js/main.js import { appState, resetProjectState } from "./state.js"; import { addTrackToState, removeLastTrackFromState } from "./pattern/pattern_state.js"; // --- CORREÇÃO AQUI --- import { toggleRecording } from "./recording.js"; import { addAudioTrackLane, removeAudioClip } from "./audio/audio_state.js"; import { updateTransportLoop } from "./audio/audio_audio.js"; import { togglePlayback, stopPlayback, rewindPlayback, } from "./pattern/pattern_audio.js"; import { startAudioEditorPlayback, stopAudioEditorPlayback, restartAudioEditorIfPlaying, } from "./audio/audio_audio.js"; import { initializeAudioContext } from "./audio.js"; import { handleFileLoad, generateMmpFile } from "./file.js"; import { renderAll, loadAndRenderSampleBrowser, showOpenProjectModal, closeOpenProjectModal } from "./ui.js"; import { renderAudioEditor } from "./audio/audio_ui.js"; import { adjustValue, enforceNumericInput } from "./utils.js"; import { ZOOM_LEVELS } from "./config.js"; // --- NOVA FUNÇÃO --- // Atualiza a aparência dos botões de ferramenta function updateToolButtons() { const sliceToolBtn = document.getElementById("slice-tool-btn"); const trimToolBtn = document.getElementById("resize-tool-trim"); const stretchToolBtn = document.getElementById("resize-tool-stretch"); if(sliceToolBtn) sliceToolBtn.classList.toggle("active", appState.global.sliceToolActive); if(trimToolBtn) trimToolBtn.classList.toggle("active", !appState.global.sliceToolActive && appState.global.resizeMode === 'trim'); if(stretchToolBtn) stretchToolBtn.classList.toggle("active", !appState.global.sliceToolActive && appState.global.resizeMode === 'stretch'); // Desativa a ferramenta de corte se outra for selecionada document.body.classList.toggle("slice-tool-active", appState.global.sliceToolActive); } document.addEventListener("DOMContentLoaded", () => { const newProjectBtn = document.getElementById("new-project-btn"); const openMmpBtn = document.getElementById("open-mmp-btn"); const saveMmpBtn = document.getElementById("save-mmp-btn"); const uploadSampleBtn = document.getElementById("upload-sample-btn"); const addInstrumentBtn = document.getElementById("add-instrument-btn"); const removeInstrumentBtn = document.getElementById("remove-instrument-btn"); const playBtn = document.getElementById("play-btn"); const stopBtn = document.getElementById("stop-btn"); const audioEditorPlayBtn = document.getElementById("audio-editor-play-btn"); const audioEditorStopBtn = document.getElementById("audio-editor-stop-btn"); const audioEditorLoopBtn = document.getElementById("audio-editor-loop-btn"); const addAudioTrackBtn = document.getElementById("add-audio-track-btn"); const rewindBtn = document.getElementById("rewind-btn"); const metronomeBtn = document.getElementById("metronome-btn"); const sliceToolBtn = document.getElementById("slice-tool-btn"); // --- NOVOS BOTÕES --- const resizeToolTrimBtn = document.getElementById("resize-tool-trim"); const resizeToolStretchBtn = document.getElementById("resize-tool-stretch"); const recordBtn = document.getElementById("record-btn"); const mmpFileInput = document.getElementById("mmp-file-input"); const sampleFileInput = document.getElementById("sample-file-input"); const openProjectModal = document.getElementById("open-project-modal"); const openModalCloseBtn = document.getElementById("open-modal-close-btn"); const loadFromComputerBtn = document.getElementById("load-from-computer-btn"); const sidebarToggle = document.getElementById("sidebar-toggle"); const addBarBtn = document.getElementById("add-bar-btn"); const zoomInBtn = document.getElementById("zoom-in-btn"); const zoomOutBtn = document.getElementById("zoom-out-btn"); // --- LISTENERS ADICIONADOS (COM LÓGICA DE CONTROLLER) --- // --- NOVO LISTENER PARA O BOTÃO DE GRAVAR --- if (recordBtn) { recordBtn.addEventListener("click", () => { // Garante que o contexto de áudio foi iniciado por um gesto do usuário initializeAudioContext(); toggleRecording(); }); } // Listener para o botão "Excluir Clipe" no menu de contexto const deleteClipBtn = document.getElementById('delete-clip'); if (deleteClipBtn) { deleteClipBtn.addEventListener('click', () => { const clipId = appState.global.selectedClipId; // 1. Lê o estado if (clipId) { if (removeAudioClip(clipId)) { // 2. Chama a função de state appState.global.selectedClipId = null; // 3. Atualiza o estado global renderAudioEditor(); // 4. Renderiza a mudança } } // Esconde o menu const menu = document.getElementById('timeline-context-menu'); if (menu) menu.style.display = 'none'; }); } // Listener global para a tecla Delete/Backspace document.addEventListener('keydown', (e) => { // Ignora se estiver digitando em um input if (e.target.tagName === 'INPUT' || e.target.tagName === 'TEXTAREA') { return; } const clipId = appState.global.selectedClipId; // 1. Lê o estado // Verifica se há um clipe selecionado e a tecla pressionada é Delete ou Backspace if ((e.key === 'Delete' || e.key === 'Backspace') && clipId) { e.preventDefault(); // Impede o navegador de voltar a página (ação do Backspace) if (removeAudioClip(clipId)) { // 2. Chama a função de state appState.global.selectedClipId = null; // 3. Atualiza o estado global renderAudioEditor(); // 4. Renderiza a mudança } } }); // Listener global para fechar menu de contexto ou desselecionar clipe document.addEventListener('click', (e) => { // Esconde o menu de contexto se clicar fora dele const menu = document.getElementById('timeline-context-menu'); if (menu && !e.target.closest('#timeline-context-menu')) { menu.style.display = 'none'; } }); // --- FIM DOS LISTENERS ADICIONADOS --- newProjectBtn.addEventListener("click", () => { if ((appState.pattern.tracks.length > 0 || appState.audio.clips.length > 0) && !confirm("Você tem certeza? Alterações não salvas serão perdidas.")) return; resetProjectState(); document.getElementById('bpm-input').value = 140; document.getElementById('bars-input').value = 1; document.getElementById('compasso-a-input').value = 4; document.getElementById('compasso-b-input').value = 4; const titleElement = document.getElementById('beat-bassline-title'); if(titleElement) titleElement.textContent = 'Novo Projeto'; renderAll(); }); addBarBtn.addEventListener("click", () => { const barsInput = document.getElementById("bars-input"); if (barsInput) adjustValue(barsInput, 1); }); openMmpBtn.addEventListener("click", showOpenProjectModal); loadFromComputerBtn.addEventListener("click", () => mmpFileInput.click()); mmpFileInput.addEventListener("change", (event) => { const file = event.target.files[0]; if (file) { handleFileLoad(file).then(() => closeOpenProjectModal()); } }); uploadSampleBtn.addEventListener("click", () => sampleFileInput.click()); saveMmpBtn.addEventListener("click", generateMmpFile); addInstrumentBtn.addEventListener("click", addTrackToState); removeInstrumentBtn.addEventListener("click", removeLastTrackFromState); playBtn.addEventListener("click", togglePlayback); stopBtn.addEventListener("click", stopPlayback); rewindBtn.addEventListener("click", rewindPlayback); metronomeBtn.addEventListener("click", () => { initializeAudioContext(); appState.global.metronomeEnabled = !appState.global.metronomeEnabled; metronomeBtn.classList.toggle("active", appState.global.metronomeEnabled); }); // --- LISTENERS DE FERRAMENTAS ATUALIZADOS --- if(sliceToolBtn) { sliceToolBtn.addEventListener("click", () => { appState.global.sliceToolActive = !appState.global.sliceToolActive; updateToolButtons(); }); } if(resizeToolTrimBtn) { resizeToolTrimBtn.addEventListener("click", () => { appState.global.resizeMode = 'trim'; appState.global.sliceToolActive = false; updateToolButtons(); }); } if(resizeToolStretchBtn) { resizeToolStretchBtn.addEventListener("click", () => { appState.global.resizeMode = 'stretch'; appState.global.sliceToolActive = false; updateToolButtons(); }); } openModalCloseBtn.addEventListener("click", closeOpenProjectModal); sidebarToggle.addEventListener("click", () => { document.body.classList.toggle("sidebar-hidden"); const icon = sidebarToggle.querySelector("i"); if (icon) { icon.className = document.body.classList.contains("sidebar-hidden") ? "fa-solid fa-caret-right" : "fa-solid fa-caret-left"; } }); const inputs = document.querySelectorAll(".value-input"); inputs.forEach((input) => { input.addEventListener("input", (event) => { enforceNumericInput(event); if (appState.global.isPlaying && (event.target.id.startsWith("compasso-") || event.target.id === 'bars-input')) { stopPlayback(); } if (event.target.id.startsWith("compasso-") || event.target.id === 'bars-input' || event.target.id === 'bpm-input') { renderAll(); } }); input.addEventListener("wheel", (event) => { event.preventDefault(); const step = event.deltaY < 0 ? 1 : -1; adjustValue(event.target, step); }); }); const buttons = document.querySelectorAll(".adjust-btn"); buttons.forEach((button) => { button.addEventListener("click", () => { const targetId = button.dataset.target + "-input"; const targetInput = document.getElementById(targetId); const step = parseInt(button.dataset.step, 10) || 1; if (targetInput) { adjustValue(targetInput, step); } }); }); if (zoomInBtn) { zoomInBtn.addEventListener("click", () => { if (appState.global.zoomLevelIndex < ZOOM_LEVELS.length - 1) { appState.global.zoomLevelIndex++; renderAll(); } }); } if (zoomOutBtn) { zoomOutBtn.addEventListener("click", () => { if (appState.global.zoomLevelIndex > 0) { appState.global.zoomLevelIndex--; renderAll(); } }); } audioEditorPlayBtn.addEventListener("click", () => { if (appState.global.isAudioEditorPlaying) { stopAudioEditorPlayback(false); // Pausa } else { startAudioEditorPlayback(); } }); audioEditorStopBtn.addEventListener("click", () => stopAudioEditorPlayback(true)); // Stop (rebobina) audioEditorLoopBtn.addEventListener("click", () => { appState.global.isLoopActive = !appState.global.isLoopActive; appState.audio.isAudioEditorLoopEnabled = appState.global.isLoopActive; audioEditorLoopBtn.classList.toggle("active", appState.global.isLoopActive); updateTransportLoop(); const loopArea = document.getElementById("loop-region"); if (loopArea) { loopArea.classList.toggle("visible", appState.global.isLoopActive); } restartAudioEditorIfPlaying(); }); if (addAudioTrackBtn) { addAudioTrackBtn.addEventListener("click", () => { addAudioTrackLane(); renderAudioEditor(); }); } loadAndRenderSampleBrowser(); const browserContent = document.getElementById('browser-content'); if (browserContent) { browserContent.addEventListener('click', function(event) { const folderName = event.target.closest('.folder-name'); if (folderName) { const folderItem = folderName.parentElement; folderItem.classList.toggle('open'); } }); } renderAll(); updateToolButtons(); // Define o estado inicial dos botões });