From 6863b3761890cf0fffeb5064a6899fbf550dcbe2 Mon Sep 17 00:00:00 2001 From: blancoberg Date: Sun, 8 Dec 2024 18:14:38 +0100 Subject: [PATCH 1/5] code editor search Code editor search --- src/surge-xt/gui/overlays/LuaEditors.cpp | 383 ++++++++++++++++++++--- src/surge-xt/gui/overlays/LuaEditors.h | 57 +++- 2 files changed, 387 insertions(+), 53 deletions(-) diff --git a/src/surge-xt/gui/overlays/LuaEditors.cpp b/src/surge-xt/gui/overlays/LuaEditors.cpp index 8651cbafb5c..ec27cd2b84c 100644 --- a/src/surge-xt/gui/overlays/LuaEditors.cpp +++ b/src/surge-xt/gui/overlays/LuaEditors.cpp @@ -41,83 +41,349 @@ namespace Surge namespace Overlays { -struct SurgeCodeEditorComponent : public juce::CodeEditorComponent +/* + --------------------------------------- + Search box + --------------------------------------- +*/ + +CodeEditorSearch::CodeEditorSearch(juce::CodeEditorComponent &editor, Surge::GUI::Skin::ptr_t skin) + : juce::TextEditor(), juce::TextEditor::Listener(), Surge::GUI::SkinConsumingComponent() { - SurgeCodeEditorComponent(juce::CodeDocument &d, juce::CodeTokeniser *t) - : juce::CodeEditorComponent(d, t) + ed = &editor; + currentSkin = skin; + + juce::Rectangle boundsLabel = juce::Rectangle(95, 2, 50, 20); + + labelResult = std::make_unique(); + + labelResult->setBounds(boundsLabel); + labelResult->setFont(juce::FontOptions(10)); + labelResult->setJustificationType(juce::Justification::right); + labelResult->setColour(juce::Label::textColourId, skin->getColor(Colors::Dialog::Button::Text)); + + addAndMakeVisible(*labelResult); + + setBorder(juce::BorderSize(2, 5, 2, 5)); + setFont(juce::FontOptions(12)); + setColour(juce::TextEditor::ColourIds::textColourId, + skin->getColor(Colors::Dialog::Button::Text)); + setColour(juce::TextEditor::backgroundColourId, + skin->getColor(Colors::Dialog::Button::Background)); + + setTitle(""); + setText(""); + + setEscapeAndReturnKeysConsumed(true); + + addListener(this); + + juce::Rectangle bounds = juce::Rectangle(0, 0, 150, 20); + setBounds(bounds); + + setVisible(false); +} + +void CodeEditorSearch::paint(juce::Graphics &g) +{ + juce::TextEditor::paint(g); + + // magnifying glass + + if (associatedBitmapStore != nullptr) { + // auto magnifyingGlass = associatedBitmapStore->getImage(IDB_SEARCH_BUTTON); + // magnifyingGlass->drawAt(g, 0, 0, 1); + // g.drawImage(magnifyingGlass->asJuceImage(), 0, 0, 20, 20, 0, 0, 20, 20, false); } - void handleEscapeKey() override + // todo draw all matches +} + +bool CodeEditorSearch::isActive() { return active; } + +void CodeEditorSearch::mouseDown(const juce::MouseEvent &event) { saveCaretStartPosition(true); } + +void CodeEditorSearch::saveCaretStartPosition(bool onlyReadCaretPosition) +{ + + if (!saveCaretStartPositionLock && + onlyReadCaretPosition == false) // prevent caretMoved feedback loop { - juce::Component *c = this; - while (c) + saveCaretStartPositionLock = true; + auto sel = ed->getHighlightedRegion(); + + if (sel.getEnd() - sel.getStart() != 0) { - if (auto fm = dynamic_cast(c)) + + // move caret to beginning of selected + if (ed->getCaretPosition() > sel.getStart()) { - fm->escapeKeyPressed(); - return; + juce::CodeDocument::Position pos = + juce::CodeDocument::Position(ed->getDocument(), sel.getStart()); + ed->moveCaretTo(pos, false); } - c = c->getParentComponent(); } + startCaretPosition = ed->getCaretPos(); + + saveCaretStartPositionLock = false; } - // Handles auto indentation + if (onlyReadCaretPosition && !saveCaretStartPositionLock) + { + startCaretPosition = ed->getCaretPos(); + } +} + +void CodeEditorSearch::focusLost(FocusChangeType) +{ + removeHighlightColors(); + ed->repaint(); +} + +void CodeEditorSearch::setHighlightColors() +{ + auto color = skin->getColor(Colors::FormulaEditor::Background); + + ed->setColour(juce::CodeEditorComponent::highlightColourId, + color.interpolatedWith(juce::Colour(108, 147, 25), 0.5)); +} - void handleReturnKey() override +void CodeEditorSearch::removeHighlightColors() +{ + ed->setColour(juce::CodeEditorComponent::highlightColourId, + skin->getColor(Colors::FormulaEditor::Highlight)); +} + +void CodeEditorSearch::show() +{ + // set selected text as search query unless it includes a newline character + auto sel = ed->getHighlightedRegion(); + juce::String txt = ed->getTextInRange(sel); + + saveCaretStartPosition(false); + + if (!txt.containsChar('\n') && sel.getLength() != 0) { + setText(txt); + } + + moveCaretToStartOfLine(false); + moveCaretToEndOfLine(true); + + setVisible(true); + search(); + grabKeyboardFocus(); + ed->repaint(); // force update selection color +} + +void CodeEditorSearch::textEditorEscapeKeyPressed(TextEditor &) { hide(); } +void CodeEditorSearch::textEditorReturnKeyPressed(TextEditor &) {} - auto pos = this->getCaretPos(); - auto txt = pos.getLineText(); - int tabs = 0; +bool CodeEditorSearch::keyPressed(const juce::KeyPress &key) +{ + juce::TextEditor::keyPressed(key); - for (int i = 0; i < txt.length(); i++) + if (key.getKeyCode() == key.returnKey) + { + if (key.getModifiers().isShiftDown()) { - if (txt.substring(i, i + 1) == " ") + showResult(-1, true); + } + else + { + showResult(1, true); + } + } + + if (key.getKeyCode() == key.escapeKey) + { + hide(); + return true; + } + + if (key.getModifiers().isCommandDown() && key.getKeyCode() == 70) + { + return true; + } + + return true; +} + +void CodeEditorSearch::hide() +{ + removeHighlightColors(); + setVisible(false); +} + +void CodeEditorSearch::textEditorTextChanged(juce::TextEditor &textEditor) { search(); } + +void CodeEditorSearch::showResult(int increment, bool moveCaret) +{ + int id = resultCurrent + 1; + if (resultTotal == 0) + { + removeHighlightColors(); + id = 0; + setColour(juce::TextEditor::focusedOutlineColourId, juce::Colour(204, 70, 70)); + setColour(juce::TextEditor::outlineColourId, + skin->getColor(Colors::FormulaEditor::Debugger::Text)); + } + else + { + setHighlightColors(); + setColour(juce::TextEditor::focusedOutlineColourId, + skin->getColor(Colors::FormulaEditor::Debugger::Text)); + setColour(juce::TextEditor::outlineColourId, + skin->getColor(Colors::FormulaEditor::Debugger::Text)); + } + + labelResult->setText(juce::String(std::to_string(id) + '/' + std::to_string(resultTotal)), + juce::NotificationType::dontSendNotification); + + repaint(); + + if (resultTotal == 0) + return; + + resultCurrent = (resultCurrent + increment + resultTotal) % resultTotal; + + saveCaretStartPositionLock = true; + ed->setHighlightedRegion( + juce::Range(result[resultCurrent], result[resultCurrent] + getTotalNumChars())); + saveCaretStartPositionLock = false; +} + +void CodeEditorSearch::resize() +{ + juce::Rectangle bounds = juce::Rectangle(ed->getBounds().getWidth() - 150 - 10, 6, 150, 24); + setBounds(bounds); +} + +void CodeEditorSearch::search() +{ + // move to start pos + saveCaretStartPositionLock = true; + ed->moveCaretTo(startCaretPosition, false); + saveCaretStartPositionLock = false; + + auto caret = ed->getCaretPos(); + + int caretPos = caret.getPosition(); + + juce::String txt = ed->getDocument().getAllContent(); + int pos = 0; + int count = 0; + int res = txt.indexOfIgnoreCase(pos, getText()); + resultCurrent = 0; + bool firstFound = false; + while (res != -1 && count < 128) + { + + result[count] = res; + if (caretPos <= res && !firstFound) + { + resultCurrent = count; + firstFound = true; + } + + pos = res + 1; + res = txt.indexOfIgnoreCase(pos, getText()); + + count++; + } + + resultTotal = count; + showResult(0, true); +} + +/* + --------------------------------------- + end search + --------------------------------------- +*/ + +SurgeCodeEditorComponent::SurgeCodeEditorComponent(juce::CodeDocument &d, juce::CodeTokeniser *t) + : juce::CodeEditorComponent(d, t) +{ +} + +void SurgeCodeEditorComponent::setSearch(CodeEditorSearch &s) { search = &s; } + +void SurgeCodeEditorComponent::handleEscapeKey() +{ + if (search->isVisible()) + { + search->hide(); + return; + } + juce::Component *c = this; + while (c) + { + if (auto fm = dynamic_cast(c)) + { + fm->escapeKeyPressed(); + return; + } + c = c->getParentComponent(); + } +} + +void SurgeCodeEditorComponent::caretPositionMoved() { search->saveCaretStartPosition(true); } + +// Handles auto indentation + +void SurgeCodeEditorComponent::handleReturnKey() +{ + + auto pos = this->getCaretPos(); + auto txt = pos.getLineText(); + int tabs = 0; + + for (int i = 0; i < txt.length(); i++) + { + if (txt.substring(i, i + 1) == " ") + { + tabs++; + } + else if (txt.substring(i, i + 1) == "\t") + { + tabs += this->getTabSize(); + } + else + { + bool indent = false; + auto trimmedTxt = txt.trim(); + + if (txt.substring(i, i + 8) == "function") { - tabs++; + + indent = true; } - else if (txt.substring(i, i + 1) == "\t") + else if (txt.substring(i, i + 2) == "if" && + trimmedTxt.substring(trimmedTxt.length() - 4, trimmedTxt.length()) == "then") { - tabs += this->getTabSize(); + indent = true; } - else + else if (trimmedTxt.substring(0, 4) == "else") { - bool indent = false; - auto trimmedTxt = txt.trim(); - - if (txt.substring(i, i + 8) == "function") - { - - indent = true; - } - else if (txt.substring(i, i + 2) == "if" && - trimmedTxt.substring(trimmedTxt.length() - 4, trimmedTxt.length()) == - "then") - { - indent = true; - } - else if (trimmedTxt.substring(0, 4) == "else") - { - indent = true; - } - else if (trimmedTxt.substring(trimmedTxt.length() - 2, trimmedTxt.length()) == - "do" || - trimmedTxt.substring(0, 5) == "while") - { - indent = true; - } + indent = true; + } + else if (trimmedTxt.substring(trimmedTxt.length() - 2, trimmedTxt.length()) == "do" || + trimmedTxt.substring(0, 5) == "while") + { + indent = true; + } - tabs += indent == true ? this->getTabSize() : 0; + tabs += indent == true ? this->getTabSize() : 0; - break; - } + break; } - - this->insertTextAtCaret("\n"); - this->insertTextAtCaret(std::string(tabs, ' ')); } -}; + + this->insertTextAtCaret("\n"); + this->insertTextAtCaret(std::string(tabs, ' ')); +} struct EditorColors { @@ -171,12 +437,16 @@ CodeEditorContainerWithApply::CodeEditorContainerWithApply(SurgeGUIEditor *ed, S mainEditor = std::make_unique(*mainDocument, tokenizer.get()); mainEditor->setTabSize(4, true); mainEditor->addKeyListener(this); + EditorColors::setColorsFromSkin(mainEditor.get(), skin); + search = std::make_unique(*mainEditor, skin); + mainEditor->setSearch(*search); if (addComponents) { addAndMakeVisible(applyButton.get()); addAndMakeVisible(mainEditor.get()); + addChildComponent(search.get()); } applyButton->setEnabled(false); @@ -193,6 +463,7 @@ void CodeEditorContainerWithApply::buttonClicked(juce::Button *button) void CodeEditorContainerWithApply::onSkinChanged() { mainEditor->setFont(skin->getFont(Fonts::LuaEditor::Code)); + search->setSkin(skin); EditorColors::setColorsFromSkin(mainEditor.get(), skin); } @@ -285,6 +556,8 @@ bool CodeEditorContainerWithApply::keyPressed(const juce::KeyPress &key, juce::C // search else if (key.getModifiers().isCommandDown() && keyCode == 70) { + search->show(); + /* search for characters and use getCharacterBounds to get its screen position */ @@ -909,6 +1182,7 @@ FormulaModulatorEditor::FormulaModulatorEditor(SurgeGUIEditor *ed, SurgeStorage controlArea = std::make_unique(this, editor); addAndMakeVisible(*controlArea); addAndMakeVisible(*mainEditor); + addChildComponent(*search); addChildComponent(*preludeDisplay); debugPanel = std::make_unique(this); @@ -1005,6 +1279,8 @@ void FormulaModulatorEditor::resized() height - 4 - controlHeight); } controlArea->setBounds(0, height - controlHeight, width, controlHeight); + + search->resize(); } void FormulaModulatorEditor::showModulatorCode() @@ -2002,6 +2278,8 @@ WavetableScriptEditor::WavetableScriptEditor(SurgeGUIEditor *ed, SurgeStorage *s controlArea = std::make_unique(this, editor); addAndMakeVisible(*controlArea); addAndMakeVisible(*mainEditor); + addChildComponent(*search); + addChildComponent(*preludeDisplay); rendererComponent = std::make_unique(this, editor, skin); @@ -2103,6 +2381,7 @@ void WavetableScriptEditor::resized() rendererComponent->setBounds(2, height - rendererHeight - controlHeight - 2, width - 2, rendererHeight); + search->resize(); rerenderFromUIState(); } diff --git a/src/surge-xt/gui/overlays/LuaEditors.h b/src/surge-xt/gui/overlays/LuaEditors.h index 12f4bce6b3f..37d37c34ab1 100644 --- a/src/surge-xt/gui/overlays/LuaEditors.h +++ b/src/surge-xt/gui/overlays/LuaEditors.h @@ -44,6 +44,59 @@ namespace Surge namespace Overlays { +class CodeEditorSearch : public juce::TextEditor, + public juce::TextEditor::Listener, + public Surge::GUI::SkinConsumingComponent +{ + private: + virtual void setHighlightColors(); + virtual void removeHighlightColors(); + juce::CodeEditorComponent *ed; + bool active = false; + int result[128]; + int resultCurrent; + int resultTotal; + bool saveCaretStartPositionLock; + Surge::GUI::Skin::ptr_t currentSkin; + + std::unique_ptr labelResult; + + juce::CodeDocument::Position startCaretPosition; + + virtual void search(); + + public: + virtual bool isActive(); + virtual void show(); + virtual void hide(); + virtual void resize(); + virtual void textEditorTextChanged(juce::TextEditor &textEditor); + virtual void mouseDown(const juce::MouseEvent &event) override; + virtual void focusLost(FocusChangeType) override; + + CodeEditorSearch(juce::CodeEditorComponent &editor, Surge::GUI::Skin::ptr_t); + virtual void textEditorEscapeKeyPressed(TextEditor &) override; + virtual void textEditorReturnKeyPressed(TextEditor &) override; + virtual bool keyPressed(const juce::KeyPress &key) override; + virtual void saveCaretStartPosition(bool onlyReadCaretPosition); + virtual void showResult(int increase, bool moveCaret); + virtual void paint(juce::Graphics &g) override; +}; + +class SurgeCodeEditorComponent : public juce::CodeEditorComponent +{ + public: + virtual void handleEscapeKey() override; + virtual void handleReturnKey() override; + virtual void caretPositionMoved() override; + + virtual void setSearch(CodeEditorSearch &s); + SurgeCodeEditorComponent(juce::CodeDocument &d, juce::CodeTokeniser *t); + + private: + CodeEditorSearch *search; +}; + /* * This is a base class that provides you an apply button, an editor, a document * a tokenizer, etc... which you need to layout with yoru other components by @@ -60,9 +113,11 @@ class CodeEditorContainerWithApply : public OverlayComponent, CodeEditorContainerWithApply(SurgeGUIEditor *ed, SurgeStorage *s, Surge::GUI::Skin::ptr_t sk, bool addComponents = false); std::unique_ptr mainDocument; - std::unique_ptr mainEditor; + std::unique_ptr mainEditor; std::unique_ptr applyButton; std::unique_ptr tokenizer; + std::unique_ptr search; + void buttonClicked(juce::Button *button) override; void codeDocumentTextDeleted(int startIndex, int endIndex) override; void codeDocumentTextInserted(const juce::String &newText, int insertIndex) override; From a7f2501bf92584f7c154354ceabc9e7eef5dd9b8 Mon Sep 17 00:00:00 2001 From: blancoberg Date: Sun, 8 Dec 2024 19:25:55 +0100 Subject: [PATCH 2/5] add override Missed a override --- src/surge-xt/gui/overlays/LuaEditors.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/surge-xt/gui/overlays/LuaEditors.h b/src/surge-xt/gui/overlays/LuaEditors.h index 37d37c34ab1..f1fd6629332 100644 --- a/src/surge-xt/gui/overlays/LuaEditors.h +++ b/src/surge-xt/gui/overlays/LuaEditors.h @@ -70,7 +70,7 @@ class CodeEditorSearch : public juce::TextEditor, virtual void show(); virtual void hide(); virtual void resize(); - virtual void textEditorTextChanged(juce::TextEditor &textEditor); + virtual void textEditorTextChanged(juce::TextEditor &textEditor) override; virtual void mouseDown(const juce::MouseEvent &event) override; virtual void focusLost(FocusChangeType) override; From 4a68e3ece878af725a29e53ddc03e568ffb33270 Mon Sep 17 00:00:00 2001 From: blancoberg Date: Mon, 9 Dec 2024 16:13:21 +0100 Subject: [PATCH 3/5] lua editor tab selection tab with selected text will add indentation to all lines in that selection --- src/surge-xt/gui/overlays/LuaEditors.cpp | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/surge-xt/gui/overlays/LuaEditors.cpp b/src/surge-xt/gui/overlays/LuaEditors.cpp index ec27cd2b84c..0540585140e 100644 --- a/src/surge-xt/gui/overlays/LuaEditors.cpp +++ b/src/surge-xt/gui/overlays/LuaEditors.cpp @@ -492,7 +492,16 @@ bool CodeEditorContainerWithApply::keyPressed(const juce::KeyPress &key, juce::C } else { - mainEditor->insertTabAtCaret(); + auto sel = mainEditor->getHighlightedRegion(); + + if (sel.getLength() == 0) + { + mainEditor->insertTabAtCaret(); + } + else + { + mainEditor->indentSelection(); + } } return true; @@ -558,9 +567,6 @@ bool CodeEditorContainerWithApply::keyPressed(const juce::KeyPress &key, juce::C { search->show(); - /* - search for characters and use getCharacterBounds to get its screen position - */ return true; } From 67fa38f617136452fd259fc8a9020697df74276c Mon Sep 17 00:00:00 2001 From: blancoberg Date: Mon, 9 Dec 2024 22:13:04 +0100 Subject: [PATCH 4/5] editor prelude fix Fixes editor prelude crash + some prep work for adding buttons to the searchbar --- src/surge-xt/gui/overlays/LuaEditors.cpp | 131 ++++++++++++----------- src/surge-xt/gui/overlays/LuaEditors.h | 15 +-- 2 files changed, 76 insertions(+), 70 deletions(-) diff --git a/src/surge-xt/gui/overlays/LuaEditors.cpp b/src/surge-xt/gui/overlays/LuaEditors.cpp index 0540585140e..2b6365ad770 100644 --- a/src/surge-xt/gui/overlays/LuaEditors.cpp +++ b/src/surge-xt/gui/overlays/LuaEditors.cpp @@ -48,12 +48,15 @@ namespace Overlays */ CodeEditorSearch::CodeEditorSearch(juce::CodeEditorComponent &editor, Surge::GUI::Skin::ptr_t skin) - : juce::TextEditor(), juce::TextEditor::Listener(), Surge::GUI::SkinConsumingComponent() + : juce::Component(), juce::TextEditor::Listener(), juce::KeyListener(), + Surge::GUI::SkinConsumingComponent() { ed = &editor; currentSkin = skin; - juce::Rectangle boundsLabel = juce::Rectangle(95, 2, 50, 20); + juce::Rectangle boundsLabel = juce::Rectangle(95, 2, 80, 20); + + textfield = std::make_unique(); labelResult = std::make_unique(); @@ -64,41 +67,31 @@ CodeEditorSearch::CodeEditorSearch(juce::CodeEditorComponent &editor, Surge::GUI addAndMakeVisible(*labelResult); - setBorder(juce::BorderSize(2, 5, 2, 5)); - setFont(juce::FontOptions(12)); - setColour(juce::TextEditor::ColourIds::textColourId, - skin->getColor(Colors::Dialog::Button::Text)); - setColour(juce::TextEditor::backgroundColourId, - skin->getColor(Colors::Dialog::Button::Background)); + textfield->setBorder(juce::BorderSize(2, 5, 2, 5)); + textfield->setFont(juce::FontOptions(12)); + textfield->setColour(juce::TextEditor::ColourIds::textColourId, + skin->getColor(Colors::Dialog::Button::Text)); + textfield->setColour(juce::TextEditor::backgroundColourId, + skin->getColor(Colors::Dialog::Button::Background)); + + addAndMakeVisible(*textfield); - setTitle(""); - setText(""); + textfield->setTitle(""); + textfield->setText(""); - setEscapeAndReturnKeysConsumed(true); + textfield->setEscapeAndReturnKeysConsumed(true); - addListener(this); + textfield->addListener(this); + textfield->addKeyListener(this); juce::Rectangle bounds = juce::Rectangle(0, 0, 150, 20); setBounds(bounds); setVisible(false); + resize(); } -void CodeEditorSearch::paint(juce::Graphics &g) -{ - juce::TextEditor::paint(g); - - // magnifying glass - - if (associatedBitmapStore != nullptr) - { - // auto magnifyingGlass = associatedBitmapStore->getImage(IDB_SEARCH_BUTTON); - // magnifyingGlass->drawAt(g, 0, 0, 1); - // g.drawImage(magnifyingGlass->asJuceImage(), 0, 0, 20, 20, 0, 0, 20, 20, false); - } - - // todo draw all matches -} +void CodeEditorSearch::paint(juce::Graphics &g) {} bool CodeEditorSearch::isActive() { return active; } @@ -107,31 +100,34 @@ void CodeEditorSearch::mouseDown(const juce::MouseEvent &event) { saveCaretStart void CodeEditorSearch::saveCaretStartPosition(bool onlyReadCaretPosition) { - if (!saveCaretStartPositionLock && - onlyReadCaretPosition == false) // prevent caretMoved feedback loop + if (!ed->isReadOnly()) { - saveCaretStartPositionLock = true; - auto sel = ed->getHighlightedRegion(); - - if (sel.getEnd() - sel.getStart() != 0) + if (!saveCaretStartPositionLock && + onlyReadCaretPosition == false) // prevent caretMoved feedback loop { + saveCaretStartPositionLock = true; + auto sel = ed->getHighlightedRegion(); - // move caret to beginning of selected - if (ed->getCaretPosition() > sel.getStart()) + if (sel.getEnd() - sel.getStart() != 0) { - juce::CodeDocument::Position pos = - juce::CodeDocument::Position(ed->getDocument(), sel.getStart()); - ed->moveCaretTo(pos, false); + + // move caret to beginning of selected + if (ed->getCaretPosition() > sel.getStart()) + { + juce::CodeDocument::Position pos = + juce::CodeDocument::Position(ed->getDocument(), sel.getStart()); + ed->moveCaretTo(pos, false); + } } - } - startCaretPosition = ed->getCaretPos(); + startCaretPosition = ed->getCaretPos(); - saveCaretStartPositionLock = false; - } + saveCaretStartPositionLock = false; + } - if (onlyReadCaretPosition && !saveCaretStartPositionLock) - { - startCaretPosition = ed->getCaretPos(); + if (onlyReadCaretPosition && !saveCaretStartPositionLock) + { + startCaretPosition = ed->getCaretPos(); + } } } @@ -165,24 +161,24 @@ void CodeEditorSearch::show() if (!txt.containsChar('\n') && sel.getLength() != 0) { - setText(txt); + textfield->setText(txt); } - moveCaretToStartOfLine(false); - moveCaretToEndOfLine(true); + textfield->moveCaretToStartOfLine(false); + textfield->moveCaretToEndOfLine(true); setVisible(true); search(); - grabKeyboardFocus(); + textfield->grabKeyboardFocus(); ed->repaint(); // force update selection color } -void CodeEditorSearch::textEditorEscapeKeyPressed(TextEditor &) { hide(); } -void CodeEditorSearch::textEditorReturnKeyPressed(TextEditor &) {} +void CodeEditorSearch::textEditorEscapeKeyPressed(juce::TextEditor &) { hide(); } +void CodeEditorSearch::textEditorReturnKeyPressed(juce::TextEditor &) {} -bool CodeEditorSearch::keyPressed(const juce::KeyPress &key) +bool CodeEditorSearch::keyPressed(const juce::KeyPress &key, juce::Component *originatingComponent) { - juce::TextEditor::keyPressed(key); + originatingComponent->keyPressed(key); if (key.getKeyCode() == key.returnKey) { @@ -225,17 +221,17 @@ void CodeEditorSearch::showResult(int increment, bool moveCaret) { removeHighlightColors(); id = 0; - setColour(juce::TextEditor::focusedOutlineColourId, juce::Colour(204, 70, 70)); - setColour(juce::TextEditor::outlineColourId, - skin->getColor(Colors::FormulaEditor::Debugger::Text)); + textfield->setColour(juce::TextEditor::focusedOutlineColourId, juce::Colour(204, 70, 70)); + textfield->setColour(juce::TextEditor::outlineColourId, + skin->getColor(Colors::FormulaEditor::Debugger::Text)); } else { setHighlightColors(); - setColour(juce::TextEditor::focusedOutlineColourId, - skin->getColor(Colors::FormulaEditor::Debugger::Text)); - setColour(juce::TextEditor::outlineColourId, - skin->getColor(Colors::FormulaEditor::Debugger::Text)); + textfield->setColour(juce::TextEditor::focusedOutlineColourId, + skin->getColor(Colors::FormulaEditor::Debugger::Text)); + textfield->setColour(juce::TextEditor::outlineColourId, + skin->getColor(Colors::FormulaEditor::Debugger::Text)); } labelResult->setText(juce::String(std::to_string(id) + '/' + std::to_string(resultTotal)), @@ -250,7 +246,7 @@ void CodeEditorSearch::showResult(int increment, bool moveCaret) saveCaretStartPositionLock = true; ed->setHighlightedRegion( - juce::Range(result[resultCurrent], result[resultCurrent] + getTotalNumChars())); + juce::Range(result[resultCurrent], result[resultCurrent] + textfield->getTotalNumChars())); saveCaretStartPositionLock = false; } @@ -258,6 +254,7 @@ void CodeEditorSearch::resize() { juce::Rectangle bounds = juce::Rectangle(ed->getBounds().getWidth() - 150 - 10, 6, 150, 24); setBounds(bounds); + textfield->setBounds(0, 0, 150, 24); } void CodeEditorSearch::search() @@ -274,7 +271,7 @@ void CodeEditorSearch::search() juce::String txt = ed->getDocument().getAllContent(); int pos = 0; int count = 0; - int res = txt.indexOfIgnoreCase(pos, getText()); + int res = txt.indexOfIgnoreCase(pos, textfield->getText()); resultCurrent = 0; bool firstFound = false; while (res != -1 && count < 128) @@ -288,7 +285,7 @@ void CodeEditorSearch::search() } pos = res + 1; - res = txt.indexOfIgnoreCase(pos, getText()); + res = txt.indexOfIgnoreCase(pos, textfield->getText()); count++; } @@ -329,7 +326,12 @@ void SurgeCodeEditorComponent::handleEscapeKey() } } -void SurgeCodeEditorComponent::caretPositionMoved() { search->saveCaretStartPosition(true); } +void SurgeCodeEditorComponent::caretPositionMoved() +{ + + if (search != nullptr) + search->saveCaretStartPosition(true); +} // Handles auto indentation @@ -441,6 +443,7 @@ CodeEditorContainerWithApply::CodeEditorContainerWithApply(SurgeGUIEditor *ed, S EditorColors::setColorsFromSkin(mainEditor.get(), skin); search = std::make_unique(*mainEditor, skin); + mainEditor->setSearch(*search); if (addComponents) { diff --git a/src/surge-xt/gui/overlays/LuaEditors.h b/src/surge-xt/gui/overlays/LuaEditors.h index f1fd6629332..29dea34cb7e 100644 --- a/src/surge-xt/gui/overlays/LuaEditors.h +++ b/src/surge-xt/gui/overlays/LuaEditors.h @@ -44,8 +44,9 @@ namespace Surge namespace Overlays { -class CodeEditorSearch : public juce::TextEditor, +class CodeEditorSearch : public juce::Component, public juce::TextEditor::Listener, + public juce::KeyListener, public Surge::GUI::SkinConsumingComponent { private: @@ -59,6 +60,7 @@ class CodeEditorSearch : public juce::TextEditor, bool saveCaretStartPositionLock; Surge::GUI::Skin::ptr_t currentSkin; + std::unique_ptr textfield; std::unique_ptr labelResult; juce::CodeDocument::Position startCaretPosition; @@ -75,12 +77,13 @@ class CodeEditorSearch : public juce::TextEditor, virtual void focusLost(FocusChangeType) override; CodeEditorSearch(juce::CodeEditorComponent &editor, Surge::GUI::Skin::ptr_t); - virtual void textEditorEscapeKeyPressed(TextEditor &) override; - virtual void textEditorReturnKeyPressed(TextEditor &) override; - virtual bool keyPressed(const juce::KeyPress &key) override; + virtual void textEditorEscapeKeyPressed(juce::TextEditor &); + virtual void textEditorReturnKeyPressed(juce::TextEditor &); + virtual bool keyPressed(const juce::KeyPress &key, + juce::Component *originatingComponent) override; virtual void saveCaretStartPosition(bool onlyReadCaretPosition); virtual void showResult(int increase, bool moveCaret); - virtual void paint(juce::Graphics &g) override; + virtual void paint(juce::Graphics &g); }; class SurgeCodeEditorComponent : public juce::CodeEditorComponent @@ -94,7 +97,7 @@ class SurgeCodeEditorComponent : public juce::CodeEditorComponent SurgeCodeEditorComponent(juce::CodeDocument &d, juce::CodeTokeniser *t); private: - CodeEditorSearch *search; + CodeEditorSearch *search = nullptr; }; /* From bc3ae5c23b05962fac1efa5eebe9980be12af2c2 Mon Sep 17 00:00:00 2001 From: blancoberg Date: Mon, 9 Dec 2024 22:31:10 +0100 Subject: [PATCH 5/5] override missed a couple of overrides. again --- src/surge-xt/gui/overlays/LuaEditors.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/surge-xt/gui/overlays/LuaEditors.h b/src/surge-xt/gui/overlays/LuaEditors.h index 29dea34cb7e..bf25dff33fb 100644 --- a/src/surge-xt/gui/overlays/LuaEditors.h +++ b/src/surge-xt/gui/overlays/LuaEditors.h @@ -77,13 +77,13 @@ class CodeEditorSearch : public juce::Component, virtual void focusLost(FocusChangeType) override; CodeEditorSearch(juce::CodeEditorComponent &editor, Surge::GUI::Skin::ptr_t); - virtual void textEditorEscapeKeyPressed(juce::TextEditor &); - virtual void textEditorReturnKeyPressed(juce::TextEditor &); + virtual void textEditorEscapeKeyPressed(juce::TextEditor &) override; + virtual void textEditorReturnKeyPressed(juce::TextEditor &) override; virtual bool keyPressed(const juce::KeyPress &key, juce::Component *originatingComponent) override; virtual void saveCaretStartPosition(bool onlyReadCaretPosition); virtual void showResult(int increase, bool moveCaret); - virtual void paint(juce::Graphics &g); + virtual void paint(juce::Graphics &g) override; }; class SurgeCodeEditorComponent : public juce::CodeEditorComponent