From d38fcaced500561dfd344756f1663fa121109635 Mon Sep 17 00:00:00 2001 From: James Ball Date: Sat, 2 Mar 2024 18:31:12 +0000 Subject: [PATCH] Add lua console clearing, pausing --- Resources/svg/pause.svg | 1 + Source/PluginEditor.cpp | 30 ++++++++--- Source/PluginEditor.h | 2 + Source/components/LuaConsole.cpp | 85 ++++++++++++++++++++++++-------- Source/components/LuaConsole.h | 19 +++++-- Source/lua/LuaParser.cpp | 2 +- Source/lua/LuaParser.h | 2 +- osci-render.jucer | 1 + 8 files changed, 110 insertions(+), 32 deletions(-) create mode 100644 Resources/svg/pause.svg diff --git a/Resources/svg/pause.svg b/Resources/svg/pause.svg new file mode 100644 index 0000000..c058118 --- /dev/null +++ b/Resources/svg/pause.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/Source/PluginEditor.cpp b/Source/PluginEditor.cpp index 8531cff..e2d2168 100644 --- a/Source/PluginEditor.cpp +++ b/Source/PluginEditor.cpp @@ -21,11 +21,10 @@ OscirenderAudioProcessorEditor::OscirenderAudioProcessorEditor(OscirenderAudioPr #endif addAndMakeVisible(console); + console.setConsoleOpen(false); - LuaParser::onPrint = [this](const juce::String& message) { - juce::MessageManager::callAsync([this, message] { - console.print(message); - }); + LuaParser::onPrint = [this](const std::string& message) { + console.print(message); }; if (!usingNativeMenuBar) { @@ -151,6 +150,10 @@ void OscirenderAudioProcessorEditor::paint(juce::Graphics& g) { if (lua.getBounds().getWidth() > 0 && lua.getBounds().getHeight() > 0) { ds.drawForRectangle(g, lua.getBounds()); } + + if (console.getBounds().getWidth() > 0 && console.getBounds().getHeight() > 0) { + ds.drawForRectangle(g, console.getBounds()); + } } void OscirenderAudioProcessorEditor::resized() { @@ -208,8 +211,8 @@ void OscirenderAudioProcessorEditor::resized() { juce::Component* rows[] = { &dummy3, &luaResizerBar, &lua }; luaLayout.layOutComponents(rows, 3, dummy2Bounds.getX(), dummy2Bounds.getY(), dummy2Bounds.getWidth(), dummy2Bounds.getHeight(), true, true); auto dummy3Bounds = dummy3.getBounds(); - console.setBounds(dummy3Bounds.removeFromBottom(200)); - dummy3Bounds.removeFromBottom(5); + console.setBounds(dummy3Bounds.removeFromBottom(console.getConsoleOpen() ? 200 : 30)); + dummy3Bounds.removeFromBottom(RESIZER_BAR_SIZE); codeEditors[index]->setBounds(dummy3Bounds); } else { codeEditors[index]->setBounds(dummy2Bounds); @@ -452,6 +455,21 @@ bool OscirenderAudioProcessorEditor::keyPressed(const juce::KeyPress& key) { return consumeKey; } +void OscirenderAudioProcessorEditor::mouseDown(const juce::MouseEvent& e) { + if (console.getBoundsInParent().removeFromTop(30).contains(e.getPosition())) { + console.setConsoleOpen(!console.getConsoleOpen()); + resized(); + } +} + +void OscirenderAudioProcessorEditor::mouseMove(const juce::MouseEvent& event) { + if (console.getBoundsInParent().removeFromTop(30).contains(event.getPosition())) { + setMouseCursor(juce::MouseCursor::PointingHandCursor); + } else { + setMouseCursor(juce::MouseCursor::NormalCursor); + } +} + void OscirenderAudioProcessorEditor::newProject() { // TODO: open a default project } diff --git a/Source/PluginEditor.h b/Source/PluginEditor.h index 3272f34..82c47c4 100644 --- a/Source/PluginEditor.h +++ b/Source/PluginEditor.h @@ -91,6 +91,8 @@ public: void updateCodeEditor(); bool keyPressed(const juce::KeyPress& key) override; + void mouseDown(const juce::MouseEvent& event) override; + void mouseMove(const juce::MouseEvent& event) override; JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (OscirenderAudioProcessorEditor) }; diff --git a/Source/components/LuaConsole.cpp b/Source/components/LuaConsole.cpp index a7273c9..f1461ad 100644 --- a/Source/components/LuaConsole.cpp +++ b/Source/components/LuaConsole.cpp @@ -4,41 +4,84 @@ LuaConsole::LuaConsole() { setText("Lua Console"); - console.setMultiLine(true); console.setReadOnly(true); - console.setCaretVisible(false); - - console.setColour(juce::TextEditor::backgroundColourId, juce::Colours::black); - console.setColour(juce::TextEditor::textColourId, juce::Colours::white); - console.setColour(juce::TextEditor::outlineColourId, juce::Colours::white); - console.setColour(juce::TextEditor::focusedOutlineColourId, juce::Colours::white); - console.setColour(juce::TextEditor::highlightColourId, juce::Colours::white); - console.setColour(juce::TextEditor::highlightedTextColourId, juce::Colours::black); - console.setColour(juce::TextEditor::shadowColourId, juce::Colours::black); + console.setLineNumbersShown(false); + console.setScrollbarThickness(0); + document.getUndoManager().setMaxNumberOfStoredUnits(0, 0); + + startTimerHz(10); + + clearConsoleButton.onClick = [this] { + clear(); + }; addAndMakeVisible(console); + addAndMakeVisible(clearConsoleButton); + addAndMakeVisible(pauseConsoleButton); + + pauseConsoleButton.onClick = [this] { + console.setScrollbarThickness(pauseConsoleButton.getToggleState() ? 10 : 0); + }; } LuaConsole::~LuaConsole() {} -void LuaConsole::print(const juce::String& text) { - console.moveCaretToEnd(); - console.insertTextAtCaret(text); +void LuaConsole::print(const std::string& text) { + juce::SpinLock::ScopedLockType l(lock); - // clear start of console if it gets too long - if (console.getTotalNumChars() > 10000) { - console.setHighlightedRegion(juce::Range(0, 1000)); - console.deleteBackwards(true); - console.moveCaretToEnd(); + if (consoleOpen && !pauseConsoleButton.getToggleState()) { + buffer += text + "\n"; + consoleLines++; } - } void LuaConsole::clear() { - console.clear(); + juce::SpinLock::ScopedLockType l(lock); + + document.replaceAllContent(""); + document.clearUndoHistory(); + consoleLines = 0; + buffer.clear(); +} + +void LuaConsole::timerCallback() { + juce::SpinLock::ScopedLockType l(lock); + + if (consoleOpen && !pauseConsoleButton.getToggleState()) { + document.insertText(juce::CodeDocument::Position(document, std::numeric_limits::max(), std::numeric_limits::max()), buffer); + buffer.clear(); + + // clear console if it gets too long + if (consoleLines > 100000) { + // soft-clear console + int linesToClear = consoleLines * 0.9; + document.deleteSection(juce::CodeDocument::Position(document, 0, 0), juce::CodeDocument::Position(document, linesToClear, 0)); + consoleLines -= linesToClear; + } + + console.moveCaretToTop(false); + console.moveCaretToEnd(false); + console.scrollDown(); + } +} + +void LuaConsole::setConsoleOpen(bool open) { + juce::SpinLock::ScopedLockType l(lock); + + consoleOpen = open; + console.setVisible(open); + if (open) { + startTimerHz(10); + } else { + stopTimer(); + } } void LuaConsole::resized() { - auto area = getLocalBounds().withTrimmedTop(20); + auto topBar = getLocalBounds().removeFromTop(30); + auto area = getLocalBounds().withTrimmedTop(30); console.setBounds(area); + + clearConsoleButton.setBounds(topBar.removeFromRight(30).withSizeKeepingCentre(20, 20)); + pauseConsoleButton.setBounds(topBar.removeFromRight(30).withSizeKeepingCentre(20, 20)); } diff --git a/Source/components/LuaConsole.h b/Source/components/LuaConsole.h index 2220ad7..166d8d8 100644 --- a/Source/components/LuaConsole.h +++ b/Source/components/LuaConsole.h @@ -2,19 +2,32 @@ #include #include "../PluginProcessor.h" +#include "SvgButton.h" +#include "../LookAndFeel.h" -class LuaConsole : public juce::GroupComponent { +class LuaConsole : public juce::GroupComponent, public juce::Timer { public: LuaConsole(); ~LuaConsole(); - void print(const juce::String& text); + void print(const std::string& text); void clear(); + void timerCallback() override; + void setConsoleOpen(bool open); + bool getConsoleOpen() { return consoleOpen; } void resized() override; private: - juce::TextEditor console; + bool consoleOpen = false; + juce::SpinLock lock; + std::string buffer; + juce::CodeDocument document; + juce::CodeEditorComponent console = { document, nullptr }; + int consoleLines = 0; + + SvgButton clearConsoleButton { "clearConsole", juce::String(BinaryData::delete_svg), juce::Colours::red }; + SvgButton pauseConsoleButton { "pauseConsole", juce::String(BinaryData::pause_svg), juce::Colours::white, Colours::accentColor }; JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(LuaConsole) }; diff --git a/Source/lua/LuaParser.cpp b/Source/lua/LuaParser.cpp index d800ba9..5515afc 100644 --- a/Source/lua/LuaParser.cpp +++ b/Source/lua/LuaParser.cpp @@ -1,7 +1,7 @@ #include "LuaParser.h" #include "luaimport.h" -std::function LuaParser::onPrint; +std::function LuaParser::onPrint; static int customPrint(lua_State* L) { int nargs = lua_gettop(L); diff --git a/Source/lua/LuaParser.h b/Source/lua/LuaParser.h index ca7cd6a..d78e6aa 100644 --- a/Source/lua/LuaParser.h +++ b/Source/lua/LuaParser.h @@ -69,7 +69,7 @@ void resetErrors(); void close(lua_State*& L); - static std::function onPrint; + static std::function onPrint; private: void reset(lua_State*& L, juce::String script); diff --git a/osci-render.jucer b/osci-render.jucer index 60883fe..5b9ab36 100644 --- a/osci-render.jucer +++ b/osci-render.jucer @@ -23,6 +23,7 @@ +