melhorando a leitura de projetos no mmpCreator
This commit is contained in:
1 parent
7b569c1bde
commit
7b5fc2566d
2 files changed
+324
-233
No files matched your search
+93
-82
@@ -65,7 +65,7 @@
|
||||
}
|
||||
|
||||
/* --- NOVOS ESTILOS PARA O BASSLINE EDITOR (Lógica 3) --- */
|
||||
|
||||
|
||||
/* Linha do instrumento (Nome à esquerda) */
|
||||
.instrument-row {
|
||||
display: flex;
|
||||
@@ -79,7 +79,7 @@
|
||||
font-size: 0.9rem;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
|
||||
/* Linha dos steps (Botões à direita) */
|
||||
.steps-row {
|
||||
display: flex;
|
||||
@@ -143,8 +143,13 @@
|
||||
title="Salvar Projeto (.mmp)"
|
||||
></i>
|
||||
<span style="margin-left: 8px">Salvar projeto</span>
|
||||
<i class="fa-solid fa-file-zipper" id="download-package-btn" title="Baixar Pacote Completo (.zip)" style="margin-left: 15px; color: #ffdd57; cursor: pointer;"></i>
|
||||
<span style="margin-left: 8px; color: #ffdd57;">Baixar ZIP</span>
|
||||
<i
|
||||
class="fa-solid fa-file-zipper"
|
||||
id="download-package-btn"
|
||||
title="Baixar Pacote Completo (.zip)"
|
||||
style="margin-left: 15px; color: #ffdd57; cursor: pointer"
|
||||
></i>
|
||||
<span style="margin-left: 8px; color: #ffdd57">Baixar ZIP</span>
|
||||
<i
|
||||
class="fa-solid fa-upload"
|
||||
id="upload-sample-btn"
|
||||
@@ -378,7 +383,7 @@
|
||||
</div>
|
||||
|
||||
<div id="sequencer-grid" class="sequencer-container"></div>
|
||||
|
||||
|
||||
<div class="tool-icons"></div>
|
||||
<div id="timeline-context-menu">
|
||||
<div id="copy-clip">Copiar</div>
|
||||
@@ -395,7 +400,7 @@
|
||||
<div id="ruler-set-loop-end">Definir Fim do Loop</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div id="track-container"></div>
|
||||
</div>
|
||||
|
||||
@@ -618,79 +623,85 @@
|
||||
// Esta função popula a área superior (Beat Editor)
|
||||
// quando se clica duas vezes num clipe da playlist.
|
||||
// =======================================================
|
||||
|
||||
window.openPatternEditor = function(basslineTrack) {
|
||||
console.log("Abrindo editor para:", basslineTrack.track_name);
|
||||
|
||||
const nameContainer = document.getElementById("track-container");
|
||||
const stepsContainer = document.getElementById("sequencer-grid");
|
||||
|
||||
if(!nameContainer || !stepsContainer) return;
|
||||
window.openPatternEditor = function (basslineTrack) {
|
||||
console.log("Abrindo editor para:", basslineTrack.track_name);
|
||||
|
||||
nameContainer.innerHTML = "";
|
||||
stepsContainer.innerHTML = "";
|
||||
const nameContainer = document.getElementById("track-container");
|
||||
const stepsContainer = document.getElementById("sequencer-grid");
|
||||
|
||||
const instruments = basslineTrack.instruments || [];
|
||||
if (!nameContainer || !stepsContainer) return;
|
||||
|
||||
if (instruments.length === 0) {
|
||||
nameContainer.innerHTML = "<div style='padding:10px; color:#ccc'>Nenhum instrumento.</div>";
|
||||
return;
|
||||
nameContainer.innerHTML = "";
|
||||
stepsContainer.innerHTML = "";
|
||||
|
||||
const instruments = basslineTrack.instruments || [];
|
||||
|
||||
if (instruments.length === 0) {
|
||||
nameContainer.innerHTML =
|
||||
"<div style='padding:10px; color:#ccc'>Nenhum instrumento.</div>";
|
||||
return;
|
||||
}
|
||||
|
||||
instruments.forEach((inst) => {
|
||||
// --- A. Nome do Instrumento ---
|
||||
const nameRow = document.createElement("div");
|
||||
nameRow.className = "instrument-row";
|
||||
|
||||
const label = document.createElement("span");
|
||||
label.innerText =
|
||||
inst.instrument_name || inst.plugin_name || "Sem Nome";
|
||||
nameRow.appendChild(label);
|
||||
nameContainer.appendChild(nameRow);
|
||||
|
||||
// --- B. Steps (Correção Aqui) ---
|
||||
let stepData = [];
|
||||
|
||||
// LÓGICA ATUALIZADA DE VISUALIZAÇÃO
|
||||
// Se houver múltiplos patterns (loop longo), combinamos os steps ativos
|
||||
// ou pegamos o pattern que realmente tem notas.
|
||||
if (inst.patterns && inst.patterns.length > 0) {
|
||||
// Cria um array base de 16 steps (ou maior se quiser suportar 32/64)
|
||||
stepData = new Array(16).fill(false);
|
||||
|
||||
inst.patterns.forEach((p) => {
|
||||
// Mescla os steps desse pattern no array principal visual
|
||||
if (p.steps) {
|
||||
p.steps.forEach((isActive, idx) => {
|
||||
if (isActive && idx < 16) stepData[idx] = true;
|
||||
});
|
||||
}
|
||||
});
|
||||
} else {
|
||||
stepData = Array(16).fill(false);
|
||||
}
|
||||
|
||||
instruments.forEach(inst => {
|
||||
// --- A. Nome do Instrumento ---
|
||||
const nameRow = document.createElement("div");
|
||||
nameRow.className = "instrument-row";
|
||||
|
||||
const label = document.createElement("span");
|
||||
label.innerText = inst.instrument_name || inst.plugin_name || "Sem Nome";
|
||||
nameRow.appendChild(label);
|
||||
nameContainer.appendChild(nameRow);
|
||||
const stepsRow = document.createElement("div");
|
||||
stepsRow.className = "steps-row";
|
||||
|
||||
// --- B. Steps (Correção Aqui) ---
|
||||
let stepData = [];
|
||||
|
||||
stepData.forEach((isActive, index) => {
|
||||
const stepBtn = document.createElement("div");
|
||||
stepBtn.className = "step-btn";
|
||||
if (isActive) stepBtn.classList.add("active");
|
||||
|
||||
stepBtn.addEventListener("click", () => {
|
||||
const newState = !stepBtn.classList.contains("active");
|
||||
if (newState) stepBtn.classList.add("active");
|
||||
else stepBtn.classList.remove("active");
|
||||
|
||||
// Atualiza na memória (atenção: idealmente atualize todos os patterns desse inst)
|
||||
if (inst.patterns && inst.patterns.length > 0) {
|
||||
// Tenta encontrar um pattern que tenha pelo menos uma nota 'true'
|
||||
const activePattern = inst.patterns.find(p => p.steps.some(s => s === true));
|
||||
|
||||
if (activePattern) {
|
||||
// Se achou um com notas, usa ele
|
||||
stepData = activePattern.steps;
|
||||
} else {
|
||||
// Se todos estão vazios, usa o primeiro mesmo
|
||||
stepData = inst.patterns[0].steps;
|
||||
}
|
||||
} else {
|
||||
stepData = Array(16).fill(false);
|
||||
inst.patterns.forEach((p) => {
|
||||
if (p.steps[index] !== undefined) p.steps[index] = newState;
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
const stepsRow = document.createElement("div");
|
||||
stepsRow.className = "steps-row";
|
||||
|
||||
stepData.forEach((isActive, index) => {
|
||||
const stepBtn = document.createElement("div");
|
||||
stepBtn.className = "step-btn";
|
||||
if (isActive) stepBtn.classList.add("active");
|
||||
|
||||
stepBtn.addEventListener("click", () => {
|
||||
const newState = !stepBtn.classList.contains("active");
|
||||
if(newState) stepBtn.classList.add("active");
|
||||
else stepBtn.classList.remove("active");
|
||||
|
||||
// Atualiza na memória (atenção: idealmente atualize todos os patterns desse inst)
|
||||
if(inst.patterns && inst.patterns.length > 0) {
|
||||
inst.patterns.forEach(p => {
|
||||
if(p.steps[index] !== undefined) p.steps[index] = newState;
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
stepsRow.appendChild(stepBtn);
|
||||
});
|
||||
|
||||
stepsContainer.appendChild(stepsRow);
|
||||
stepsRow.appendChild(stepBtn);
|
||||
});
|
||||
|
||||
stepsContainer.appendChild(stepsRow);
|
||||
});
|
||||
};
|
||||
|
||||
// --- FUNÇÃO GLOBAL PARA ABRIR O PIANO ROLL (JÁ EXISTENTE) ---
|
||||
@@ -829,7 +840,7 @@
|
||||
|
||||
const newNote = {
|
||||
pos: quantizedPos,
|
||||
len: 48,
|
||||
len: 48,
|
||||
key: midiNote,
|
||||
vol: 100,
|
||||
pan: 0,
|
||||
@@ -877,7 +888,7 @@
|
||||
<script>
|
||||
document.addEventListener("DOMContentLoaded", () => {
|
||||
const downloadBtn = document.getElementById("download-package-btn");
|
||||
|
||||
|
||||
if (downloadBtn) {
|
||||
downloadBtn.addEventListener("click", () => {
|
||||
const params = new URLSearchParams(window.location.search);
|
||||
@@ -889,10 +900,12 @@
|
||||
}
|
||||
const apiUrl = `/api/download/${projectName}`;
|
||||
downloadBtn.style.opacity = "0.5";
|
||||
setTimeout(() => downloadBtn.style.opacity = "1", 500);
|
||||
setTimeout(() => (downloadBtn.style.opacity = "1"), 500);
|
||||
window.location.href = apiUrl;
|
||||
} else {
|
||||
alert("Nenhum projeto selecionado na URL. Abra ou Salve um projeto primeiro.");
|
||||
alert(
|
||||
"Nenhum projeto selecionado na URL. Abra ou Salve um projeto primeiro."
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -903,7 +916,6 @@
|
||||
const sampleInput = document.getElementById("sample-file-input");
|
||||
|
||||
if (uploadSampleBtn && sampleInput) {
|
||||
|
||||
uploadSampleBtn.addEventListener("click", () => {
|
||||
sampleInput.click();
|
||||
});
|
||||
@@ -913,27 +925,27 @@
|
||||
|
||||
const file = sampleInput.files[0];
|
||||
const category = prompt(
|
||||
"Em qual categoria este sample se encaixa? (Ex: drums, effects, vocals)",
|
||||
"Em qual categoria este sample se encaixa? (Ex: drums, effects, vocals)",
|
||||
"imported"
|
||||
);
|
||||
|
||||
if (category === null) {
|
||||
sampleInput.value = "";
|
||||
sampleInput.value = "";
|
||||
return;
|
||||
}
|
||||
|
||||
const formData = new FormData();
|
||||
formData.append("sample_file", file);
|
||||
formData.append("subfolder", category);
|
||||
formData.append("sample_file", file);
|
||||
formData.append("subfolder", category);
|
||||
|
||||
const originalIcon = uploadSampleBtn.className;
|
||||
uploadSampleBtn.className = "fa-solid fa-spinner fa-spin";
|
||||
uploadSampleBtn.className = "fa-solid fa-spinner fa-spin";
|
||||
uploadSampleBtn.style.pointerEvents = "none";
|
||||
|
||||
try {
|
||||
const response = await fetch("/api/upload/sample", {
|
||||
method: "POST",
|
||||
body: formData
|
||||
body: formData,
|
||||
});
|
||||
|
||||
const result = await response.json();
|
||||
@@ -943,14 +955,13 @@
|
||||
} else {
|
||||
alert("Erro ao enviar: " + (result.error || "Desconhecido"));
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
console.error("Erro no upload:", error);
|
||||
alert("Erro de conexão com o servidor.");
|
||||
} finally {
|
||||
uploadSampleBtn.className = originalIcon;
|
||||
uploadSampleBtn.style.pointerEvents = "auto";
|
||||
sampleInput.value = "";
|
||||
sampleInput.value = "";
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -963,4 +974,4 @@
|
||||
<script src="https://cdn.socket.io/4.7.5/socket.io.min.js"></script>
|
||||
<script src="assets/js/creations/socket.js" type="module"></script>
|
||||
</body>
|
||||
</html>
|
||||
</html>
|
||||
Reference in new issue
Block a user