versão 2.0.1 - Correção do grid (Editor de Samples), loop, delete, resize, trim e streching funcionais
This commit is contained in:
1 parent
352ceecec8
commit
b3f0d13b90
9 files changed
+856
-250
No files matched your search
+103
-31
@@ -1,7 +1,8 @@
|
||||
// js/main.js
|
||||
import { appState, resetProjectState } from "./state.js";
|
||||
import { addTrackToState, removeLastTrackFromState } from "./pattern/pattern_state.js";
|
||||
import { addAudioTrackLane } from "./audio/audio_state.js";
|
||||
// --- CORREÇÃO AQUI ---
|
||||
import { addAudioTrackLane, removeAudioClip } from "./audio/audio_state.js";
|
||||
import { updateTransportLoop } from "./audio/audio_audio.js";
|
||||
import {
|
||||
togglePlayback,
|
||||
@@ -20,6 +21,21 @@ 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");
|
||||
@@ -36,6 +52,11 @@ document.addEventListener("DOMContentLoaded", () => {
|
||||
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 mmpFileInput = document.getElementById("mmp-file-input");
|
||||
const sampleFileInput = document.getElementById("sample-file-input");
|
||||
const openProjectModal = document.getElementById("open-project-modal");
|
||||
@@ -46,6 +67,55 @@ document.addEventListener("DOMContentLoaded", () => {
|
||||
const zoomInBtn = document.getElementById("zoom-in-btn");
|
||||
const zoomOutBtn = document.getElementById("zoom-out-btn");
|
||||
|
||||
// --- LISTENERS ADICIONADOS (COM LÓGICA DE CONTROLLER) ---
|
||||
|
||||
// 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();
|
||||
@@ -74,10 +144,31 @@ document.addEventListener("DOMContentLoaded", () => {
|
||||
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); });
|
||||
if(sliceToolBtn) { sliceToolBtn.addEventListener("click", () => { appState.global.sliceToolActive = !appState.global.sliceToolActive; sliceToolBtn.classList.toggle("active", appState.global.sliceToolActive); document.body.classList.toggle("slice-tool-active", appState.global.sliceToolActive); }); }
|
||||
|
||||
// --- 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);
|
||||
|
||||
// ### CORREÇÃO 2: Adicionada verificação 'if (icon)' ###
|
||||
sidebarToggle.addEventListener("click", () => {
|
||||
document.body.classList.toggle("sidebar-hidden");
|
||||
const icon = sidebarToggle.querySelector("i");
|
||||
@@ -116,50 +207,31 @@ document.addEventListener("DOMContentLoaded", () => {
|
||||
});
|
||||
}
|
||||
|
||||
audioEditorPlayBtn.addEventListener("click", () => { if (appState.global.isAudioEditorPlaying) { stopAudioEditorPlayback(); } else { startAudioEditorPlayback(); } });
|
||||
audioEditorStopBtn.addEventListener("click", stopAudioEditorPlayback);
|
||||
audioEditorPlayBtn.addEventListener("click", () => {
|
||||
if (appState.global.isAudioEditorPlaying) {
|
||||
stopAudioEditorPlayback(false); // Pausa
|
||||
} else {
|
||||
startAudioEditorPlayback();
|
||||
}
|
||||
});
|
||||
audioEditorStopBtn.addEventListener("click", () => stopAudioEditorPlayback(true)); // Stop (rebobina)
|
||||
|
||||
// ### CORREÇÃO 1: Listeners duplicados combinados em um só ###
|
||||
// No main.js
|
||||
audioEditorLoopBtn.addEventListener("click", () => {
|
||||
console.log("--- Botão de Loop Clicado ---"); // DEBUG 1
|
||||
|
||||
// 1. Altera o estado global de loop
|
||||
appState.global.isLoopActive = !appState.global.isLoopActive;
|
||||
console.log("Estado appState.global.isLoopActive:", appState.global.isLoopActive); // DEBUG 2
|
||||
|
||||
// 2. Sincroniza o estado do loop do editor
|
||||
appState.audio.isAudioEditorLoopEnabled = appState.global.isLoopActive;
|
||||
|
||||
// 3. Atualiza a aparência do botão
|
||||
audioEditorLoopBtn.classList.toggle("active", appState.global.isLoopActive);
|
||||
|
||||
// 4. Sincroniza o Tone.Transport
|
||||
updateTransportLoop();
|
||||
|
||||
// 5. Mostra/esconde a área de loop
|
||||
const loopArea = document.getElementById("loop-region");
|
||||
|
||||
// ESTE É O TESTE MAIS IMPORTANTE:
|
||||
if (loopArea) {
|
||||
console.log("Elemento #loop-region ENCONTRADO. Alterando classe 'visible'."); // DEBUG 3
|
||||
loopArea.classList.toggle("visible", appState.global.isLoopActive);
|
||||
} else {
|
||||
console.error("ERRO GRAVE: Elemento #loop-region NÃO FOI ENCONTRADO!"); // DEBUG 4
|
||||
}
|
||||
|
||||
// 6. Reinicia o playback se estiver tocando
|
||||
restartAudioEditorIfPlaying();
|
||||
});
|
||||
|
||||
if (addAudioTrackBtn) { addAudioTrackBtn.addEventListener("click", () => { addAudioTrackLane(); renderAudioEditor(); }); }
|
||||
|
||||
// ### CORREÇÃO 3: Ordem de execução corrigida ###
|
||||
|
||||
// 1. Carrega o conteúdo do navegador de samples
|
||||
loadAndRenderSampleBrowser();
|
||||
|
||||
// 2. Adiciona o listener DEPOIS que o conteúdo supostamente existe
|
||||
const browserContent = document.getElementById('browser-content');
|
||||
if (browserContent) {
|
||||
browserContent.addEventListener('click', function(event) {
|
||||
@@ -171,6 +243,6 @@ document.addEventListener("DOMContentLoaded", () => {
|
||||
});
|
||||
}
|
||||
|
||||
// 3. Renderiza o resto
|
||||
renderAll();
|
||||
updateToolButtons(); // Define o estado inicial dos botões
|
||||
});
|
||||
Reference in new issue
Block a user