Browse Source

Minor additions to Rectangle and CodeEditorComponent. Jucer development.

tags/2021-05-28
Julian Storer 15 years ago
parent
commit
49b47cc866
13 changed files with 479 additions and 99 deletions
  1. +103
    -14
      extras/Jucer (experimental)/Source/model/jucer_CodeGenerator.cpp
  2. +44
    -6
      extras/Jucer (experimental)/Source/model/jucer_CodeGenerator.h
  3. +17
    -9
      extras/Jucer (experimental)/Source/model/jucer_ComponentDocument.cpp
  4. +6
    -2
      extras/Jucer (experimental)/Source/model/jucer_ComponentDocument.h
  5. +144
    -0
      extras/Jucer (experimental)/Source/ui/Component Editor/jucer_ComponentEditor.cpp
  6. +64
    -34
      juce_amalgamated.cpp
  7. +14
    -0
      juce_amalgamated.h
  8. +1
    -0
      src/gui/components/code_editor/juce_CodeDocument.cpp
  9. +38
    -16
      src/gui/components/code_editor/juce_CodeEditorComponent.cpp
  10. +10
    -0
      src/gui/components/code_editor/juce_CodeEditorComponent.h
  11. +12
    -0
      src/gui/graphics/geometry/juce_Rectangle.h
  12. +11
    -7
      src/native/mac/juce_iphone_UIViewComponentPeer.mm
  13. +15
    -11
      src/native/mac/juce_mac_NSViewComponentPeer.mm

+ 103
- 14
extras/Jucer (experimental)/Source/model/jucer_CodeGenerator.cpp View File

@@ -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();
sectionContent.clear();
@@ -339,19 +403,23 @@ void CodeGenerator::CustomisedCodeSnippets::reloadFrom (const String& fileConten
sectionNames.add (tag);
CodeDocument* doc = new CodeDocument();
CodeDocumentRef::Ptr doc (new CodeDocumentRef (new CodeDocument()));
sectionContent.add (doc);
doc->replaceAllContent (content);
doc->getDocument().replaceAllContent (content);
doc->getDocument().clearUndoHistory();
doc->getDocument().setSavePoint();
i = endLine;
}
}
}
}
sendSynchronousChangeMessage (this);
}
void CodeGenerator::CustomisedCodeSnippets::applyTo (String& fileContent) const
void CodeGenerator::CustomCodeList::applyTo (String& fileContent) const
{
StringArray lines;
lines.addLines (fileContent);
@@ -400,12 +468,31 @@ void CodeGenerator::CustomisedCodeSnippets::applyTo (String& fileContent) const
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);
@@ -415,24 +502,26 @@ CodeDocument* CodeGenerator::CustomisedCodeSnippets::getDocumentFor (const Strin
if (createIfNotFound)
{
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;
}
const String CodeGenerator::CustomisedCodeSnippets::getSectionContent (const String& sectionName) const
const String CodeGenerator::CustomCodeList::getSectionContent (const String& sectionName) const
{
const int index = sectionNames.indexOf (sectionName);
if (index >= 0)
return sectionContent[index]->getAllContent();
return sectionContent[index]->getDocument().getAllContent();
return String::empty;
}
void CodeGenerator::CustomisedCodeSnippets::removeSection (const String& sectionName)
void CodeGenerator::CustomCodeList::removeSection (const String& sectionName)
{
const int index = sectionNames.indexOf (sectionName);


+ 44
- 6
extras/Jucer (experimental)/Source/model/jucer_CodeGenerator.h View File

@@ -75,23 +75,61 @@ public:
//==============================================================================
// An object to load and store all the user-defined bits of code as documents.
class CustomisedCodeSnippets
class CustomCodeList : public ChangeBroadcaster
{
public:
CustomisedCodeSnippets();
~CustomisedCodeSnippets();
CustomCodeList();
~CustomCodeList();
void reloadFrom (const String& fileContent);
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;
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:
StringArray sectionNames;
OwnedArray <CodeDocument> sectionContent;
ReferenceCountedArray <CodeDocumentRef> sectionContent;
};
//==============================================================================


+ 17
- 9
extras/Jucer (experimental)/Source/model/jucer_ComponentDocument.cpp View File

@@ -80,19 +80,24 @@ void ComponentDocument::beginNewTransaction()
undoManager.beginNewTransaction();
}
void ComponentDocument::valueTreePropertyChanged (ValueTree& treeWhosePropertyHasChanged, const var::identifier& property)
void ComponentDocument::changed()
{
changedSinceSaved = true;
}
void ComponentDocument::valueTreePropertyChanged (ValueTree& treeWhosePropertyHasChanged, const var::identifier& property)
{
changed();
}
void ComponentDocument::valueTreeChildrenChanged (ValueTree& treeWhoseChildHasChanged)
{
changedSinceSaved = true;
changed();
}
void ComponentDocument::valueTreeParentChanged (ValueTree& treeWhoseParentHasChanged)
{
changedSinceSaved = true;
changed();
}
bool ComponentDocument::isComponentFile (const File& file)
@@ -114,6 +119,9 @@ bool ComponentDocument::isComponentFile (const File& file)
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)
{
CodeGenerator codeGen;
@@ -128,20 +136,20 @@ void ComponentDocument::writeCode (OutputStream& cpp, OutputStream& header)
}
{
String code (BinaryData::jucer_ComponentTemplate_cpp);
String code (getCppTemplate());
String oldContent;
codeGen.applyToCode (code, cppFile, false, project);
customisedCodeSnippets.applyTo (code);
customCode.applyTo (code);
cpp << code;
}
{
String code (BinaryData::jucer_ComponentTemplate_h);
String code (getHeaderTemplate());
String oldContent;
codeGen.applyToCode (code, cppFile.withFileExtension (".h"), false, project);
customisedCodeSnippets.applyTo (code);
customCode.applyTo (code);
header << code;
}
}
@@ -224,7 +232,7 @@ bool ComponentDocument::reload()
undoManager.clearUndoHistory();
changedSinceSaved = false;
customisedCodeSnippets.reloadFrom (cppFile.loadFileAsString());
customCode.reloadFrom (cppFile.loadFileAsString());
return true;
}
}
@@ -234,7 +242,7 @@ bool ComponentDocument::reload()
bool ComponentDocument::hasChangedSinceLastSave()
{
return changedSinceSaved;
return changedSinceSaved || customCode.needsSaving();
}
void ComponentDocument::createSubTreeIfNotThere (const String& name)


