kopia lustrzana https://github.com/jameshball/osci-render
All files have their own code editors, fix various bugs
rodzic
bb2a03ec2d
commit
902286a086
|
@ -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();
|
||||||
|
|
|
@ -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)
|
||||||
};
|
};
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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];
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
};
|
};
|
Ładowanie…
Reference in New Issue