diff --git a/plugin/components/ide_view.cpp b/plugin/components/ide_view.cpp index 5b0e8a5..b3777a9 100644 --- a/plugin/components/ide_view.cpp +++ b/plugin/components/ide_view.cpp @@ -147,6 +147,12 @@ void YsfxIDEView::focusOfChildComponentChanged(FocusChangeType cause) if (m_impl->getCurrentEditor()->hasFocus()) { juce::Timer *timer = FunctionalTimer::create([this]() { m_impl->getCurrentEditor()->checkFileForModifications(); + + int idx = 0; + for (auto& m : m_impl->m_editors) { + m_impl->m_tabs->setTabName(idx, m->getDisplayName()); + ++idx; + } }); m_impl->m_fileCheckTimer.reset(timer); timer->startTimer(100); @@ -170,7 +176,9 @@ void YsfxIDEView::Impl::setupNewFx() } else { juce::File file{juce::CharPointer_UTF8{ysfx_get_file_path(fx)}}; - m_editors[0]->loadFile(file); + if ((m_editors[0]->getPath() != file) || (!m_editors[0]->wasModified())) { + m_editors[0]->loadFile(file); + }; m_vars.ensureStorageAllocated(64); @@ -287,6 +295,7 @@ void YsfxIDEView::Impl::openDocument(juce::File file) auto editor = addEditor(); editor->loadFile(file); + setCurrentEditor(m_editors.size() - 1); } @@ -458,7 +467,7 @@ void YsfxIDEView::Impl::relayoutUI() m_tabs->clearTabs(); int idx = 0; for (const auto m : m_editors) { - m_tabs->addTab(m->getName(), m_self->getLookAndFeel().findColour(m_btnSave->buttonColourId), idx); + m_tabs->addTab(m->getDisplayName(), m_self->getLookAndFeel().findColour(m_btnSave->buttonColourId), idx); ++idx; } m_tabs->setCurrentTabIndex(m_currentEditorIndex, false); diff --git a/plugin/components/ysfx_document.h b/plugin/components/ysfx_document.h index bb80876..589ccf2 100644 --- a/plugin/components/ysfx_document.h +++ b/plugin/components/ysfx_document.h @@ -124,46 +124,70 @@ class CodeEditor : public juce::CodeEditorComponent }; -class YSFXCodeEditor +class YSFXCodeEditor : public juce::CodeDocument::Listener { public: YSFXCodeEditor(juce::CodeTokeniser* tokenizer, std::function keyPressCallback, std::function dblClickCallback) { m_document = std::make_unique(); + m_document->addListener(this); m_editor = std::make_unique(*m_document, tokenizer, keyPressCallback, dblClickCallback); m_editor->setVisible(false); }; ~YSFXCodeEditor() { // Make sure we kill the editor first since it may be referencing the document! + m_document->removeListener(this); m_editor.reset(); m_document.reset(); } - void setColourScheme(juce::CodeEditorComponent::ColourScheme colourScheme) { m_editor->setColourScheme(colourScheme); }; - void checkFileForModifications() { m_document->checkFileForModifications(); }; - void reset() { m_document->reset(); }; - void setReadOnly(bool readOnly) { m_editor->setReadOnly(readOnly); }; + void codeDocumentTextDeleted(int startIndex, int endIndex) override { + (void) startIndex; + (void) endIndex; + m_modified = true; + } + void codeDocumentTextInserted(const juce::String& newText, int insertIndex) override { + (void) newText; + (void) insertIndex; + m_modified = true; + } - juce::File getPath() { return m_document->getPath(); }; - juce::String getName() { return m_document->getName(); }; - void loadFile(juce::File file) { m_document->loadFile(file); }; - bool saveFile(juce::File file = juce::File{}) { return m_document->saveFile(file); }; - int search(juce::String text, bool reverse = false) { return m_editor->search(text, reverse); }; + void setColourScheme(juce::CodeEditorComponent::ColourScheme colourScheme) { m_editor->setColourScheme(colourScheme); } + void checkFileForModifications() { m_document->checkFileForModifications(); } + void reset() { m_document->reset(); } + void setReadOnly(bool readOnly) { m_editor->setReadOnly(readOnly); } + bool wasModified() { return m_modified; }; + + juce::File getPath() { return m_document->getPath(); } + juce::String getName() { return m_document->getName(); } + juce::String getDisplayName() { return m_document->getName() + (m_modified ? "*" : ""); } + void loadFile(juce::File file) { + m_document->loadFile(file); + m_modified = false; + } + bool saveFile(juce::File file = juce::File{}) { + if (m_document->saveFile(file)) { + m_modified = false; + return true; + } else return false; + } + int search(juce::String text, bool reverse = false) { return m_editor->search(text, reverse); } bool hasFocus() { juce::Component *focus = m_editor->getCurrentlyFocusedComponent(); return focus == m_editor.get(); }; - juce::String getLineAt(int x, int y) const { return m_editor->getLineAt(x, y); }; - CodeEditor* getVisibleComponent() { return m_editor.get(); }; + juce::String getLineAt(int x, int y) const { return m_editor->getLineAt(x, y); } + CodeEditor* getVisibleComponent() { return m_editor.get(); } - void setVisible(bool visible) { m_editor->setVisible(visible); }; + void setVisible(bool visible) { m_editor->setVisible(visible); } template - void setBounds(T&& arg) { m_editor->setBounds(std::forward(arg)); }; + void setBounds(T&& arg) { m_editor->setBounds(std::forward(arg)); } private: std::unique_ptr m_editor; std::unique_ptr m_document; + bool m_modified{false}; };