+ 6
- 2
extras/Jucer (experimental)/Source/model/jucer_ComponentDocument.h View File

@@ -47,6 +47,7 @@ public:
bool save();
bool reload();
bool hasChangedSinceLastSave();
void changed();
const File getCppFile() const { return cppFile; }
//==============================================================================
@@ -136,7 +137,10 @@ public:
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; }
@@ -164,7 +168,7 @@ private:
File cppFile;
ValueTree root;
ScopedPointer<MarkerList> markersX, markersY;
CodeGenerator::CustomisedCodeSnippets customisedCodeSnippets;
CodeGenerator::CustomCodeList customCode;
mutable UndoManager undoManager;
bool changedSinceSaved;


+ 144
- 0
extras/Jucer (experimental)/Source/ui/Component Editor/jucer_ComponentEditor.cpp View File

@@ -536,14 +536,158 @@ public:
CodeEditorHolder (ComponentEditor& editor_)
: editor (editor_)
{
addAndMakeVisible (viewport = new Viewport());
viewport->setScrollBarsShown (true, false);
viewport->setViewedComponent (new ContentHolder (editor));
}
~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:
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;
};
//==============================================================================


+ 64
- 34
juce_amalgamated.cpp View File

@@ -43436,6 +43436,7 @@ void CodeDocument::Position::setPositionMaintained (const bool isMaintained) thr
}
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));
owner->positionsToMaintain.removeValue (this);
}
@@ -43949,7 +43950,8 @@ class CodeEditorComponent::CaretComponent : public Component,
public Timer
{
public:
CaretComponent()
CaretComponent (CodeEditorComponent& owner_)
: owner (owner_)
{
setAlwaysOnTop (true);
setInterceptsMouseClicks (false, false);
@@ -43961,27 +43963,29 @@ public:

void paint (Graphics& g)
{
if (getParentComponent()->hasKeyboardFocus (true))
g.fillAll (findColour (CodeEditorComponent::caretColourId));
g.fillAll (findColour (CodeEditorComponent::caretColourId));
}

void timerCallback()
{
setVisible (! isVisible());
setVisible (shouldBeShown() && ! isVisible());
}

void updatePosition (CodeEditorComponent& owner)
void updatePosition()
{
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:
CodeEditorComponent& owner;

CaretComponent (const CaretComponent&);
CaretComponent& operator= (const CaretComponent&);

bool shouldBeShown() const { return owner.hasKeyboardFocus (true); }
};

class CodeEditorComponent::CodeEditorLine
@@ -44224,7 +44228,7 @@ CodeEditorComponent::CodeEditorComponent (CodeDocument& document_,
addAndMakeVisible (horizontalScrollBar = new ScrollBar (false));
horizontalScrollBar->setSingleStepSize (1.0);

addAndMakeVisible (caret = new CaretComponent());
addAndMakeVisible (caret = new CaretComponent (*this));

Font f (12.0f);
f.setTypefaceName (Font::getDefaultMonospacedFontName());
@@ -44262,7 +44266,7 @@ void CodeEditorComponent::codeDocumentChanged (const CodeDocument::Position& aff

triggerAsyncUpdate();

caret->updatePosition (*this);
caret->updatePosition();
columnToTryToMaintain = -1;

if (affectedTextEnd.getPosition() >= selectionStart.getPosition()
@@ -44282,7 +44286,7 @@ void CodeEditorComponent::resized()
columnsOnScreen = (int) ((getWidth() - scrollbarThickness) / charWidth);
lines.clear();
rebuildLineTokens();
caret->updatePosition (*this);
caret->updatePosition();

verticalScrollBar->setBounds (getWidth() - scrollbarThickness, 0, scrollbarThickness, getHeight() - scrollbarThickness);
horizontalScrollBar->setBounds (gutter, getHeight() - scrollbarThickness, getWidth() - scrollbarThickness - gutter, scrollbarThickness);
@@ -44424,7 +44428,7 @@ void CodeEditorComponent::moveCaretTo (const CodeDocument::Position& newPos, con
deselectAll();
}

caret->updatePosition (*this);
caret->updatePosition();
scrollToKeepCaretOnScreen();
updateScrollBars();
}
@@ -44455,7 +44459,7 @@ void CodeEditorComponent::scrollToLineInternal (int newFirstLineOnScreen)
if (newFirstLineOnScreen != firstLineOnScreen)
{
firstLineOnScreen = newFirstLineOnScreen;
caret->updatePosition (*this);
caret->updatePosition();

updateCachedIterators (firstLineOnScreen);
triggerAsyncUpdate();
@@ -44469,7 +44473,7 @@ void CodeEditorComponent::scrollToColumnInternal (double column)
if (xOffset != newOffset)
{
xOffset = newOffset;
caret->updatePosition (*this);
caret->updatePosition();
repaint();
}
}
@@ -44967,8 +44971,16 @@ void CodeEditorComponent::mouseDoubleClick (const MouseEvent& e)

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)
@@ -44979,6 +44991,16 @@ void CodeEditorComponent::scrollBarMoved (ScrollBar* scrollBarThatHasMoved, doub
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()
{
useSpacesForTabs = insertSpaces;
@@ -240061,15 +240083,19 @@ void UIViewComponentPeer::toFront (bool makeActiveWindow)

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)
{
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 ];
}
}
}



+ 14
- 0
juce_amalgamated.h View File

@@ -10313,6 +10313,14 @@ public:

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()
{
w = jmax (ValueType(), x + w - newLeft);
@@ -21156,6 +21164,8 @@ public:

void setFont (const Font& newFont);

const Font& getFont() const throw() { return font; }

void resetToDefaultColours();

void setColourForTokenType (int tokenType, const Colour& colour);
@@ -21174,6 +21184,8 @@ public:

void setScrollbarThickness (int thickness) throw();

int getScrollbarThickness() const throw() { return scrollbarThickness; }

void resized();
void paint (Graphics& g);
bool keyPressed (const KeyPress& key);
@@ -21182,6 +21194,8 @@ public:
void mouseUp (const MouseEvent& e);
void mouseDoubleClick (const MouseEvent& e);
void mouseWheelMove (const MouseEvent& e, float wheelIncrementX, float wheelIncrementY);
void focusGained (FocusChangeType cause);
void focusLost (FocusChangeType cause);
void timerCallback();
void scrollBarMoved (ScrollBar* scrollBarThatHasMoved, double newRangeStart);
void handleAsyncUpdate();


+ 1
- 0
src/gui/components/code_editor/juce_CodeDocument.cpp View File

@@ -431,6 +431,7 @@ void CodeDocument::Position::setPositionMaintained (const bool isMaintained) thr
}
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));
owner->positionsToMaintain.removeValue (this);
}


