All files have their own code editors, fix various bugs

pull/170/head
James Ball 2023-07-02 13:09:24 +01:00
rodzic bb2a03ec2d
commit 902286a086
7 zmienionych plików z 103 dodań i 60 usunięć

Wyświetl plik

@ -20,6 +20,7 @@ MainComponent::MainComponent(OscirenderAudioProcessor& p, OscirenderAudioProcess
audioProcessor.addFile(file); audioProcessor.addFile(file);
} }
} }
pluginEditor.addCodeEditor(audioProcessor.getCurrentFileIndex());
pluginEditor.updateCodeEditor(); pluginEditor.updateCodeEditor();
updateFileLabel(); updateFileLabel();
}); });
@ -29,6 +30,11 @@ MainComponent::MainComponent(OscirenderAudioProcessor& p, OscirenderAudioProcess
closeFileButton.setButtonText("Close File"); closeFileButton.setButtonText("Close File");
closeFileButton.onClick = [this] { closeFileButton.onClick = [this] {
int index = audioProcessor.getCurrentFileIndex();
if (index == -1) {
return;
}
pluginEditor.removeCodeEditor(audioProcessor.getCurrentFileIndex());
audioProcessor.removeFile(audioProcessor.getCurrentFileIndex()); audioProcessor.removeFile(audioProcessor.getCurrentFileIndex());
pluginEditor.updateCodeEditor(); pluginEditor.updateCodeEditor();
updateFileLabel(); updateFileLabel();

Wyświetl plik

@ -13,6 +13,7 @@ public:
~MainComponent() override; ~MainComponent() override;
void resized() override; void resized() override;
void updateFileLabel();
private: private:
OscirenderAudioProcessor& audioProcessor; OscirenderAudioProcessor& audioProcessor;
OscirenderAudioProcessorEditor& pluginEditor; OscirenderAudioProcessorEditor& pluginEditor;
@ -22,7 +23,5 @@ private:
juce::TextButton closeFileButton; juce::TextButton closeFileButton;
juce::Label fileLabel; juce::Label fileLabel;
void updateFileLabel();
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(MainComponent) JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(MainComponent)
}; };

Wyświetl plik

@ -21,48 +21,27 @@ OscirenderAudioProcessorEditor::OscirenderAudioProcessorEditor(OscirenderAudioPr
addAndMakeVisible(effects); addAndMakeVisible(effects);
addAndMakeVisible(main); addAndMakeVisible(main);
codeEditor = std::make_unique<juce::CodeEditorComponent>(codeDocument, &luaTokeniser);
addAndMakeVisible(*codeEditor);
codeEditor->loadContent (R"LUA(
-- defines a factorial function
function fact (n)
if n == 0 then
return 1
else
return n * fact(n-1)
end
end
print("enter a number:")
a = io.read("*number") -- read a number
print(fact(a))
)LUA");
// I need to disable accessibility otherwise it doesn't work! Appears to be a JUCE issue, very annoying!
codeEditor->setAccessible(false);
// listen for changes to the code editor
codeDocument.addListener(this);
addAndMakeVisible(collapseButton); addAndMakeVisible(collapseButton);
collapseButton.onClick = [this] { collapseButton.onClick = [this] {
if (codeEditor->isVisible()) { int index = audioProcessor.getCurrentFileIndex();
codeEditor->setVisible(false); if (index != -1) {
juce::Path path; if (codeEditors[index]->isVisible()) {
path.addTriangle(0.0f, 0.5f, 1.0f, 1.0f, 1.0f, 0.0f); codeEditors[index]->setVisible(false);
collapseButton.setShape(path, false, true, true); juce::Path path;
} else { path.addTriangle(0.0f, 0.5f, 1.0f, 1.0f, 1.0f, 0.0f);
codeEditor->setVisible(true); collapseButton.setShape(path, false, true, true);
updateCodeEditor(); } else {
juce::Path path; codeEditors[index]->setVisible(true);
path.addTriangle(0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.5f); updateCodeEditor();
collapseButton.setShape(path, false, true, true); juce::Path path;
} path.addTriangle(0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.5f);
resized(); collapseButton.setShape(path, false, true, true);
}
resized();
}
}; };
juce::Path path; juce::Path path;
path.addTriangle(0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.5f); path.addTriangle(0.0f, 0.5f, 1.0f, 1.0f, 1.0f, 0.0f);
collapseButton.setShape(path, false, true, true); collapseButton.setShape(path, false, true, true);
resized(); resized();
} }
@ -81,54 +60,101 @@ void OscirenderAudioProcessorEditor::paint (juce::Graphics& g)
void OscirenderAudioProcessorEditor::resized() { void OscirenderAudioProcessorEditor::resized() {
auto area = getLocalBounds(); auto area = getLocalBounds();
auto sections = 2; auto sections = 2;
if (codeEditor != nullptr) { int index = audioProcessor.getCurrentFileIndex();
if (codeEditor->isVisible()) { if (index != -1) {
if (codeEditors[index]->isVisible()) {
sections++; sections++;
codeEditor->setBounds(area.removeFromRight(getWidth() / sections)); codeEditors[index]->setBounds(area.removeFromRight(getWidth() / sections));
} else { } else {
codeEditor->setBounds(0, 0, 0, 0); codeEditors[index]->setBounds(0, 0, 0, 0);
} }
collapseButton.setBounds(area.removeFromRight(20)); collapseButton.setBounds(area.removeFromRight(20));
} } else {
collapseButton.setBounds(0, 0, 0, 0);
}
effects.setBounds(area.removeFromRight(getWidth() / sections)); effects.setBounds(area.removeFromRight(getWidth() / sections));
main.setBounds(area.removeFromTop(getHeight() / 2)); main.setBounds(area.removeFromTop(getHeight() / 2));
} }
void OscirenderAudioProcessorEditor::addCodeEditor(int index) {
std::shared_ptr<juce::CodeDocument> codeDocument = std::make_shared<juce::CodeDocument>();
codeDocuments.insert(codeDocuments.begin() + index, codeDocument);
juce::String extension = audioProcessor.getFile(index).getFileExtension();
juce::CodeTokeniser* tokeniser = nullptr;
if (extension == ".lua") {
tokeniser = &luaTokeniser;
} else if (extension == ".svg") {
tokeniser = &xmlTokeniser;
}
std::shared_ptr<juce::CodeEditorComponent> editor = std::make_shared<juce::CodeEditorComponent>(*codeDocument, tokeniser);
// I need to disable accessibility otherwise it doesn't work! Appears to be a JUCE issue, very annoying!
editor->setAccessible(false);
// listen for changes to the code editor
codeDocument->addListener(this);
codeEditors.insert(codeEditors.begin() + index, editor);
addChildComponent(*editor);
}
void OscirenderAudioProcessorEditor::removeCodeEditor(int index) {
codeEditors.erase(codeEditors.begin() + index);
codeDocuments.erase(codeDocuments.begin() + index);
}
void OscirenderAudioProcessorEditor::updateCodeEditor() { void OscirenderAudioProcessorEditor::updateCodeEditor() {
if (codeEditor->isVisible() && audioProcessor.getCurrentFileIndex() != -1) { // check if any code editors are visible
codeEditor->loadContent(juce::MemoryInputStream(*audioProcessor.getFileBlock(audioProcessor.getCurrentFileIndex()), false).readEntireStreamAsString()); bool visible = false;
for (int i = 0; i < codeEditors.size(); i++) {
if (codeEditors[i]->isVisible()) {
visible = true;
break;
}
}
int index = audioProcessor.getCurrentFileIndex();
if (index != -1 && visible) {
for (int i = 0; i < codeEditors.size(); i++) {
codeEditors[i]->setVisible(false);
}
codeEditors[index]->setVisible(true);
codeEditors[index]->loadContent(juce::MemoryInputStream(*audioProcessor.getFileBlock(index), false).readEntireStreamAsString());
} }
resized();
} }
void OscirenderAudioProcessorEditor::codeDocumentTextInserted(const juce::String& newText, int insertIndex) { void OscirenderAudioProcessorEditor::codeDocumentTextInserted(const juce::String& newText, int insertIndex) {
juce::String file = codeDocument.getAllContent(); int index = audioProcessor.getCurrentFileIndex();
audioProcessor.updateFileBlock(audioProcessor.getCurrentFileIndex(), std::make_shared<juce::MemoryBlock>(file.toRawUTF8(), file.getNumBytesAsUTF8() + 1)); juce::String file = codeDocuments[index]->getAllContent();
audioProcessor.updateFileBlock(index, std::make_shared<juce::MemoryBlock>(file.toRawUTF8(), file.getNumBytesAsUTF8() + 1));
} }
void OscirenderAudioProcessorEditor::codeDocumentTextDeleted(int startIndex, int endIndex) { void OscirenderAudioProcessorEditor::codeDocumentTextDeleted(int startIndex, int endIndex) {
juce::String file = codeDocument.getAllContent(); int index = audioProcessor.getCurrentFileIndex();
audioProcessor.updateFileBlock(audioProcessor.getCurrentFileIndex(), std::make_shared<juce::MemoryBlock>(file.toRawUTF8(), file.getNumBytesAsUTF8() + 1)); juce::String file = codeDocuments[index]->getAllContent();
audioProcessor.updateFileBlock(index, std::make_shared<juce::MemoryBlock>(file.toRawUTF8(), file.getNumBytesAsUTF8() + 1));
} }
bool OscirenderAudioProcessorEditor::keyPressed(const juce::KeyPress& key) { bool OscirenderAudioProcessorEditor::keyPressed(const juce::KeyPress& key) {
int numFiles = audioProcessor.numFiles(); int numFiles = audioProcessor.numFiles();
int currentFile = audioProcessor.getCurrentFileIndex(); int currentFile = audioProcessor.getCurrentFileIndex();
bool updated = false;
if (key.getTextCharacter() == 'j') { if (key.getTextCharacter() == 'j') {
currentFile++; currentFile++;
if (currentFile == numFiles) { if (currentFile == numFiles) {
currentFile = 0; currentFile = 0;
} }
audioProcessor.changeCurrentFile(currentFile); updated = true;
updateCodeEditor();
return true;
} else if (key.getTextCharacter() == 'k') { } else if (key.getTextCharacter() == 'k') {
currentFile--; currentFile--;
if (currentFile < 0) { if (currentFile < 0) {
currentFile = numFiles - 1; currentFile = numFiles - 1;
} }
updated = true;
}
if (updated) {
audioProcessor.changeCurrentFile(currentFile); audioProcessor.changeCurrentFile(currentFile);
updateCodeEditor(); updateCodeEditor();
return true; main.updateFileLabel();
} }
return false;
return updated;
} }

