| @@ -304,15 +304,79 @@ void CodeGenerator::applyToCode (String& code, const File& targetFile, | |||||
| //============================================================================== | //============================================================================== | ||||
| CodeGenerator::CustomisedCodeSnippets::CustomisedCodeSnippets() | |||||
| CodeGenerator::CustomCodeList::Iterator::Iterator (const String& documentText, CustomCodeList& customCode_) | |||||
| : customCode (customCode_), i (0), codeDocument (0) | |||||
| { | { | ||||
| lines.addLines (documentText); | |||||
| } | } | ||||
| CodeGenerator::CustomisedCodeSnippets::~CustomisedCodeSnippets() | |||||
| CodeGenerator::CustomCodeList::Iterator::~Iterator() | |||||
| { | { | ||||
| } | } | ||||
| void CodeGenerator::CustomisedCodeSnippets::reloadFrom (const String& fileContent) | |||||
| bool CodeGenerator::CustomCodeList::Iterator::next() | |||||
| { | |||||
| textBefore = String::empty; | |||||
| textAfter = String::empty; | |||||
| while (i < lines.size()) | |||||
| { | |||||
| textBefore += lines[i] + "\n"; | |||||
| if (lines[i].trimStart().startsWith ("//[")) | |||||
| { | |||||
| String tag (lines[i].trimStart().substring (3)); | |||||
| tag = tag.upToFirstOccurrenceOf ("]", false, false).trim(); | |||||
| if (! (tag.isEmpty() || tag.startsWithChar ('/'))) | |||||
| { | |||||
| const int endLine = indexOfLineStartingWith (lines, "//[/" + tag + "]", i + 1); | |||||
| if (endLine > i) | |||||
| { | |||||
| sectionName = tag; | |||||
| codeDocument = customCode.getDocumentFor (tag, true); | |||||
| i = endLine; | |||||
| bool isLastTag = true; | |||||
| for (int j = i + 1; j < lines.size(); ++j) | |||||
| { | |||||
| if (lines[j].trimStart().startsWith ("//[")) | |||||
| { | |||||
| isLastTag = false; | |||||
| break; | |||||
| } | |||||
| } | |||||
| if (isLastTag) | |||||
| { | |||||
| textAfter = lines.joinIntoString (newLine, i, lines.size() - i); | |||||
| i = lines.size(); | |||||
| } | |||||
| return true; | |||||
| } | |||||
| } | |||||
| } | |||||
| ++i; | |||||
| } | |||||
| return false; | |||||
| } | |||||
| //============================================================================== | |||||
| CodeGenerator::CustomCodeList::CustomCodeList() | |||||
| { | |||||
| } | |||||
| CodeGenerator::CustomCodeList::~CustomCodeList() | |||||
| { | |||||
| } | |||||
| void CodeGenerator::CustomCodeList::reloadFrom (const String& fileContent) | |||||
| { | { | ||||
| sectionNames.clear(); | sectionNames.clear(); | ||||
| sectionContent.clear(); | sectionContent.clear(); | ||||
| @@ -339,19 +403,23 @@ void CodeGenerator::CustomisedCodeSnippets::reloadFrom (const String& fileConten | |||||
| sectionNames.add (tag); | sectionNames.add (tag); | ||||
| CodeDocument* doc = new CodeDocument(); | |||||
| CodeDocumentRef::Ptr doc (new CodeDocumentRef (new CodeDocument())); | |||||
| sectionContent.add (doc); | sectionContent.add (doc); | ||||
| doc->replaceAllContent (content); | |||||
| doc->getDocument().replaceAllContent (content); | |||||
| doc->getDocument().clearUndoHistory(); | |||||
| doc->getDocument().setSavePoint(); | |||||
| i = endLine; | i = endLine; | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| sendSynchronousChangeMessage (this); | |||||
| } | } | ||||
| void CodeGenerator::CustomisedCodeSnippets::applyTo (String& fileContent) const | |||||
| void CodeGenerator::CustomCodeList::applyTo (String& fileContent) const | |||||
| { | { | ||||
| StringArray lines; | StringArray lines; | ||||
| lines.addLines (fileContent); | lines.addLines (fileContent); | ||||
| @@ -400,12 +468,31 @@ void CodeGenerator::CustomisedCodeSnippets::applyTo (String& fileContent) const | |||||
| fileContent = lines.joinIntoString (newLine); | fileContent = lines.joinIntoString (newLine); | ||||
| } | } | ||||
| bool CodeGenerator::CustomisedCodeSnippets::areAnySnippetsUnsaved() const | |||||
| bool CodeGenerator::CustomCodeList::needsSaving() const | |||||
| { | |||||
| for (int i = sectionContent.size(); --i >= 0;) | |||||
| if (sectionContent.getUnchecked(i)->getDocument().hasChangedSinceSavePoint()) | |||||
| return true; | |||||
| return false; | |||||
| } | |||||
| int CodeGenerator::CustomCodeList::getNumSections() const | |||||
| { | |||||
| return sectionNames.size(); | |||||
| } | |||||
| const String CodeGenerator::CustomCodeList::getSectionName (int index) const | |||||
| { | |||||
| return sectionNames [index]; | |||||
| } | |||||
| const CodeGenerator::CustomCodeList::CodeDocumentRef::Ptr CodeGenerator::CustomCodeList::getDocument (int index) const | |||||
| { | { | ||||
| return true; //xxx | |||||
| return sectionContent [index]; | |||||
| } | } | ||||
| CodeDocument* CodeGenerator::CustomisedCodeSnippets::getDocumentFor (const String& sectionName, bool createIfNotFound) | |||||
| const CodeGenerator::CustomCodeList::CodeDocumentRef::Ptr CodeGenerator::CustomCodeList::getDocumentFor (const String& sectionName, bool createIfNotFound) | |||||
| { | { | ||||
| const int index = sectionNames.indexOf (sectionName); | const int index = sectionNames.indexOf (sectionName); | ||||
| @@ -415,24 +502,26 @@ CodeDocument* CodeGenerator::CustomisedCodeSnippets::getDocumentFor (const Strin | |||||
| if (createIfNotFound) | if (createIfNotFound) | ||||
| { | { | ||||
| sectionNames.add (sectionName); | sectionNames.add (sectionName); | ||||
| sectionContent.add (new CodeDocument()); | |||||
| return sectionContent.getLast(); | |||||
| const CodeDocumentRef::Ptr doc (new CodeDocumentRef (new CodeDocument())); | |||||
| sectionContent.add (doc); | |||||
| return doc; | |||||
| } | } | ||||
| return 0; | return 0; | ||||
| } | } | ||||
| const String CodeGenerator::CustomisedCodeSnippets::getSectionContent (const String& sectionName) const | |||||
| const String CodeGenerator::CustomCodeList::getSectionContent (const String& sectionName) const | |||||
| { | { | ||||
| const int index = sectionNames.indexOf (sectionName); | const int index = sectionNames.indexOf (sectionName); | ||||
| if (index >= 0) | if (index >= 0) | ||||
| return sectionContent[index]->getAllContent(); | |||||
| return sectionContent[index]->getDocument().getAllContent(); | |||||
| return String::empty; | return String::empty; | ||||
| } | } | ||||
| void CodeGenerator::CustomisedCodeSnippets::removeSection (const String& sectionName) | |||||
| void CodeGenerator::CustomCodeList::removeSection (const String& sectionName) | |||||
| { | { | ||||
| const int index = sectionNames.indexOf (sectionName); | const int index = sectionNames.indexOf (sectionName); | ||||
| @@ -75,23 +75,61 @@ public: | |||||
| //============================================================================== | //============================================================================== | ||||
| // An object to load and store all the user-defined bits of code as documents. | // An object to load and store all the user-defined bits of code as documents. | ||||
| class CustomisedCodeSnippets | |||||
| class CustomCodeList : public ChangeBroadcaster | |||||
| { | { | ||||
| public: | public: | ||||
| CustomisedCodeSnippets(); | |||||
| ~CustomisedCodeSnippets(); | |||||
| CustomCodeList(); | |||||
| ~CustomCodeList(); | |||||
| void reloadFrom (const String& fileContent); | void reloadFrom (const String& fileContent); | ||||
| void applyTo (String& fileContent) const; | void applyTo (String& fileContent) const; | ||||
| bool areAnySnippetsUnsaved() const; | |||||
| bool needsSaving() const; | |||||
| CodeDocument* getDocumentFor (const String& sectionName, bool createIfNotFound); | |||||
| //============================================================================== | |||||
| // Ref-counted wrapper for a code document.. | |||||
| class CodeDocumentRef : public ReferenceCountedObject | |||||
| { | |||||
| public: | |||||
| CodeDocumentRef (CodeDocument* doc_) : doc (doc_) {} | |||||
| CodeDocument& getDocument() const throw() { return *doc; } | |||||
| typedef ReferenceCountedObjectPtr<CodeDocumentRef> Ptr; | |||||
| private: | |||||
| CodeDocument* doc; | |||||
| }; | |||||
| //============================================================================== | |||||
| int getNumSections() const; | |||||
| const String getSectionName (int index) const; | |||||
| const CodeDocumentRef::Ptr getDocument (int index) const; | |||||
| const CodeDocumentRef::Ptr getDocumentFor (const String& sectionName, bool createIfNotFound); | |||||
| const String getSectionContent (const String& sectionName) const; | const String getSectionContent (const String& sectionName) const; | ||||
| void removeSection (const String& sectionName); | void removeSection (const String& sectionName); | ||||
| class Iterator | |||||
| { | |||||
| public: | |||||
| Iterator (const String& documentText, CustomCodeList& customCode); | |||||
| ~Iterator(); | |||||
| bool next(); | |||||
| String textBefore, textAfter, sectionName; | |||||
| CodeDocumentRef::Ptr codeDocument; | |||||
| private: | |||||
| CustomCodeList& customCode; | |||||
| StringArray lines; | |||||
| int i; | |||||
| }; | |||||
| private: | private: | ||||
| StringArray sectionNames; | StringArray sectionNames; | ||||
| OwnedArray <CodeDocument> sectionContent; | |||||
| ReferenceCountedArray <CodeDocumentRef> sectionContent; | |||||
| }; | }; | ||||
| //============================================================================== | //============================================================================== | ||||
| @@ -80,19 +80,24 @@ void ComponentDocument::beginNewTransaction() | |||||
| undoManager.beginNewTransaction(); | undoManager.beginNewTransaction(); | ||||
| } | } | ||||
| void ComponentDocument::valueTreePropertyChanged (ValueTree& treeWhosePropertyHasChanged, const var::identifier& property) | |||||
| void ComponentDocument::changed() | |||||
| { | { | ||||
| changedSinceSaved = true; | changedSinceSaved = true; | ||||
| } | } | ||||
| void ComponentDocument::valueTreePropertyChanged (ValueTree& treeWhosePropertyHasChanged, const var::identifier& property) | |||||
| { | |||||
| changed(); | |||||
| } | |||||
| void ComponentDocument::valueTreeChildrenChanged (ValueTree& treeWhoseChildHasChanged) | void ComponentDocument::valueTreeChildrenChanged (ValueTree& treeWhoseChildHasChanged) | ||||
| { | { | ||||
| changedSinceSaved = true; | |||||
| changed(); | |||||
| } | } | ||||
| void ComponentDocument::valueTreeParentChanged (ValueTree& treeWhoseParentHasChanged) | void ComponentDocument::valueTreeParentChanged (ValueTree& treeWhoseParentHasChanged) | ||||
| { | { | ||||
| changedSinceSaved = true; | |||||
| changed(); | |||||
| } | } | ||||
| bool ComponentDocument::isComponentFile (const File& file) | bool ComponentDocument::isComponentFile (const File& file) | ||||
| @@ -114,6 +119,9 @@ bool ComponentDocument::isComponentFile (const File& file) | |||||
| return false; | return false; | ||||
| } | } | ||||
| const String ComponentDocument::getCppTemplate() const { return String (BinaryData::jucer_ComponentTemplate_cpp); } | |||||
| const String ComponentDocument::getHeaderTemplate() const { return String (BinaryData::jucer_ComponentTemplate_h); } | |||||
| void ComponentDocument::writeCode (OutputStream& cpp, OutputStream& header) | void ComponentDocument::writeCode (OutputStream& cpp, OutputStream& header) | ||||
| { | { | ||||
| CodeGenerator codeGen; | CodeGenerator codeGen; | ||||
| @@ -128,20 +136,20 @@ void ComponentDocument::writeCode (OutputStream& cpp, OutputStream& header) | |||||
| } | } | ||||
| { | { | ||||
| String code (BinaryData::jucer_ComponentTemplate_cpp); | |||||
| String code (getCppTemplate()); | |||||
| String oldContent; | String oldContent; | ||||
| codeGen.applyToCode (code, cppFile, false, project); | codeGen.applyToCode (code, cppFile, false, project); | ||||
| customisedCodeSnippets.applyTo (code); | |||||
| customCode.applyTo (code); | |||||
| cpp << code; | cpp << code; | ||||
| } | } | ||||
| { | { | ||||
| String code (BinaryData::jucer_ComponentTemplate_h); | |||||
| String code (getHeaderTemplate()); | |||||
| String oldContent; | String oldContent; | ||||
| codeGen.applyToCode (code, cppFile.withFileExtension (".h"), false, project); | codeGen.applyToCode (code, cppFile.withFileExtension (".h"), false, project); | ||||
| customisedCodeSnippets.applyTo (code); | |||||
| customCode.applyTo (code); | |||||
| header << code; | header << code; | ||||
| } | } | ||||
| } | } | ||||
| @@ -224,7 +232,7 @@ bool ComponentDocument::reload() | |||||
| undoManager.clearUndoHistory(); | undoManager.clearUndoHistory(); | ||||
| changedSinceSaved = false; | changedSinceSaved = false; | ||||
| customisedCodeSnippets.reloadFrom (cppFile.loadFileAsString()); | |||||
| customCode.reloadFrom (cppFile.loadFileAsString()); | |||||
| return true; | return true; | ||||
| } | } | ||||
| } | } | ||||
| @@ -234,7 +242,7 @@ bool ComponentDocument::reload() | |||||
| bool ComponentDocument::hasChangedSinceLastSave() | bool ComponentDocument::hasChangedSinceLastSave() | ||||
| { | { | ||||
| return changedSinceSaved; | |||||
| return changedSinceSaved || customCode.needsSaving(); | |||||
| } | } | ||||
| void ComponentDocument::createSubTreeIfNotThere (const String& name) | void ComponentDocument::createSubTreeIfNotThere (const String& name) | ||||
| @@ -47,6 +47,7 @@ public: | |||||
| bool save(); | bool save(); | ||||
| bool reload(); | bool reload(); | ||||
| bool hasChangedSinceLastSave(); | bool hasChangedSinceLastSave(); | ||||
| void changed(); | |||||
| const File getCppFile() const { return cppFile; } | const File getCppFile() const { return cppFile; } | ||||
| //============================================================================== | //============================================================================== | ||||
| @@ -136,7 +137,10 @@ public: | |||||
| void endDrag (const MouseEvent& e); | void endDrag (const MouseEvent& e); | ||||
| //============================================================================== | //============================================================================== | ||||
| CodeGenerator::CustomisedCodeSnippets& getCustomisedCodeSnippets() throw() { return customisedCodeSnippets; } | |||||
| CodeGenerator::CustomCodeList& getCustomCodeList() throw() { return customCode; } | |||||
| const String getCppTemplate() const; | |||||
| const String getHeaderTemplate() const; | |||||
| //============================================================================== | //============================================================================== | ||||
| ValueTree& getRoot() { return root; } | ValueTree& getRoot() { return root; } | ||||
| @@ -164,7 +168,7 @@ private: | |||||
| File cppFile; | File cppFile; | ||||
| ValueTree root; | ValueTree root; | ||||
| ScopedPointer<MarkerList> markersX, markersY; | ScopedPointer<MarkerList> markersX, markersY; | ||||
| CodeGenerator::CustomisedCodeSnippets customisedCodeSnippets; | |||||
| CodeGenerator::CustomCodeList customCode; | |||||
| mutable UndoManager undoManager; | mutable UndoManager undoManager; | ||||
| bool changedSinceSaved; | bool changedSinceSaved; | ||||
| @@ -536,14 +536,158 @@ public: | |||||
| CodeEditorHolder (ComponentEditor& editor_) | CodeEditorHolder (ComponentEditor& editor_) | ||||
| : editor (editor_) | : editor (editor_) | ||||
| { | { | ||||
| addAndMakeVisible (viewport = new Viewport()); | |||||
| viewport->setScrollBarsShown (true, false); | |||||
| viewport->setViewedComponent (new ContentHolder (editor)); | |||||
| } | } | ||||
| ~CodeEditorHolder() | ~CodeEditorHolder() | ||||
| { | { | ||||
| } | } | ||||
| void resized() | |||||
| { | |||||
| viewport->setBounds (getLocalBounds()); | |||||
| int visWidth = viewport->getMaximumVisibleWidth(); | |||||
| dynamic_cast <ContentHolder*> (viewport->getViewedComponent())->updateSize (visWidth); | |||||
| if (viewport->getMaximumVisibleWidth() != visWidth) | |||||
| dynamic_cast <ContentHolder*> (viewport->getViewedComponent())->updateSize (viewport->getMaximumVisibleWidth()); | |||||
| } | |||||
| private: | private: | ||||
| ComponentEditor& editor; | ComponentEditor& editor; | ||||
| enum { updateCommandId = 0x23427fa1 }; | |||||
| class EditorHolder : public Component, | |||||
| public CodeDocument::Listener | |||||
| { | |||||
| public: | |||||
| EditorHolder (const CodeGenerator::CustomCodeList::CodeDocumentRef::Ptr doc, | |||||
| const String& name, const String& textBefore, const String& textAfter) | |||||
| : Component (name), document (doc), cppTokeniser(), codeEditor (doc->getDocument(), &cppTokeniser) | |||||
| { | |||||
| linesBefore.addLines (textBefore); | |||||
| linesAfter.addLines (textAfter); | |||||
| addAndMakeVisible (&codeEditor); | |||||
| doc->getDocument().addListener (this); | |||||
| } | |||||
| ~EditorHolder() | |||||
| { | |||||
| document->getDocument().removeListener (this); | |||||
| } | |||||
| void paint (Graphics& g) | |||||
| { | |||||
| g.setFont (codeEditor.getFont()); | |||||
| g.setColour (Colours::darkgrey); | |||||
| const int fontHeight = codeEditor.getLineHeight(); | |||||
| const int fontAscent = (int) codeEditor.getFont().getAscent(); | |||||
| const int textX = 5; | |||||
| int i; | |||||
| for (i = 0; i < linesBefore.size(); ++i) | |||||
| g.drawSingleLineText (linesBefore[i], textX, i * fontHeight + fontAscent); | |||||
| for (i = 0; i < linesAfter.size(); ++i) | |||||
| g.drawSingleLineText (linesAfter[i], textX, codeEditor.getBottom() + i * fontHeight + fontAscent); | |||||
| } | |||||
| void updateSize (int width) | |||||
| { | |||||
| const int fontHeight = codeEditor.getLineHeight(); | |||||
| codeEditor.setBounds (0, fontHeight * linesBefore.size() + 1, | |||||
| width, 2 + codeEditor.getScrollbarThickness() | |||||
| + fontHeight * jmax (1, document->getDocument().getNumLines())); | |||||
| setSize (width, (linesBefore.size() + linesAfter.size()) * fontHeight + codeEditor.getHeight()); | |||||
| } | |||||
| void codeDocumentChanged (const CodeDocument::Position&, const CodeDocument::Position&) | |||||
| { | |||||
| int oldHeight = getHeight(); | |||||
| updateSize (getWidth()); | |||||
| if (getHeight() != oldHeight) | |||||
| getParentComponent()->handleCommandMessage (updateCommandId); | |||||
| } | |||||
| const CodeGenerator::CustomCodeList::CodeDocumentRef::Ptr document; | |||||
| CPlusPlusCodeTokeniser cppTokeniser; | |||||
| CodeEditorComponent codeEditor; | |||||
| StringArray linesBefore, linesAfter; | |||||
| }; | |||||
| class ContentHolder : public Component, | |||||
| public ChangeListener | |||||
| { | |||||
| public: | |||||
| ContentHolder (ComponentEditor& editor_) | |||||
| : editor (editor_) | |||||
| { | |||||
| setOpaque (true); | |||||
| editor.getDocument().getCustomCodeList().addChangeListener (this); | |||||
| changeListenerCallback (0); | |||||
| } | |||||
| ~ContentHolder() | |||||
| { | |||||
| editor.getDocument().getCustomCodeList().removeChangeListener (this); | |||||
| } | |||||
| void paint (Graphics& g) | |||||
| { | |||||
| g.fillAll (Colours::lightgrey); | |||||
| } | |||||
| void updateSize (int width) | |||||
| { | |||||
| int y = 2; | |||||
| for (int i = 0; i < editors.size(); ++i) | |||||
| { | |||||
| editors.getUnchecked(i)->updateSize (width - 8); | |||||
| editors.getUnchecked(i)->setTopLeftPosition (4, y + 1); | |||||
| y = editors.getUnchecked(i)->getBottom() + 1; | |||||
| } | |||||
| setSize (width, y + 2); | |||||
| } | |||||
| void changeListenerCallback (void*) | |||||
| { | |||||
| editors.clear(); | |||||
| CodeGenerator::CustomCodeList::Iterator iter (editor.getDocument().getCppTemplate(), | |||||
| editor.getDocument().getCustomCodeList()); | |||||
| while (iter.next()) | |||||
| { | |||||
| EditorHolder* ed = new EditorHolder (iter.codeDocument, iter.sectionName, iter.textBefore, iter.textAfter); | |||||
| editors.add (ed); | |||||
| addAndMakeVisible (ed); | |||||
| } | |||||
| updateSize (getWidth()); | |||||
| } | |||||
| void handleCommandMessage (int commandId) | |||||
| { | |||||
| if (commandId == updateCommandId) | |||||
| updateSize (getWidth()); | |||||
| else | |||||
| Component::handleCommandMessage (commandId); | |||||
| } | |||||
| OwnedArray <EditorHolder> editors; | |||||
| ComponentEditor& editor; | |||||
| }; | |||||
| Viewport* viewport; | |||||
| }; | }; | ||||
| //============================================================================== | //============================================================================== | ||||
| @@ -43436,6 +43436,7 @@ void CodeDocument::Position::setPositionMaintained (const bool isMaintained) thr | |||||
| } | } | ||||
| else | else | ||||
| { | { | ||||
| // If this happens, you may have deleted the document while there are Position objects that are still using it... | |||||
| jassert (owner->positionsToMaintain.contains (this)); | jassert (owner->positionsToMaintain.contains (this)); | ||||
| owner->positionsToMaintain.removeValue (this); | owner->positionsToMaintain.removeValue (this); | ||||
| } | } | ||||
| @@ -43949,7 +43950,8 @@ class CodeEditorComponent::CaretComponent : public Component, | |||||
| public Timer | public Timer | ||||
| { | { | ||||
| public: | public: | ||||
| CaretComponent() | |||||
| CaretComponent (CodeEditorComponent& owner_) | |||||
| : owner (owner_) | |||||
| { | { | ||||
| setAlwaysOnTop (true); | setAlwaysOnTop (true); | ||||
| setInterceptsMouseClicks (false, false); | setInterceptsMouseClicks (false, false); | ||||
| @@ -43961,27 +43963,29 @@ public: | |||||
| void paint (Graphics& g) | void paint (Graphics& g) | ||||
| { | { | ||||
| if (getParentComponent()->hasKeyboardFocus (true)) | |||||
| g.fillAll (findColour (CodeEditorComponent::caretColourId)); | |||||
| g.fillAll (findColour (CodeEditorComponent::caretColourId)); | |||||
| } | } | ||||
| void timerCallback() | void timerCallback() | ||||
| { | { | ||||
| setVisible (! isVisible()); | |||||
| setVisible (shouldBeShown() && ! isVisible()); | |||||
| } | } | ||||
| void updatePosition (CodeEditorComponent& owner) | |||||
| void updatePosition() | |||||
| { | { | ||||
| startTimer (400); | startTimer (400); | ||||
| setVisible (true); | |||||
| setVisible (shouldBeShown()); | |||||
| const Rectangle<int> pos (owner.getCharacterBounds (owner.getCaretPos())); | |||||
| setBounds (pos.getX(), pos.getY(), 2, pos.getHeight()); | |||||
| setBounds (owner.getCharacterBounds (owner.getCaretPos()).withWidth (2)); | |||||
| } | } | ||||
| private: | private: | ||||
| CodeEditorComponent& owner; | |||||
| CaretComponent (const CaretComponent&); | CaretComponent (const CaretComponent&); | ||||
| CaretComponent& operator= (const CaretComponent&); | CaretComponent& operator= (const CaretComponent&); | ||||
| bool shouldBeShown() const { return owner.hasKeyboardFocus (true); } | |||||
| }; | }; | ||||
| class CodeEditorComponent::CodeEditorLine | class CodeEditorComponent::CodeEditorLine | ||||
| @@ -44224,7 +44228,7 @@ CodeEditorComponent::CodeEditorComponent (CodeDocument& document_, | |||||
| addAndMakeVisible (horizontalScrollBar = new ScrollBar (false)); | addAndMakeVisible (horizontalScrollBar = new ScrollBar (false)); | ||||
| horizontalScrollBar->setSingleStepSize (1.0); | horizontalScrollBar->setSingleStepSize (1.0); | ||||
| addAndMakeVisible (caret = new CaretComponent()); | |||||
| addAndMakeVisible (caret = new CaretComponent (*this)); | |||||
| Font f (12.0f); | Font f (12.0f); | ||||
| f.setTypefaceName (Font::getDefaultMonospacedFontName()); | f.setTypefaceName (Font::getDefaultMonospacedFontName()); | ||||
| @@ -44262,7 +44266,7 @@ void CodeEditorComponent::codeDocumentChanged (const CodeDocument::Position& aff | |||||
| triggerAsyncUpdate(); | triggerAsyncUpdate(); | ||||
| caret->updatePosition (*this); | |||||
| caret->updatePosition(); | |||||
| columnToTryToMaintain = -1; | columnToTryToMaintain = -1; | ||||
| if (affectedTextEnd.getPosition() >= selectionStart.getPosition() | if (affectedTextEnd.getPosition() >= selectionStart.getPosition() | ||||
| @@ -44282,7 +44286,7 @@ void CodeEditorComponent::resized() | |||||
| columnsOnScreen = (int) ((getWidth() - scrollbarThickness) / charWidth); | columnsOnScreen = (int) ((getWidth() - scrollbarThickness) / charWidth); | ||||
| lines.clear(); | lines.clear(); | ||||
| rebuildLineTokens(); | rebuildLineTokens(); | ||||
| caret->updatePosition (*this); | |||||
| caret->updatePosition(); | |||||
| verticalScrollBar->setBounds (getWidth() - scrollbarThickness, 0, scrollbarThickness, getHeight() - scrollbarThickness); | verticalScrollBar->setBounds (getWidth() - scrollbarThickness, 0, scrollbarThickness, getHeight() - scrollbarThickness); | ||||
| horizontalScrollBar->setBounds (gutter, getHeight() - scrollbarThickness, getWidth() - scrollbarThickness - gutter, scrollbarThickness); | horizontalScrollBar->setBounds (gutter, getHeight() - scrollbarThickness, getWidth() - scrollbarThickness - gutter, scrollbarThickness); | ||||
| @@ -44424,7 +44428,7 @@ void CodeEditorComponent::moveCaretTo (const CodeDocument::Position& newPos, con | |||||
| deselectAll(); | deselectAll(); | ||||
| } | } | ||||
| caret->updatePosition (*this); | |||||
| caret->updatePosition(); | |||||
| scrollToKeepCaretOnScreen(); | scrollToKeepCaretOnScreen(); | ||||
| updateScrollBars(); | updateScrollBars(); | ||||
| } | } | ||||
| @@ -44455,7 +44459,7 @@ void CodeEditorComponent::scrollToLineInternal (int newFirstLineOnScreen) | |||||
| if (newFirstLineOnScreen != firstLineOnScreen) | if (newFirstLineOnScreen != firstLineOnScreen) | ||||
| { | { | ||||
| firstLineOnScreen = newFirstLineOnScreen; | firstLineOnScreen = newFirstLineOnScreen; | ||||
| caret->updatePosition (*this); | |||||
| caret->updatePosition(); | |||||
| updateCachedIterators (firstLineOnScreen); | updateCachedIterators (firstLineOnScreen); | ||||
| triggerAsyncUpdate(); | triggerAsyncUpdate(); | ||||
| @@ -44469,7 +44473,7 @@ void CodeEditorComponent::scrollToColumnInternal (double column) | |||||
| if (xOffset != newOffset) | if (xOffset != newOffset) | ||||
| { | { | ||||
| xOffset = newOffset; | xOffset = newOffset; | ||||
| caret->updatePosition (*this); | |||||
| caret->updatePosition(); | |||||
| repaint(); | repaint(); | ||||
| } | } | ||||
| } | } | ||||
| @@ -44967,8 +44971,16 @@ void CodeEditorComponent::mouseDoubleClick (const MouseEvent& e) | |||||
| void CodeEditorComponent::mouseWheelMove (const MouseEvent& e, float wheelIncrementX, float wheelIncrementY) | void CodeEditorComponent::mouseWheelMove (const MouseEvent& e, float wheelIncrementX, float wheelIncrementY) | ||||
| { | { | ||||
| verticalScrollBar->mouseWheelMove (e, 0, wheelIncrementY); | |||||
| horizontalScrollBar->mouseWheelMove (e, wheelIncrementX, 0); | |||||
| if ((verticalScrollBar->isVisible() && wheelIncrementY != 0) | |||||
| || (horizontalScrollBar->isVisible() && wheelIncrementX != 0)) | |||||
| { | |||||
| verticalScrollBar->mouseWheelMove (e, 0, wheelIncrementY); | |||||
| horizontalScrollBar->mouseWheelMove (e, wheelIncrementX, 0); | |||||
| } | |||||
| else | |||||
| { | |||||
| Component::mouseWheelMove (e, wheelIncrementX, wheelIncrementY); | |||||
| } | |||||
| } | } | ||||
| void CodeEditorComponent::scrollBarMoved (ScrollBar* scrollBarThatHasMoved, double newRangeStart) | void CodeEditorComponent::scrollBarMoved (ScrollBar* scrollBarThatHasMoved, double newRangeStart) | ||||
| @@ -44979,6 +44991,16 @@ void CodeEditorComponent::scrollBarMoved (ScrollBar* scrollBarThatHasMoved, doub | |||||
| scrollToColumnInternal (newRangeStart); | scrollToColumnInternal (newRangeStart); | ||||
| } | } | ||||
| void CodeEditorComponent::focusGained (FocusChangeType cause) | |||||
| { | |||||
| caret->updatePosition(); | |||||
| } | |||||
| void CodeEditorComponent::focusLost (FocusChangeType cause) | |||||
| { | |||||
| caret->updatePosition(); | |||||
| } | |||||
| void CodeEditorComponent::setTabSize (const int numSpaces, const bool insertSpaces) throw() | void CodeEditorComponent::setTabSize (const int numSpaces, const bool insertSpaces) throw() | ||||
| { | { | ||||
| useSpacesForTabs = insertSpaces; | useSpacesForTabs = insertSpaces; | ||||
| @@ -240061,15 +240083,19 @@ void UIViewComponentPeer::toFront (bool makeActiveWindow) | |||||
| void UIViewComponentPeer::toBehind (ComponentPeer* other) | void UIViewComponentPeer::toBehind (ComponentPeer* other) | ||||
| { | { | ||||
| UIViewComponentPeer* o = (UIViewComponentPeer*) other; | |||||
| UIViewComponentPeer* const otherPeer = dynamic_cast <UIViewComponentPeer*> (other); | |||||
| jassert (otherPeer != 0); // wrong type of window? | |||||
| if (isSharedWindow) | |||||
| if (otherPeer != 0) | |||||
| { | { | ||||
| [[view superview] insertSubview: view belowSubview: o->view]; | |||||
| } | |||||
| else | |||||
| { | |||||
| jassertfalse // don't know how to do this | |||||
| if (isSharedWindow) | |||||
| { | |||||
| [[view superview] insertSubview: view belowSubview: otherPeer->view]; | |||||
| } | |||||
| else | |||||
| { | |||||
| jassertfalse // don't know how to do this | |||||
| } | |||||
| } | } | ||||
| } | } | ||||
| @@ -245320,19 +245346,23 @@ void NSViewComponentPeer::toFront (bool makeActiveWindow) | |||||
| void NSViewComponentPeer::toBehind (ComponentPeer* other) | void NSViewComponentPeer::toBehind (ComponentPeer* other) | ||||
| { | { | ||||
| NSViewComponentPeer* o = (NSViewComponentPeer*) other; | |||||
| NSViewComponentPeer* const otherPeer = dynamic_cast <NSViewComponentPeer*> (other); | |||||
| jassert (otherPeer != 0); // wrong type of window? | |||||
| if (isSharedWindow) | |||||
| if (otherPeer != 0) | |||||
| { | { | ||||
| [[view superview] addSubview: view | |||||
| positioned: NSWindowBelow | |||||
| relativeTo: o->view]; | |||||
| } | |||||
| else | |||||
| { | |||||
| [window orderWindow: NSWindowBelow | |||||
| relativeTo: o->window != 0 ? [o->window windowNumber] | |||||
| : nil ]; | |||||
| if (isSharedWindow) | |||||
| { | |||||
| [[view superview] addSubview: view | |||||
| positioned: NSWindowBelow | |||||
| relativeTo: otherPeer->view]; | |||||
| } | |||||
| else | |||||
| { | |||||
| [window orderWindow: NSWindowBelow | |||||
| relativeTo: otherPeer->window != 0 ? [otherPeer->window windowNumber] | |||||
| : nil ]; | |||||
| } | |||||
| } | } | ||||
| } | } | ||||
| @@ -10313,6 +10313,14 @@ public: | |||||
| void setHeight (const ValueType newHeight) throw() { h = newHeight; } | void setHeight (const ValueType newHeight) throw() { h = newHeight; } | ||||
| const Rectangle withX (const ValueType newX) const throw() { return Rectangle (newX, y, w, h); } | |||||
| const Rectangle withY (const ValueType newY) const throw() { return Rectangle (x, newY, w, h); } | |||||
| const Rectangle withWidth (const ValueType newWidth) const throw() { return Rectangle (x, y, newWidth, h); } | |||||
| const Rectangle withHeight (const ValueType newHeight) const throw() { return Rectangle (x, y, w, newHeight); } | |||||
| void setLeft (const ValueType newLeft) throw() | void setLeft (const ValueType newLeft) throw() | ||||
| { | { | ||||
| w = jmax (ValueType(), x + w - newLeft); | w = jmax (ValueType(), x + w - newLeft); | ||||
| @@ -21156,6 +21164,8 @@ public: | |||||
| void setFont (const Font& newFont); | void setFont (const Font& newFont); | ||||
| const Font& getFont() const throw() { return font; } | |||||
| void resetToDefaultColours(); | void resetToDefaultColours(); | ||||
| void setColourForTokenType (int tokenType, const Colour& colour); | void setColourForTokenType (int tokenType, const Colour& colour); | ||||
| @@ -21174,6 +21184,8 @@ public: | |||||
| void setScrollbarThickness (int thickness) throw(); | void setScrollbarThickness (int thickness) throw(); | ||||
| int getScrollbarThickness() const throw() { return scrollbarThickness; } | |||||
| void resized(); | void resized(); | ||||
| void paint (Graphics& g); | void paint (Graphics& g); | ||||
| bool keyPressed (const KeyPress& key); | bool keyPressed (const KeyPress& key); | ||||
| @@ -21182,6 +21194,8 @@ public: | |||||
| void mouseUp (const MouseEvent& e); | void mouseUp (const MouseEvent& e); | ||||
| void mouseDoubleClick (const MouseEvent& e); | void mouseDoubleClick (const MouseEvent& e); | ||||
| void mouseWheelMove (const MouseEvent& e, float wheelIncrementX, float wheelIncrementY); | void mouseWheelMove (const MouseEvent& e, float wheelIncrementX, float wheelIncrementY); | ||||
| void focusGained (FocusChangeType cause); | |||||
| void focusLost (FocusChangeType cause); | |||||
| void timerCallback(); | void timerCallback(); | ||||
| void scrollBarMoved (ScrollBar* scrollBarThatHasMoved, double newRangeStart); | void scrollBarMoved (ScrollBar* scrollBarThatHasMoved, double newRangeStart); | ||||
| void handleAsyncUpdate(); | void handleAsyncUpdate(); | ||||
| @@ -431,6 +431,7 @@ void CodeDocument::Position::setPositionMaintained (const bool isMaintained) thr | |||||
| } | } | ||||
| else | else | ||||
| { | { | ||||
| // If this happens, you may have deleted the document while there are Position objects that are still using it... | |||||
| jassert (owner->positionsToMaintain.contains (this)); | jassert (owner->positionsToMaintain.contains (this)); | ||||
| owner->positionsToMaintain.removeValue (this); | owner->positionsToMaintain.removeValue (this); | ||||
| } | } | ||||
| @@ -37,7 +37,8 @@ class CodeEditorComponent::CaretComponent : public Component, | |||||
| public Timer | public Timer | ||||
| { | { | ||||
| public: | public: | ||||
| CaretComponent() | |||||
| CaretComponent (CodeEditorComponent& owner_) | |||||
| : owner (owner_) | |||||
| { | { | ||||
| setAlwaysOnTop (true); | setAlwaysOnTop (true); | ||||
| setInterceptsMouseClicks (false, false); | setInterceptsMouseClicks (false, false); | ||||
| @@ -49,27 +50,29 @@ public: | |||||
| void paint (Graphics& g) | void paint (Graphics& g) | ||||
| { | { | ||||
| if (getParentComponent()->hasKeyboardFocus (true)) | |||||
| g.fillAll (findColour (CodeEditorComponent::caretColourId)); | |||||
| g.fillAll (findColour (CodeEditorComponent::caretColourId)); | |||||
| } | } | ||||
| void timerCallback() | void timerCallback() | ||||
| { | { | ||||
| setVisible (! isVisible()); | |||||
| setVisible (shouldBeShown() && ! isVisible()); | |||||
| } | } | ||||
| void updatePosition (CodeEditorComponent& owner) | |||||
| void updatePosition() | |||||
| { | { | ||||
| startTimer (400); | startTimer (400); | ||||
| setVisible (true); | |||||
| setVisible (shouldBeShown()); | |||||
| const Rectangle<int> pos (owner.getCharacterBounds (owner.getCaretPos())); | |||||
| setBounds (pos.getX(), pos.getY(), 2, pos.getHeight()); | |||||
| setBounds (owner.getCharacterBounds (owner.getCaretPos()).withWidth (2)); | |||||
| } | } | ||||
| private: | private: | ||||
| CodeEditorComponent& owner; | |||||
| CaretComponent (const CaretComponent&); | CaretComponent (const CaretComponent&); | ||||
| CaretComponent& operator= (const CaretComponent&); | CaretComponent& operator= (const CaretComponent&); | ||||
| bool shouldBeShown() const { return owner.hasKeyboardFocus (true); } | |||||
| }; | }; | ||||
| //============================================================================== | //============================================================================== | ||||
| @@ -314,7 +317,7 @@ CodeEditorComponent::CodeEditorComponent (CodeDocument& document_, | |||||
| addAndMakeVisible (horizontalScrollBar = new ScrollBar (false)); | addAndMakeVisible (horizontalScrollBar = new ScrollBar (false)); | ||||
| horizontalScrollBar->setSingleStepSize (1.0); | horizontalScrollBar->setSingleStepSize (1.0); | ||||
| addAndMakeVisible (caret = new CaretComponent()); | |||||
| addAndMakeVisible (caret = new CaretComponent (*this)); | |||||
| Font f (12.0f); | Font f (12.0f); | ||||
| f.setTypefaceName (Font::getDefaultMonospacedFontName()); | f.setTypefaceName (Font::getDefaultMonospacedFontName()); | ||||
| @@ -353,7 +356,7 @@ void CodeEditorComponent::codeDocumentChanged (const CodeDocument::Position& aff | |||||
| triggerAsyncUpdate(); | triggerAsyncUpdate(); | ||||
| caret->updatePosition (*this); | |||||
| caret->updatePosition(); | |||||
| columnToTryToMaintain = -1; | columnToTryToMaintain = -1; | ||||
| if (affectedTextEnd.getPosition() >= selectionStart.getPosition() | if (affectedTextEnd.getPosition() >= selectionStart.getPosition() | ||||
| @@ -373,7 +376,7 @@ void CodeEditorComponent::resized() | |||||
| columnsOnScreen = (int) ((getWidth() - scrollbarThickness) / charWidth); | columnsOnScreen = (int) ((getWidth() - scrollbarThickness) / charWidth); | ||||
| lines.clear(); | lines.clear(); | ||||
| rebuildLineTokens(); | rebuildLineTokens(); | ||||
| caret->updatePosition (*this); | |||||
| caret->updatePosition(); | |||||
| verticalScrollBar->setBounds (getWidth() - scrollbarThickness, 0, scrollbarThickness, getHeight() - scrollbarThickness); | verticalScrollBar->setBounds (getWidth() - scrollbarThickness, 0, scrollbarThickness, getHeight() - scrollbarThickness); | ||||
| horizontalScrollBar->setBounds (gutter, getHeight() - scrollbarThickness, getWidth() - scrollbarThickness - gutter, scrollbarThickness); | horizontalScrollBar->setBounds (gutter, getHeight() - scrollbarThickness, getWidth() - scrollbarThickness - gutter, scrollbarThickness); | ||||
| @@ -516,7 +519,7 @@ void CodeEditorComponent::moveCaretTo (const CodeDocument::Position& newPos, con | |||||
| deselectAll(); | deselectAll(); | ||||
| } | } | ||||
| caret->updatePosition (*this); | |||||
| caret->updatePosition(); | |||||
| scrollToKeepCaretOnScreen(); | scrollToKeepCaretOnScreen(); | ||||
| updateScrollBars(); | updateScrollBars(); | ||||
| } | } | ||||
| @@ -547,7 +550,7 @@ void CodeEditorComponent::scrollToLineInternal (int newFirstLineOnScreen) | |||||
| if (newFirstLineOnScreen != firstLineOnScreen) | if (newFirstLineOnScreen != firstLineOnScreen) | ||||
| { | { | ||||
| firstLineOnScreen = newFirstLineOnScreen; | firstLineOnScreen = newFirstLineOnScreen; | ||||
| caret->updatePosition (*this); | |||||
| caret->updatePosition(); | |||||
| updateCachedIterators (firstLineOnScreen); | updateCachedIterators (firstLineOnScreen); | ||||
| triggerAsyncUpdate(); | triggerAsyncUpdate(); | ||||
| @@ -561,7 +564,7 @@ void CodeEditorComponent::scrollToColumnInternal (double column) | |||||
| if (xOffset != newOffset) | if (xOffset != newOffset) | ||||
| { | { | ||||
| xOffset = newOffset; | xOffset = newOffset; | ||||
| caret->updatePosition (*this); | |||||
| caret->updatePosition(); | |||||
| repaint(); | repaint(); | ||||
| } | } | ||||
| } | } | ||||
| @@ -1071,8 +1074,16 @@ void CodeEditorComponent::mouseDoubleClick (const MouseEvent& e) | |||||
| void CodeEditorComponent::mouseWheelMove (const MouseEvent& e, float wheelIncrementX, float wheelIncrementY) | void CodeEditorComponent::mouseWheelMove (const MouseEvent& e, float wheelIncrementX, float wheelIncrementY) | ||||
| { | { | ||||
| verticalScrollBar->mouseWheelMove (e, 0, wheelIncrementY); | |||||
| horizontalScrollBar->mouseWheelMove (e, wheelIncrementX, 0); | |||||
| if ((verticalScrollBar->isVisible() && wheelIncrementY != 0) | |||||
| || (horizontalScrollBar->isVisible() && wheelIncrementX != 0)) | |||||
| { | |||||
| verticalScrollBar->mouseWheelMove (e, 0, wheelIncrementY); | |||||
| horizontalScrollBar->mouseWheelMove (e, wheelIncrementX, 0); | |||||
| } | |||||
| else | |||||
| { | |||||
| Component::mouseWheelMove (e, wheelIncrementX, wheelIncrementY); | |||||
| } | |||||
| } | } | ||||
| void CodeEditorComponent::scrollBarMoved (ScrollBar* scrollBarThatHasMoved, double newRangeStart) | void CodeEditorComponent::scrollBarMoved (ScrollBar* scrollBarThatHasMoved, double newRangeStart) | ||||
| @@ -1083,6 +1094,17 @@ void CodeEditorComponent::scrollBarMoved (ScrollBar* scrollBarThatHasMoved, doub | |||||
| scrollToColumnInternal (newRangeStart); | scrollToColumnInternal (newRangeStart); | ||||
| } | } | ||||
| //============================================================================== | |||||
| void CodeEditorComponent::focusGained (FocusChangeType cause) | |||||
| { | |||||
| caret->updatePosition(); | |||||
| } | |||||
| void CodeEditorComponent::focusLost (FocusChangeType cause) | |||||
| { | |||||
| caret->updatePosition(); | |||||
| } | |||||
| //============================================================================== | //============================================================================== | ||||
| void CodeEditorComponent::setTabSize (const int numSpaces, const bool insertSpaces) throw() | void CodeEditorComponent::setTabSize (const int numSpaces, const bool insertSpaces) throw() | ||||
| { | { | ||||
| @@ -175,6 +175,9 @@ public: | |||||
| */ | */ | ||||
| void setFont (const Font& newFont); | void setFont (const Font& newFont); | ||||
| /** Returns the font that the editor is using. */ | |||||
| const Font& getFont() const throw() { return font; } | |||||
| /** Resets the syntax highlighting colours to the default ones provided by the | /** Resets the syntax highlighting colours to the default ones provided by the | ||||
| code tokeniser. | code tokeniser. | ||||
| @see CodeTokeniser::getDefaultColour | @see CodeTokeniser::getDefaultColour | ||||
| @@ -217,6 +220,9 @@ public: | |||||
| /** Changes the size of the scrollbars. */ | /** Changes the size of the scrollbars. */ | ||||
| void setScrollbarThickness (int thickness) throw(); | void setScrollbarThickness (int thickness) throw(); | ||||
| /** Returns the thickness of the scrollbars. */ | |||||
| int getScrollbarThickness() const throw() { return scrollbarThickness; } | |||||
| //============================================================================== | //============================================================================== | ||||
| /** @internal */ | /** @internal */ | ||||
| void resized(); | void resized(); | ||||
| @@ -235,6 +241,10 @@ public: | |||||
| /** @internal */ | /** @internal */ | ||||
| void mouseWheelMove (const MouseEvent& e, float wheelIncrementX, float wheelIncrementY); | void mouseWheelMove (const MouseEvent& e, float wheelIncrementX, float wheelIncrementY); | ||||
| /** @internal */ | /** @internal */ | ||||
| void focusGained (FocusChangeType cause); | |||||
| /** @internal */ | |||||
| void focusLost (FocusChangeType cause); | |||||
| /** @internal */ | |||||
| void timerCallback(); | void timerCallback(); | ||||
| /** @internal */ | /** @internal */ | ||||
| void scrollBarMoved (ScrollBar* scrollBarThatHasMoved, double newRangeStart); | void scrollBarMoved (ScrollBar* scrollBarThatHasMoved, double newRangeStart); | ||||
| @@ -161,6 +161,18 @@ public: | |||||
| /** Changes the rectangle's height */ | /** Changes the rectangle's height */ | ||||
| void setHeight (const ValueType newHeight) throw() { h = newHeight; } | void setHeight (const ValueType newHeight) throw() { h = newHeight; } | ||||
| /** Returns a rectangle which has the same size and y-position as this one, but with a different x-position. */ | |||||
| const Rectangle withX (const ValueType newX) const throw() { return Rectangle (newX, y, w, h); } | |||||
| /** Returns a rectangle which has the same size and x-position as this one, but with a different y-position. */ | |||||
| const Rectangle withY (const ValueType newY) const throw() { return Rectangle (x, newY, w, h); } | |||||
| /** Returns a rectangle which has the same position and height as this one, but with a different width. */ | |||||
| const Rectangle withWidth (const ValueType newWidth) const throw() { return Rectangle (x, y, newWidth, h); } | |||||
| /** Returns a rectangle which has the same position and width as this one, but with a different height. */ | |||||
| const Rectangle withHeight (const ValueType newHeight) const throw() { return Rectangle (x, y, w, newHeight); } | |||||
| /** Moves the x position, adjusting the width so that the right-hand edge remains in the same place. | /** Moves the x position, adjusting the width so that the right-hand edge remains in the same place. | ||||
| If the x is moved to be on the right of the current right-hand edge, the width will be set to zero. | If the x is moved to be on the right of the current right-hand edge, the width will be set to zero. | ||||
| */ | */ | ||||
| @@ -592,15 +592,19 @@ void UIViewComponentPeer::toFront (bool makeActiveWindow) | |||||
| void UIViewComponentPeer::toBehind (ComponentPeer* other) | void UIViewComponentPeer::toBehind (ComponentPeer* other) | ||||
| { | { | ||||
| UIViewComponentPeer* o = (UIViewComponentPeer*) other; | |||||
| UIViewComponentPeer* const otherPeer = dynamic_cast <UIViewComponentPeer*> (other); | |||||
| jassert (otherPeer != 0); // wrong type of window? | |||||
| if (isSharedWindow) | |||||
| if (otherPeer != 0) | |||||
| { | { | ||||
| [[view superview] insertSubview: view belowSubview: o->view]; | |||||
| } | |||||
| else | |||||
| { | |||||
| jassertfalse // don't know how to do this | |||||
| if (isSharedWindow) | |||||
| { | |||||
| [[view superview] insertSubview: view belowSubview: otherPeer->view]; | |||||
| } | |||||
| else | |||||
| { | |||||
| jassertfalse // don't know how to do this | |||||
| } | |||||
| } | } | ||||
| } | } | ||||
| @@ -1178,19 +1178,23 @@ void NSViewComponentPeer::toFront (bool makeActiveWindow) | |||||
| void NSViewComponentPeer::toBehind (ComponentPeer* other) | void NSViewComponentPeer::toBehind (ComponentPeer* other) | ||||
| { | { | ||||
| NSViewComponentPeer* o = (NSViewComponentPeer*) other; | |||||
| NSViewComponentPeer* const otherPeer = dynamic_cast <NSViewComponentPeer*> (other); | |||||
| jassert (otherPeer != 0); // wrong type of window? | |||||
| if (isSharedWindow) | |||||
| { | |||||
| [[view superview] addSubview: view | |||||
| positioned: NSWindowBelow | |||||
| relativeTo: o->view]; | |||||
| } | |||||
| else | |||||
| if (otherPeer != 0) | |||||
| { | { | ||||
| [window orderWindow: NSWindowBelow | |||||
| relativeTo: o->window != 0 ? [o->window windowNumber] | |||||
| : nil ]; | |||||
| if (isSharedWindow) | |||||
| { | |||||
| [[view superview] addSubview: view | |||||
| positioned: NSWindowBelow | |||||
| relativeTo: otherPeer->view]; | |||||
| } | |||||
| else | |||||
| { | |||||
| [window orderWindow: NSWindowBelow | |||||
| relativeTo: otherPeer->window != 0 ? [otherPeer->window windowNumber] | |||||
| : nil ]; | |||||
| } | |||||
| } | } | ||||
| } | } | ||||