+ 38
- 16
src/gui/components/code_editor/juce_CodeEditorComponent.cpp View File

@@ -37,7 +37,8 @@ class CodeEditorComponent::CaretComponent : public Component,
public Timer
{
public:
CaretComponent()
CaretComponent (CodeEditorComponent& owner_)
: owner (owner_)
{
setAlwaysOnTop (true);
setInterceptsMouseClicks (false, false);
@@ -49,27 +50,29 @@ public:
void paint (Graphics& g)
{
if (getParentComponent()->hasKeyboardFocus (true))
g.fillAll (findColour (CodeEditorComponent::caretColourId));
g.fillAll (findColour (CodeEditorComponent::caretColourId));
}
void timerCallback()
{
setVisible (! isVisible());
setVisible (shouldBeShown() && ! isVisible());
}
void updatePosition (CodeEditorComponent& owner)
void updatePosition()
{
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:
CodeEditorComponent& owner;
CaretComponent (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));
horizontalScrollBar->setSingleStepSize (1.0);
addAndMakeVisible (caret = new CaretComponent());
addAndMakeVisible (caret = new CaretComponent (*this));
Font f (12.0f);
f.setTypefaceName (Font::getDefaultMonospacedFontName());
@@ -353,7 +356,7 @@ void CodeEditorComponent::codeDocumentChanged (const CodeDocument::Position& aff
triggerAsyncUpdate();
caret->updatePosition (*this);
caret->updatePosition();
columnToTryToMaintain = -1;
if (affectedTextEnd.getPosition() >= selectionStart.getPosition()
@@ -373,7 +376,7 @@ void CodeEditorComponent::resized()
columnsOnScreen = (int) ((getWidth() - scrollbarThickness) / charWidth);
lines.clear();
rebuildLineTokens();
caret->updatePosition (*this);
caret->updatePosition();
verticalScrollBar->setBounds (getWidth() - scrollbarThickness, 0, scrollbarThickness, getHeight() - scrollbarThickness);
horizontalScrollBar->setBounds (gutter, getHeight() - scrollbarThickness, getWidth() - scrollbarThickness - gutter, scrollbarThickness);
@@ -516,7 +519,7 @@ void CodeEditorComponent::moveCaretTo (const CodeDocument::Position& newPos, con
deselectAll();
}
caret->updatePosition (*this);
caret->updatePosition();
scrollToKeepCaretOnScreen();
updateScrollBars();
}
@@ -547,7 +550,7 @@ void CodeEditorComponent::scrollToLineInternal (int newFirstLineOnScreen)
if (newFirstLineOnScreen != firstLineOnScreen)
{
firstLineOnScreen = newFirstLineOnScreen;
caret->updatePosition (*this);
caret->updatePosition();
updateCachedIterators (firstLineOnScreen);
triggerAsyncUpdate();
@@ -561,7 +564,7 @@ void CodeEditorComponent::scrollToColumnInternal (double column)
if (xOffset != newOffset)
{
xOffset = newOffset;
caret->updatePosition (*this);
caret->updatePosition();
repaint();
}
}
@@ -1071,8 +1074,16 @@ void CodeEditorComponent::mouseDoubleClick (const MouseEvent& e)
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)
@@ -1083,6 +1094,17 @@ void CodeEditorComponent::scrollBarMoved (ScrollBar* scrollBarThatHasMoved, doub
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()
{


+ 10
- 0
src/gui/components/code_editor/juce_CodeEditorComponent.h View File

@@ -175,6 +175,9 @@ public:
*/
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
code tokeniser.
@see CodeTokeniser::getDefaultColour
@@ -217,6 +220,9 @@ public:
/** Changes the size of the scrollbars. */
void setScrollbarThickness (int thickness) throw();
/** Returns the thickness of the scrollbars. */
int getScrollbarThickness() const throw() { return scrollbarThickness; }
//==============================================================================
/** @internal */
void resized();
@@ -235,6 +241,10 @@ public:
/** @internal */
void mouseWheelMove (const MouseEvent& e, float wheelIncrementX, float wheelIncrementY);
/** @internal */
void focusGained (FocusChangeType cause);
/** @internal */
void focusLost (FocusChangeType cause);
/** @internal */
void timerCallback();
/** @internal */
void scrollBarMoved (ScrollBar* scrollBarThatHasMoved, double newRangeStart);


+ 12
- 0
src/gui/graphics/geometry/juce_Rectangle.h View File

@@ -161,6 +161,18 @@ public:
/** Changes the rectangle's height */
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.
If the x is moved to be on the right of the current right-hand edge, the width will be set to zero.
*/


+ 11
- 7
src/native/mac/juce_iphone_UIViewComponentPeer.mm View File

@@ -592,15 +592,19 @@ void UIViewComponentPeer::toFront (bool makeActiveWindow)
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
}
}
}


+ 15
- 11
src/native/mac/juce_mac_NSViewComponentPeer.mm View File

@@ -1178,19 +1178,23 @@ void NSViewComponentPeer::toFront (bool makeActiveWindow)
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 ];
}
}
}


Loading…
Cancel
Save