diff --git a/Source/PluginEditor.cpp b/Source/PluginEditor.cpp index 14fe7fb..44115fa 100644 --- a/Source/PluginEditor.cpp +++ b/Source/PluginEditor.cpp @@ -8,6 +8,7 @@ OscirenderAudioProcessorEditor::OscirenderAudioProcessorEditor(OscirenderAudioPr addAndMakeVisible(main); addChildComponent(lua); addChildComponent(obj); + addChildComponent(txt); addAndMakeVisible(volume); menuBar.setModel(&menuBarModel); @@ -135,10 +136,11 @@ void OscirenderAudioProcessorEditor::resized() { auto effectsSection = area.removeFromRight(1.2 * getWidth() / sections); main.setBounds(area.reduced(5)); - if (lua.isVisible() || obj.isVisible()) { - auto altEffectsSection = effectsSection.removeFromBottom(juce::jmin(effectsSection.getHeight() / 2, 300)); + if (lua.isVisible() || obj.isVisible() || txt.isVisible()) { + auto altEffectsSection = effectsSection.removeFromBottom(juce::jmin(effectsSection.getHeight() / 2, txt.isVisible() ? 150 : 300)); lua.setBounds(altEffectsSection.reduced(5)); obj.setBounds(altEffectsSection.reduced(5)); + txt.setBounds(altEffectsSection.reduced(5)); } effects.setBounds(effectsSection.reduced(5)); @@ -214,13 +216,16 @@ void OscirenderAudioProcessorEditor::fileUpdated(juce::String fileName) { juce::String extension = fileName.fromLastOccurrenceOf(".", true, false); lua.setVisible(false); obj.setVisible(false); + txt.setVisible(false); if (fileName.isEmpty()) { // do nothing } else if (extension == ".lua") { lua.setVisible(true); } else if (extension == ".obj") { obj.setVisible(true); - } + } else if (extension == ".txt") { + txt.setVisible(true); + } main.updateFileLabel(); updateCodeEditor(); } diff --git a/Source/PluginEditor.h b/Source/PluginEditor.h index 062e8e3..149d0ab 100644 --- a/Source/PluginEditor.h +++ b/Source/PluginEditor.h @@ -6,6 +6,7 @@ #include "MainComponent.h" #include "LuaComponent.h" #include "ObjComponent.h" +#include "TxtComponent.h" #include "components/VolumeComponent.h" #include "components/MainMenuBarModel.h" #include "LookAndFeel.h" @@ -43,6 +44,7 @@ private: MainComponent main{audioProcessor, *this}; LuaComponent lua{audioProcessor, *this}; ObjComponent obj{audioProcessor, *this}; + TxtComponent txt{audioProcessor, *this}; EffectsComponent effects{audioProcessor, *this}; VolumeComponent volume{audioProcessor}; std::vector> codeDocuments; diff --git a/Source/PluginProcessor.cpp b/Source/PluginProcessor.cpp index fd53982..55aca71 100644 --- a/Source/PluginProcessor.cpp +++ b/Source/PluginProcessor.cpp @@ -355,7 +355,8 @@ void OscirenderAudioProcessor::openFile(int index) { if (index < 0 || index >= fileBlocks.size()) { return; } - parsers[index]->parse(fileNames[index].fromLastOccurrenceOf(".", true, false), std::make_unique(*fileBlocks[index], false)); + juce::SpinLock::ScopedLockType lock(fontLock); + parsers[index]->parse(fileNames[index].fromLastOccurrenceOf(".", true, false), std::make_unique(*fileBlocks[index], false), font); changeCurrentFile(index); } diff --git a/Source/PluginProcessor.h b/Source/PluginProcessor.h index 43a9840..c511b99 100644 --- a/Source/PluginProcessor.h +++ b/Source/PluginProcessor.h @@ -180,6 +180,9 @@ public: // so should only be accessed by message thread juce::String currentProjectFile; + juce::SpinLock fontLock; + juce::Font font = juce::Font(juce::Font::getDefaultSansSerifFontName(), 1.0f, juce::Font::plain); + void addLuaSlider(); void addFrame(std::vector> frame, int fileIndex) override; void updateEffectPrecedence(); @@ -190,6 +193,7 @@ public: void removeFile(int index); int numFiles(); void changeCurrentFile(int index); + void openFile(int index); int getCurrentFileIndex(); std::shared_ptr getCurrentFileParser(); juce::String getCurrentFileName(); @@ -244,7 +248,6 @@ private: void updateFrame(); void updateLengthIncrement(); void incrementShapeDrawing(); - void openFile(int index); void updateLuaValues(); void updateObjValues(); std::shared_ptr getEffect(juce::String id); diff --git a/Source/TxtComponent.cpp b/Source/TxtComponent.cpp new file mode 100644 index 0000000..b9d4363 --- /dev/null +++ b/Source/TxtComponent.cpp @@ -0,0 +1,51 @@ +#include "TxtComponent.h" +#include "PluginEditor.h" + +TxtComponent::TxtComponent(OscirenderAudioProcessor& p, OscirenderAudioProcessorEditor& editor) : audioProcessor(p), pluginEditor(editor) { + setText(".txt File Settings"); + + addAndMakeVisible(font); + addAndMakeVisible(bold); + addAndMakeVisible(italic); + + for (int i = 0; i < installedFonts.size(); i++) { + font.addItem(installedFonts[i], i + 1); + } + + { + juce::SpinLock::ScopedLockType lock(audioProcessor.fontLock); + juce::String defaultFont = audioProcessor.font.getTypefaceName(); + int index = installedFonts.indexOf(defaultFont); + if (index == -1) { + index = 0; + } + font.setSelectedItemIndex(index); + bold.setToggleState(audioProcessor.font.isBold(), juce::dontSendNotification); + italic.setToggleState(audioProcessor.font.isItalic(), juce::dontSendNotification); + } + + auto updateFont = [this]() { + juce::SpinLock::ScopedLockType lock1(audioProcessor.parsersLock); + juce::SpinLock::ScopedLockType lock2(audioProcessor.effectsLock); + { + juce::SpinLock::ScopedLockType lock3(audioProcessor.fontLock); + audioProcessor.font.setTypefaceName(installedFonts[font.getSelectedItemIndex()]); + audioProcessor.font.setBold(bold.getToggleState()); + audioProcessor.font.setItalic(italic.getToggleState()); + } + + audioProcessor.openFile(audioProcessor.currentFile); + }; + + font.onChange = updateFont; + bold.onClick = updateFont; + italic.onClick = updateFont; +} + +void TxtComponent::resized() { + auto area = getLocalBounds().withTrimmedTop(20).reduced(20); + double rowHeight = 30; + font.setBounds(area.removeFromTop(rowHeight)); + bold.setBounds(area.removeFromTop(rowHeight)); + italic.setBounds(area.removeFromTop(rowHeight)); +} diff --git a/Source/TxtComponent.h b/Source/TxtComponent.h new file mode 100644 index 0000000..e92d304 --- /dev/null +++ b/Source/TxtComponent.h @@ -0,0 +1,23 @@ +#pragma once + +#include +#include "PluginProcessor.h" + +class OscirenderAudioProcessorEditor; +class TxtComponent : public juce::GroupComponent, public juce::MouseListener { +public: + TxtComponent(OscirenderAudioProcessor&, OscirenderAudioProcessorEditor&); + + void resized() override; +private: + OscirenderAudioProcessor& audioProcessor; + OscirenderAudioProcessorEditor& pluginEditor; + + juce::StringArray installedFonts = juce::Font::findAllTypefaceNames(); + + juce::ComboBox font; + juce::ToggleButton bold{"Bold"}; + juce::ToggleButton italic{"Italic"}; + + JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(TxtComponent) +}; \ No newline at end of file diff --git a/Source/parser/FileParser.cpp b/Source/parser/FileParser.cpp index 7683c74..12d411d 100644 --- a/Source/parser/FileParser.cpp +++ b/Source/parser/FileParser.cpp @@ -5,7 +5,7 @@ FileParser::FileParser() {} -void FileParser::parse(juce::String extension, std::unique_ptr stream) { +void FileParser::parse(juce::String extension, std::unique_ptr stream, juce::Font font) { juce::SpinLock::ScopedLockType scope(lock); object = nullptr; @@ -21,7 +21,7 @@ void FileParser::parse(juce::String extension, std::unique_ptr(stream->readEntireStreamAsString()); } else if (extension == ".txt") { - text = std::make_shared(stream->readEntireStreamAsString(), juce::Font(1.0f)); + text = std::make_shared(stream->readEntireStreamAsString(), font); } else if (extension == ".lua") { lua = std::make_shared(stream->readEntireStreamAsString()); } diff --git a/Source/parser/FileParser.h b/Source/parser/FileParser.h index 28e642b..9d87668 100644 --- a/Source/parser/FileParser.h +++ b/Source/parser/FileParser.h @@ -8,17 +8,17 @@ #include "../txt/TextParser.h" #include "../lua/LuaParser.h" -class FileParser : public FrameSource { +class FileParser { public: FileParser(); - void parse(juce::String extension, std::unique_ptr) override; - std::vector> nextFrame() override; - Vector2 nextSample() override; - bool isSample() override; - bool isActive() override; - void disable() override; - void enable() override; + void parse(juce::String extension, std::unique_ptr, juce::Font); + std::vector> nextFrame(); + Vector2 nextSample(); + bool isSample(); + bool isActive(); + void disable(); + void enable(); std::shared_ptr getObject(); std::shared_ptr getCamera(); diff --git a/Source/parser/FrameProducer.cpp b/Source/parser/FrameProducer.cpp index 30e0bd5..38828bb 100644 --- a/Source/parser/FrameProducer.cpp +++ b/Source/parser/FrameProducer.cpp @@ -1,6 +1,6 @@ #include "FrameProducer.h" -FrameProducer::FrameProducer(FrameConsumer& fc, std::shared_ptr fs) : frameConsumer(fc), frameSource(fs), juce::Thread("producer", 0) {} +FrameProducer::FrameProducer(FrameConsumer& fc, std::shared_ptr fs) : frameConsumer(fc), frameSource(fs), juce::Thread("producer", 0) {} FrameProducer::~FrameProducer() { frameSource->disable(); @@ -15,7 +15,7 @@ void FrameProducer::run() { } } -void FrameProducer::setSource(std::shared_ptr source, int fileIndex) { +void FrameProducer::setSource(std::shared_ptr source, int fileIndex) { juce::SpinLock::ScopedLockType scope(lock); frameSource->disable(); frameSource = source; diff --git a/Source/parser/FrameProducer.h b/Source/parser/FrameProducer.h index 873c6f4..0057830 100644 --- a/Source/parser/FrameProducer.h +++ b/Source/parser/FrameProducer.h @@ -1,19 +1,19 @@ #pragma once #include -#include "FrameSource.h" +#include "FileParser.h" #include "FrameConsumer.h" class FrameProducer : public juce::Thread { public: - FrameProducer(FrameConsumer&, std::shared_ptr); + FrameProducer(FrameConsumer&, std::shared_ptr); ~FrameProducer() override; void run() override; - void setSource(std::shared_ptr, int fileIndex); + void setSource(std::shared_ptr, int fileIndex); private: juce::SpinLock lock; FrameConsumer& frameConsumer; - std::shared_ptr frameSource; + std::shared_ptr frameSource; int sourceFileIndex = -1; }; \ No newline at end of file diff --git a/Source/parser/FrameSource.h b/Source/parser/FrameSource.h index a15ff04..02490a4 100644 --- a/Source/parser/FrameSource.h +++ b/Source/parser/FrameSource.h @@ -7,7 +7,6 @@ class FrameSource { public: - virtual void parse(juce::String extension, std::unique_ptr) = 0; virtual std::vector> nextFrame() = 0; virtual Vector2 nextSample() = 0; virtual bool isSample() = 0; diff --git a/osci-render.jucer b/osci-render.jucer index a352979..653d8a3 100644 --- a/osci-render.jucer +++ b/osci-render.jucer @@ -435,6 +435,9 @@ + +