Wyświetl plik

@ -27,15 +27,18 @@ public:
void paint (juce::Graphics&) override; void paint (juce::Graphics&) override;
void resized() override; void resized() override;
void addCodeEditor(int index);
void removeCodeEditor(int index);
void updateCodeEditor(); void updateCodeEditor();
private: private:
OscirenderAudioProcessor& audioProcessor; OscirenderAudioProcessor& audioProcessor;
MainComponent main; MainComponent main;
EffectsComponent effects; EffectsComponent effects;
juce::CodeDocument codeDocument; std::vector<std::shared_ptr<juce::CodeDocument>> codeDocuments;
std::vector<std::shared_ptr<juce::CodeEditorComponent>> codeEditors;
juce::LuaTokeniser luaTokeniser; juce::LuaTokeniser luaTokeniser;
std::unique_ptr<juce::CodeEditorComponent> codeEditor; juce::XmlTokeniser xmlTokeniser;
juce::ShapeButton collapseButton; juce::ShapeButton collapseButton;
void codeDocumentTextInserted(const juce::String& newText, int insertIndex) override; void codeDocumentTextInserted(const juce::String& newText, int insertIndex) override;

Wyświetl plik

@ -241,6 +241,10 @@ void OscirenderAudioProcessor::openFile(int index) {
} }
void OscirenderAudioProcessor::changeCurrentFile(int index) { void OscirenderAudioProcessor::changeCurrentFile(int index) {
if (index == -1) {
currentFile = -1;
producer->setSource(std::make_shared<FileParser>(), -1);
}
if (index < 0 || index >= fileBlocks.size()) { if (index < 0 || index >= fileBlocks.size()) {
return; return;
} }
@ -257,6 +261,10 @@ juce::File OscirenderAudioProcessor::getCurrentFile() {
return files[currentFile]; return files[currentFile];
} }
juce::File OscirenderAudioProcessor::getFile(int index) {
return files[index];
}
std::shared_ptr<juce::MemoryBlock> OscirenderAudioProcessor::getFileBlock(int index) { std::shared_ptr<juce::MemoryBlock> OscirenderAudioProcessor::getFileBlock(int index) {
return fileBlocks[index]; return fileBlocks[index];
} }

Wyświetl plik

@ -95,6 +95,7 @@ public:
void changeCurrentFile(int index); void changeCurrentFile(int index);
int getCurrentFileIndex(); int getCurrentFileIndex();
juce::File getCurrentFile(); juce::File getCurrentFile();
juce::File getFile(int index);
std::shared_ptr<juce::MemoryBlock> getFileBlock(int index); std::shared_ptr<juce::MemoryBlock> getFileBlock(int index);
private: private:
double theta = 0.0; double theta = 0.0;

Wyświetl plik

@ -14,5 +14,5 @@ public:
private: private:
FrameConsumer& frameConsumer; FrameConsumer& frameConsumer;
std::shared_ptr<FrameSource> frameSource; std::shared_ptr<FrameSource> frameSource;
int sourceFileIndex = 0; int sourceFileIndex = -1;
}; };