kopia lustrzana https://github.com/jameshball/osci-render
Make code editor not appear if a binary file is open, and add About menu
rodzic
35c8f52d47
commit
8f437c716e
Plik binarny nie jest wyświetlany.
Po Szerokość: | Wysokość: | Rozmiar: 36 KiB |
|
@ -42,6 +42,7 @@ FrameSettingsComponent::FrameSettingsComponent(OscirenderAudioProcessor& p, Osci
|
|||
invertImage.onClick = [this]() {
|
||||
audioProcessor.invertImage->setValue(invertImage.getToggleState());
|
||||
};
|
||||
invertImage.setTooltip("Inverts the image so that dark pixels become light, and vice versa.");
|
||||
|
||||
threshold.slider.onValueChange = [this]() {
|
||||
audioProcessor.imageThreshold->setValue(threshold.slider.getValue());
|
||||
|
|
|
@ -25,6 +25,8 @@ MainComponent::MainComponent(OscirenderAudioProcessor& p, OscirenderAudioProcess
|
|||
fileAdded = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (fileAdded) {
|
||||
pluginEditor.fileUpdated(audioProcessor.getCurrentFileName());
|
||||
}
|
||||
|
@ -89,7 +91,7 @@ MainComponent::MainComponent(OscirenderAudioProcessor& p, OscirenderAudioProcess
|
|||
fileType.addItem(".lua", 1);
|
||||
fileType.addItem(".svg", 2);
|
||||
fileType.addItem(".obj", 3);
|
||||
fileType.addItem(".txt", 4);
|
||||
fileType.addItem(".txt", 4);
|
||||
fileType.setSelectedId(1);
|
||||
addAndMakeVisible(fileType);
|
||||
addAndMakeVisible(createFile);
|
||||
|
|
|
@ -21,6 +21,8 @@ public:
|
|||
private:
|
||||
OscirenderAudioProcessor& audioProcessor;
|
||||
OscirenderAudioProcessorEditor& pluginEditor;
|
||||
|
||||
bool isBinaryFile(juce::String name);
|
||||
|
||||
std::unique_ptr<juce::FileChooser> chooser;
|
||||
juce::TextButton fileButton;
|
||||
|
@ -44,4 +46,4 @@ private:
|
|||
AudioRecordingComponent recorder{audioProcessor};
|
||||
|
||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(MainComponent)
|
||||
};
|
||||
};
|
||||
|
|
|
@ -44,7 +44,7 @@ OscirenderAudioProcessorEditor::OscirenderAudioProcessorEditor(OscirenderAudioPr
|
|||
int index = editingCustomFunction ? 0 : audioProcessor.getCurrentFileIndex() + 1;
|
||||
if (originalIndex != -1 || editingCustomFunction) {
|
||||
codeEditors[index]->setVisible(!codeEditors[index]->isVisible());
|
||||
updateCodeEditor();
|
||||
updateCodeEditor(!editingCustomFunction && isBinaryFile(audioProcessor.getCurrentFileName()));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -122,6 +122,10 @@ OscirenderAudioProcessorEditor::~OscirenderAudioProcessorEditor() {
|
|||
#endif
|
||||
}
|
||||
|
||||
bool OscirenderAudioProcessorEditor::isBinaryFile(juce::String name) {
|
||||
return name.endsWith(".gpla") || name.endsWith(".gif") || name.endsWith(".png") || name.endsWith(".jpg") || name.endsWith(".jpeg");
|
||||
}
|
||||
|
||||
// parsersLock must be held
|
||||
void OscirenderAudioProcessorEditor::initialiseCodeEditors() {
|
||||
codeEditors.clear();
|
||||
|
@ -163,7 +167,7 @@ void OscirenderAudioProcessorEditor::resized() {
|
|||
int originalIndex = audioProcessor.getCurrentFileIndex();
|
||||
int index = editingCustomFunction ? 0 : audioProcessor.getCurrentFileIndex() + 1;
|
||||
|
||||
bool ableToEditFile = originalIndex != -1 || editingCustomFunction;
|
||||
bool ableToEditFile = (originalIndex != -1 && !isBinaryFile(audioProcessor.getCurrentFileName())) || editingCustomFunction;
|
||||
bool fileOpen = false;
|
||||
bool luaFileOpen = false;
|
||||
|
||||
|
@ -275,35 +279,44 @@ void OscirenderAudioProcessorEditor::removeCodeEditor(int index) {
|
|||
|
||||
|
||||
// parsersLock AND effectsLock must be locked before calling this function
|
||||
void OscirenderAudioProcessorEditor::updateCodeEditor(bool shouldOpenEditor) {
|
||||
void OscirenderAudioProcessorEditor::updateCodeEditor(bool binaryFile, bool shouldOpenEditor) {
|
||||
// check if any code editors are visible
|
||||
bool visible = shouldOpenEditor;
|
||||
if (!visible) {
|
||||
for (int i = 0; i < codeEditors.size(); i++) {
|
||||
if (codeEditors[i]->isVisible()) {
|
||||
visible = true;
|
||||
if (binaryFile) {
|
||||
codeEditors[i]->setVisible(false);
|
||||
} else {
|
||||
visible = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
int originalIndex = audioProcessor.getCurrentFileIndex();
|
||||
int index = editingCustomFunction ? 0 : audioProcessor.getCurrentFileIndex() + 1;
|
||||
if ((originalIndex != -1 || editingCustomFunction) && visible) {
|
||||
for (int i = 0; i < codeEditors.size(); i++) {
|
||||
codeEditors[i]->setVisible(false);
|
||||
|
||||
collapseButton.setVisible(!binaryFile);
|
||||
|
||||
if (!binaryFile) {
|
||||
int originalIndex = audioProcessor.getCurrentFileIndex();
|
||||
int index = editingCustomFunction ? 0 : audioProcessor.getCurrentFileIndex() + 1;
|
||||
if ((originalIndex != -1 || editingCustomFunction) && visible) {
|
||||
for (int i = 0; i < codeEditors.size(); i++) {
|
||||
codeEditors[i]->setVisible(false);
|
||||
}
|
||||
codeEditors[index]->setVisible(true);
|
||||
// used so that codeDocumentTextInserted and codeDocumentTextDeleted know whether the parserLock
|
||||
// is held by the message thread or not. We hold the lock in this function, but not when the
|
||||
// code document is updated by the user editing text. Since both functions are called by the
|
||||
// message thread, this is safe.
|
||||
updatingDocumentsWithParserLock = true;
|
||||
if (index == 0) {
|
||||
codeEditors[index]->getEditor().loadContent(audioProcessor.customEffect->getCode());
|
||||
} else {
|
||||
codeEditors[index]->getEditor().loadContent(juce::MemoryInputStream(*audioProcessor.getFileBlock(originalIndex), false).readEntireStreamAsString());
|
||||
}
|
||||
updatingDocumentsWithParserLock = false;
|
||||
}
|
||||
codeEditors[index]->setVisible(true);
|
||||
// used so that codeDocumentTextInserted and codeDocumentTextDeleted know whether the parserLock
|
||||
// is held by the message thread or not. We hold the lock in this function, but not when the
|
||||
// code document is updated by the user editing text. Since both functions are called by the
|
||||
// message thread, this is safe.
|
||||
updatingDocumentsWithParserLock = true;
|
||||
if (index == 0) {
|
||||
codeEditors[index]->getEditor().loadContent(audioProcessor.customEffect->getCode());
|
||||
} else {
|
||||
codeEditors[index]->getEditor().loadContent(juce::MemoryInputStream(*audioProcessor.getFileBlock(originalIndex), false).readEntireStreamAsString());
|
||||
}
|
||||
updatingDocumentsWithParserLock = false;
|
||||
}
|
||||
triggerAsyncUpdate();
|
||||
}
|
||||
|
@ -311,7 +324,7 @@ void OscirenderAudioProcessorEditor::updateCodeEditor(bool shouldOpenEditor) {
|
|||
// parsersLock MUST be locked before calling this function
|
||||
void OscirenderAudioProcessorEditor::fileUpdated(juce::String fileName, bool shouldOpenEditor) {
|
||||
settings.fileUpdated(fileName);
|
||||
updateCodeEditor(shouldOpenEditor);
|
||||
updateCodeEditor(isBinaryFile(fileName), shouldOpenEditor);
|
||||
}
|
||||
|
||||
void OscirenderAudioProcessorEditor::handleAsyncUpdate() {
|
||||
|
@ -359,7 +372,7 @@ void OscirenderAudioProcessorEditor::editCustomFunction(bool enable) {
|
|||
juce::SpinLock::ScopedLockType lock1(audioProcessor.parsersLock);
|
||||
juce::SpinLock::ScopedLockType lock2(audioProcessor.effectsLock);
|
||||
codeEditors[0]->setVisible(enable);
|
||||
updateCodeEditor();
|
||||
updateCodeEditor(!editingCustomFunction && isBinaryFile(audioProcessor.getCurrentFileName()));
|
||||
}
|
||||
|
||||
// parsersLock AND effectsLock must be locked before calling this function
|
||||
|
|
|
@ -18,6 +18,7 @@ public:
|
|||
void paint(juce::Graphics&) override;
|
||||
void resized() override;
|
||||
|
||||
bool isBinaryFile(juce::String name);
|
||||
void initialiseCodeEditors();
|
||||
void addCodeEditor(int index);
|
||||
void removeCodeEditor(int index);
|
||||
|
@ -90,7 +91,7 @@ public:
|
|||
void codeDocumentTextInserted(const juce::String& newText, int insertIndex) override;
|
||||
void codeDocumentTextDeleted(int startIndex, int endIndex) override;
|
||||
void updateCodeDocument();
|
||||
void updateCodeEditor(bool shouldOpenEditor = false);
|
||||
void updateCodeEditor(bool binaryFile, bool shouldOpenEditor = false);
|
||||
|
||||
bool keyPressed(const juce::KeyPress& key) override;
|
||||
void mouseDown(const juce::MouseEvent& event) override;
|
||||
|
|
|
@ -147,6 +147,8 @@ OscirenderAudioProcessor::OscirenderAudioProcessor()
|
|||
permanentEffects.push_back(frequencyEffect);
|
||||
permanentEffects.push_back(volumeEffect);
|
||||
permanentEffects.push_back(thresholdEffect);
|
||||
permanentEffects.push_back(imageThreshold);
|
||||
permanentEffects.push_back(imageStride);
|
||||
|
||||
for (int i = 0; i < 26; i++) {
|
||||
addLuaSlider();
|
||||
|
@ -155,8 +157,6 @@ OscirenderAudioProcessor::OscirenderAudioProcessor()
|
|||
allEffects = toggleableEffects;
|
||||
allEffects.insert(allEffects.end(), permanentEffects.begin(), permanentEffects.end());
|
||||
allEffects.insert(allEffects.end(), luaEffects.begin(), luaEffects.end());
|
||||
allEffects.push_back(imageThreshold);
|
||||
allEffects.push_back(imageStride);
|
||||
|
||||
for (auto effect : allEffects) {
|
||||
for (auto effectParameter : effect->parameters) {
|
||||
|
|
|
@ -212,7 +212,7 @@ public:
|
|||
return input;
|
||||
}, new EffectParameter(
|
||||
"Image Threshold",
|
||||
"image threshold innit",
|
||||
"Controls the probability of visiting a dark pixel versus a light pixel. Darker pixels are less likely to be visited, so turning the threshold to a lower value makes it more likely to visit dark pixels.",
|
||||
"imageThreshold",
|
||||
VERSION_HINT, 0.5, 0, 1
|
||||
)
|
||||
|
@ -222,9 +222,9 @@ public:
|
|||
return input;
|
||||
}, new EffectParameter(
|
||||
"Image Stride",
|
||||
"image stride innit",
|
||||
"Controls the spacing between pixels when drawing an image. Larger values mean more of the image can be drawn, but at a lower fidelity.",
|
||||
"imageStride",
|
||||
VERSION_HINT, 2, 1, 50, 1, false
|
||||
VERSION_HINT, 4, 1, 50, 1, false
|
||||
)
|
||||
);
|
||||
|
||||
|
|
|
@ -0,0 +1,33 @@
|
|||
#include "AboutComponent.h"
|
||||
#include <format>
|
||||
|
||||
AboutComponent::AboutComponent() {
|
||||
addAndMakeVisible(logoComponent);
|
||||
addAndMakeVisible(text);
|
||||
|
||||
logoComponent.setImage(logo);
|
||||
|
||||
text.setMultiLine(true);
|
||||
text.setReadOnly(true);
|
||||
text.setInterceptsMouseClicks(false, false);
|
||||
text.setOpaque(false);
|
||||
text.setColour(juce::TextEditor::backgroundColourId, juce::Colours::transparentBlack);
|
||||
text.setColour(juce::TextEditor::outlineColourId, juce::Colours::transparentBlack);
|
||||
text.setJustification(juce::Justification(juce::Justification::centred));
|
||||
text.setText(
|
||||
juce::String(ProjectInfo::projectName) + " by " + ProjectInfo::companyName + "\n"
|
||||
"Version " + ProjectInfo::versionString + "\n\n"
|
||||
"A huge thank you to:\n"
|
||||
"DJ_Level_3, for contributing several features to osci-render\n"
|
||||
"BUS ERROR Collective, for providing the source code for the Hilligoss encoder\n"
|
||||
"All the community, for suggesting features and reporting issues!\n\n"
|
||||
"I am open for commissions! Email me at james@ball.sh."
|
||||
);
|
||||
}
|
||||
|
||||
void AboutComponent::resized() {
|
||||
auto area = getLocalBounds();
|
||||
area.removeFromTop(10);
|
||||
logoComponent.setBounds(area.removeFromTop(110));
|
||||
text.setBounds(area);
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
#pragma once
|
||||
|
||||
#include <JuceHeader.h>
|
||||
|
||||
class AboutComponent : public juce::Component {
|
||||
public:
|
||||
AboutComponent();
|
||||
|
||||
void resized() override;
|
||||
|
||||
private:
|
||||
juce::Image logo = juce::ImageFileFormat::loadFrom(BinaryData::logo_png, BinaryData::logo_pngSize);
|
||||
juce::ImageComponent logoComponent;
|
||||
|
||||
juce::TextEditor text;
|
||||
|
||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (AboutComponent)
|
||||
};
|
|
@ -3,9 +3,9 @@
|
|||
|
||||
juce::StringArray MainMenuBarModel::getMenuBarNames() {
|
||||
if (editor.processor.wrapperType == juce::AudioProcessor::WrapperType::wrapperType_Standalone) {
|
||||
return juce::StringArray("File", "Audio");
|
||||
return juce::StringArray("File", "About", "Audio");
|
||||
} else {
|
||||
return juce::StringArray("File");
|
||||
return juce::StringArray("File", "About");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -20,6 +20,8 @@ juce::PopupMenu MainMenuBarModel::getMenuForIndex(int topLevelMenuIndex, const j
|
|||
menu.addItem(4, "Create New Project");
|
||||
}
|
||||
} else if (topLevelMenuIndex == 1) {
|
||||
menu.addItem(1, "About osci-render");
|
||||
} else if (topLevelMenuIndex == 2) {
|
||||
menu.addItem(1, "Settings");
|
||||
}
|
||||
|
||||
|
@ -46,7 +48,21 @@ void MainMenuBarModel::menuItemSelected(int menuItemID, int topLevelMenuIndex) {
|
|||
break;
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
case 1: {
|
||||
juce::String m = "Test";
|
||||
juce::DialogWindow::LaunchOptions options;
|
||||
AboutComponent* about = new AboutComponent();
|
||||
options.content.setOwned(about);
|
||||
options.content->setSize(500, 250);
|
||||
options.dialogTitle = "About";
|
||||
options.dialogBackgroundColour = Colours::dark;
|
||||
options.escapeKeyTriggersCloseButton = true;
|
||||
options.useNativeTitleBar = true;
|
||||
options.resizable = false;
|
||||
|
||||
juce::DialogWindow* dw = options.launchAsync();
|
||||
} break;
|
||||
case 2:
|
||||
editor.openAudioSettings();
|
||||
break;
|
||||
default:
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
#pragma once
|
||||
#include <JuceHeader.h>
|
||||
#include "AboutComponent.h"
|
||||
|
||||
class OscirenderAudioProcessorEditor;
|
||||
class MainMenuBarModel : public juce::MenuBarModel {
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
#pragma once
|
||||
|
||||
#define NOMINMAX
|
||||
#include <algorithm>
|
||||
#include <JuceHeader.h>
|
||||
#include "../concurrency/BufferConsumer.h"
|
||||
|
|
|
@ -151,9 +151,9 @@ Point ImageParser::getSample() {
|
|||
std::fill(visited.begin(), visited.end(), false);
|
||||
}
|
||||
|
||||
float thresholdPow = audioProcessor.imageThreshold->getValue() * 10 + 1;
|
||||
float thresholdPow = audioProcessor.imageThreshold->getActualValue() * 10 + 1;
|
||||
|
||||
findNearestNeighbour(10, thresholdPow, audioProcessor.imageStride->getValue(), audioProcessor.invertImage->getValue());
|
||||
findNearestNeighbour(10, thresholdPow, audioProcessor.imageStride->getActualValue(), audioProcessor.invertImage->getValue());
|
||||
float maxDim = juce::jmax(width, height);
|
||||
count++;
|
||||
float widthDiff = (maxDim - width) / 2;
|
||||
|
|
|
@ -13,6 +13,9 @@
|
|||
<FILE id="G2dMtI" name="invalid.gpla" compile="0" resource="1" file="Resources/gpla/invalid.gpla"/>
|
||||
<FILE id="b9HuXW" name="noframes.gpla" compile="0" resource="1" file="Resources/gpla/noframes.gpla"/>
|
||||
</GROUP>
|
||||
<GROUP id="{525C568C-29E9-D0A2-9773-8A04981C5575}" name="images">
|
||||
<FILE id="jI9VSZ" name="logo.png" compile="0" resource="1" file="Resources/images/logo.png"/>
|
||||
</GROUP>
|
||||
<GROUP id="{C2609827-4F4A-1ADA-8BA1-A40C1D92649C}" name="lua">
|
||||
<FILE id="xANsA8" name="demo.lua" compile="0" resource="1" file="Resources/lua/demo.lua"/>
|
||||
</GROUP>
|
||||
|
@ -115,6 +118,10 @@
|
|||
<FILE id="CdKZCg" name="Matching.h" compile="0" resource="0" file="Source/chinese_postman/Matching.h"/>
|
||||
</GROUP>
|
||||
<GROUP id="{CD81913A-7F0E-5898-DA77-5EBEB369DEB1}" name="components">
|
||||
<FILE id="gPTmR4" name="AboutComponent.cpp" compile="1" resource="0"
|
||||
file="Source/components/AboutComponent.cpp"/>
|
||||
<FILE id="vDlOTn" name="AboutComponent.h" compile="0" resource="0"
|
||||
file="Source/components/AboutComponent.h"/>
|
||||
<FILE id="M7wyTt" name="AudioRecordingComponent.h" compile="0" resource="0"
|
||||
file="Source/components/AudioRecordingComponent.h"/>
|
||||
<FILE id="kUinTt" name="ComponentList.cpp" compile="1" resource="0"
|
||||
|
|
Ładowanie…
Reference in New Issue