| @@ -378,9 +378,9 @@ CodeGenerator::CustomCodeList::~CustomCodeList() | |||||
| void CodeGenerator::CustomCodeList::reloadFrom (const String& fileContent) | void CodeGenerator::CustomCodeList::reloadFrom (const String& fileContent) | ||||
| { | { | ||||
| sectionNames.clear(); | |||||
| sectionContent.clear(); | |||||
| StringArray newNames; | |||||
| ReferenceCountedArray<CodeDocumentRef> newContent; | |||||
| StringArray lines; | StringArray lines; | ||||
| lines.addLines (fileContent); | lines.addLines (fileContent); | ||||
| @@ -400,22 +400,28 @@ void CodeGenerator::CustomCodeList::reloadFrom (const String& fileContent) | |||||
| if (endLine > i) | if (endLine > i) | ||||
| { | { | ||||
| String content (lines.joinIntoString (newLine, i + 1, endLine - i - 1)); | String content (lines.joinIntoString (newLine, i + 1, endLine - i - 1)); | ||||
| newNames.add (tag); | |||||
| sectionNames.add (tag); | |||||
| CodeDocumentRef::Ptr doc (new CodeDocumentRef (new CodeDocument())); | |||||
| sectionContent.add (doc); | |||||
| doc->getDocument().replaceAllContent (content); | |||||
| doc->getDocument().clearUndoHistory(); | |||||
| doc->getDocument().setSavePoint(); | |||||
| CodeDocumentRef::Ptr doc (getDocumentFor (tag, false)); | |||||
| if (doc == 0) | |||||
| { | |||||
| CodeDocument* const codeDoc = new CodeDocument(); | |||||
| doc = new CodeDocumentRef (codeDoc); | |||||
| codeDoc->replaceAllContent (content); | |||||
| codeDoc->clearUndoHistory(); | |||||
| codeDoc->setSavePoint(); | |||||
| } | |||||
| newContent.add (doc); | |||||
| i = endLine; | i = endLine; | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| sectionNames = newNames; | |||||
| sectionContent = newContent; | |||||
| sendSynchronousChangeMessage (this); | sendSynchronousChangeMessage (this); | ||||
| } | } | ||||
| @@ -90,14 +90,13 @@ public: | |||||
| class CodeDocumentRef : public ReferenceCountedObject | class CodeDocumentRef : public ReferenceCountedObject | ||||
| { | { | ||||
| public: | public: | ||||
| CodeDocumentRef (CodeDocument* doc_) : doc (doc_) {} | |||||
| CodeDocument& getDocument() const throw() { return *doc; } | |||||
| CodeDocumentRef (CodeDocument* doc_) : doc (doc_) {} | |||||
| CodeDocument& getDocument() const throw() { return *doc; } | |||||
| typedef ReferenceCountedObjectPtr<CodeDocumentRef> Ptr; | typedef ReferenceCountedObjectPtr<CodeDocumentRef> Ptr; | ||||
| private: | private: | ||||
| CodeDocument* doc; | |||||
| CodeDocument* const doc; | |||||
| }; | }; | ||||
| //============================================================================== | //============================================================================== | ||||
| @@ -122,6 +122,20 @@ bool ComponentDocument::isComponentFile (const File& file) | |||||
| const String ComponentDocument::getCppTemplate() const { return String (BinaryData::jucer_ComponentTemplate_cpp); } | const String ComponentDocument::getCppTemplate() const { return String (BinaryData::jucer_ComponentTemplate_cpp); } | ||||
| const String ComponentDocument::getHeaderTemplate() const { return String (BinaryData::jucer_ComponentTemplate_h); } | const String ComponentDocument::getHeaderTemplate() const { return String (BinaryData::jucer_ComponentTemplate_h); } | ||||
| const String ComponentDocument::getCppContent() | |||||
| { | |||||
| MemoryOutputStream cpp, header; | |||||
| writeCode (cpp, header); | |||||
| return cpp.toUTF8(); | |||||
| } | |||||
| const String ComponentDocument::getHeaderContent() | |||||
| { | |||||
| MemoryOutputStream cpp, header; | |||||
| writeCode (cpp, header); | |||||
| return header.toUTF8(); | |||||
| } | |||||
| void ComponentDocument::writeCode (OutputStream& cpp, OutputStream& header) | void ComponentDocument::writeCode (OutputStream& cpp, OutputStream& header) | ||||
| { | { | ||||
| CodeGenerator codeGen; | CodeGenerator codeGen; | ||||
| @@ -142,6 +142,9 @@ public: | |||||
| const String getCppTemplate() const; | const String getCppTemplate() const; | ||||
| const String getHeaderTemplate() const; | const String getHeaderTemplate() const; | ||||
| const String getCppContent(); | |||||
| const String getHeaderContent(); | |||||
| //============================================================================== | //============================================================================== | ||||
| ValueTree& getRoot() { return root; } | ValueTree& getRoot() { return root; } | ||||
| ValueTree getComponentGroup() const; | ValueTree getComponentGroup() const; | ||||
| @@ -530,15 +530,20 @@ private: | |||||
| }; | }; | ||||
| //============================================================================== | //============================================================================== | ||||
| class ComponentEditor::CodeEditorHolder : public Component | |||||
| class ComponentEditor::CodeEditorHolder : public Component, | |||||
| public ButtonListener | |||||
| { | { | ||||
| public: | public: | ||||
| CodeEditorHolder (ComponentEditor& editor_) | CodeEditorHolder (ComponentEditor& editor_) | ||||
| : editor (editor_) | |||||
| : editor (editor_), switchFileButton (String::empty), showingHeader (true) | |||||
| { | { | ||||
| addAndMakeVisible (viewport = new Viewport()); | |||||
| viewport->setScrollBarsShown (true, false); | |||||
| viewport->setViewedComponent (new ContentHolder (editor)); | |||||
| addAndMakeVisible (&viewport); | |||||
| viewport.setScrollBarsShown (true, false); | |||||
| addAndMakeVisible (&switchFileButton); | |||||
| buttonClicked (0); | |||||
| switchFileButton.addButtonListener (this); | |||||
| } | } | ||||
| ~CodeEditorHolder() | ~CodeEditorHolder() | ||||
| @@ -547,26 +552,36 @@ public: | |||||
| void resized() | void resized() | ||||
| { | { | ||||
| viewport->setBounds (getLocalBounds()); | |||||
| viewport.setBounds (getLocalBounds()); | |||||
| int visWidth = viewport.getMaximumVisibleWidth(); | |||||
| dynamic_cast <ContentHolder*> (viewport.getViewedComponent())->updateSize (visWidth); | |||||
| int visWidth = viewport->getMaximumVisibleWidth(); | |||||
| dynamic_cast <ContentHolder*> (viewport->getViewedComponent())->updateSize (visWidth); | |||||
| if (viewport.getMaximumVisibleWidth() != visWidth) | |||||
| dynamic_cast <ContentHolder*> (viewport.getViewedComponent())->updateSize (viewport.getMaximumVisibleWidth()); | |||||
| if (viewport->getMaximumVisibleWidth() != visWidth) | |||||
| dynamic_cast <ContentHolder*> (viewport->getViewedComponent())->updateSize (viewport->getMaximumVisibleWidth()); | |||||
| switchFileButton.setBounds (getWidth() - 150, 4, 120, 20); | |||||
| } | |||||
| void buttonClicked (Button*) | |||||
| { | |||||
| showingHeader = ! showingHeader; | |||||
| viewport.setViewedComponent (new ContentHolder (editor.getDocument(), showingHeader)); | |||||
| resized(); | |||||
| switchFileButton.setButtonText (showingHeader ? "Show CPP file" : "Show header file"); | |||||
| } | } | ||||
| private: | private: | ||||
| ComponentEditor& editor; | |||||
| enum { updateCommandId = 0x23427fa1 }; | enum { updateCommandId = 0x23427fa1 }; | ||||
| //============================================================================== | |||||
| class EditorHolder : public Component, | class EditorHolder : public Component, | ||||
| public CodeDocument::Listener | public CodeDocument::Listener | ||||
| { | { | ||||
| public: | public: | ||||
| EditorHolder (const CodeGenerator::CustomCodeList::CodeDocumentRef::Ptr doc, | 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) | |||||
| const String& textBefore, const String& textAfter) | |||||
| : document (doc), cppTokeniser(), codeEditor (doc->getDocument(), &cppTokeniser) | |||||
| { | { | ||||
| linesBefore.addLines (textBefore); | linesBefore.addLines (textBefore); | ||||
| linesAfter.addLines (textAfter); | linesAfter.addLines (textAfter); | ||||
| @@ -603,7 +618,7 @@ private: | |||||
| codeEditor.setBounds (0, fontHeight * linesBefore.size() + 1, | codeEditor.setBounds (0, fontHeight * linesBefore.size() + 1, | ||||
| width, 2 + codeEditor.getScrollbarThickness() | width, 2 + codeEditor.getScrollbarThickness() | ||||
| + fontHeight * jmax (1, document->getDocument().getNumLines())); | |||||
| + fontHeight * jlimit (1, 50, document->getDocument().getNumLines())); | |||||
| setSize (width, (linesBefore.size() + linesAfter.size()) * fontHeight + codeEditor.getHeight()); | setSize (width, (linesBefore.size() + linesAfter.size()) * fontHeight + codeEditor.getHeight()); | ||||
| } | } | ||||
| @@ -616,27 +631,29 @@ private: | |||||
| getParentComponent()->handleCommandMessage (updateCommandId); | getParentComponent()->handleCommandMessage (updateCommandId); | ||||
| } | } | ||||
| private: | |||||
| const CodeGenerator::CustomCodeList::CodeDocumentRef::Ptr document; | const CodeGenerator::CustomCodeList::CodeDocumentRef::Ptr document; | ||||
| CPlusPlusCodeTokeniser cppTokeniser; | CPlusPlusCodeTokeniser cppTokeniser; | ||||
| CodeEditorComponent codeEditor; | CodeEditorComponent codeEditor; | ||||
| StringArray linesBefore, linesAfter; | StringArray linesBefore, linesAfter; | ||||
| }; | }; | ||||
| //============================================================================== | |||||
| class ContentHolder : public Component, | class ContentHolder : public Component, | ||||
| public ChangeListener | public ChangeListener | ||||
| { | { | ||||
| public: | public: | ||||
| ContentHolder (ComponentEditor& editor_) | |||||
| : editor (editor_) | |||||
| ContentHolder (ComponentDocument& document_, bool isHeader_) | |||||
| : document (document_), isHeader (isHeader_) | |||||
| { | { | ||||
| setOpaque (true); | setOpaque (true); | ||||
| editor.getDocument().getCustomCodeList().addChangeListener (this); | |||||
| document.getCustomCodeList().addChangeListener (this); | |||||
| changeListenerCallback (0); | changeListenerCallback (0); | ||||
| } | } | ||||
| ~ContentHolder() | ~ContentHolder() | ||||
| { | { | ||||
| editor.getDocument().getCustomCodeList().removeChangeListener (this); | |||||
| document.getCustomCodeList().removeChangeListener (this); | |||||
| } | } | ||||
| void paint (Graphics& g) | void paint (Graphics& g) | ||||
| @@ -647,12 +664,12 @@ private: | |||||
| void updateSize (int width) | void updateSize (int width) | ||||
| { | { | ||||
| int y = 2; | int y = 2; | ||||
| for (int i = 0; i < editors.size(); ++i) | 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; | |||||
| EditorHolder* const ed = editors.getUnchecked(i); | |||||
| ed->updateSize (width - 8); | |||||
| ed->setTopLeftPosition (4, y + 1); | |||||
| y = ed->getBottom() + 1; | |||||
| } | } | ||||
| setSize (width, y + 2); | setSize (width, y + 2); | ||||
| @@ -662,12 +679,13 @@ private: | |||||
| { | { | ||||
| editors.clear(); | editors.clear(); | ||||
| CodeGenerator::CustomCodeList::Iterator iter (editor.getDocument().getCppTemplate(), | |||||
| editor.getDocument().getCustomCodeList()); | |||||
| CodeGenerator::CustomCodeList::Iterator iter (isHeader ? document.getHeaderContent() | |||||
| : document.getCppContent(), | |||||
| document.getCustomCodeList()); | |||||
| while (iter.next()) | while (iter.next()) | ||||
| { | { | ||||
| EditorHolder* ed = new EditorHolder (iter.codeDocument, iter.sectionName, iter.textBefore, iter.textAfter); | |||||
| EditorHolder* ed = new EditorHolder (iter.codeDocument, iter.textBefore, iter.textAfter); | |||||
| editors.add (ed); | editors.add (ed); | ||||
| addAndMakeVisible (ed); | addAndMakeVisible (ed); | ||||
| } | } | ||||
| @@ -683,11 +701,16 @@ private: | |||||
| Component::handleCommandMessage (commandId); | Component::handleCommandMessage (commandId); | ||||
| } | } | ||||
| private: | |||||
| OwnedArray <EditorHolder> editors; | OwnedArray <EditorHolder> editors; | ||||
| ComponentEditor& editor; | |||||
| ComponentDocument& document; | |||||
| bool isHeader; | |||||
| }; | }; | ||||
| Viewport* viewport; | |||||
| ComponentEditor& editor; | |||||
| Viewport viewport; | |||||
| TextButton switchFileButton; | |||||
| bool showingHeader; | |||||
| }; | }; | ||||
| //============================================================================== | //============================================================================== | ||||
| @@ -485,6 +485,14 @@ public: | |||||
| canvas.continueDrag (e); | canvas.continueDrag (e); | ||||
| showSizeGuides(); | showSizeGuides(); | ||||
| } | } | ||||
| Viewport* viewport = Component::findParentComponentOfClass ((Viewport*) 0); | |||||
| if (viewport != 0) | |||||
| { | |||||
| MouseEvent e2 (e.getEventRelativeTo (viewport)); | |||||
| viewport->autoScroll (e2.x, e2.y, 8, 16); | |||||
| } | |||||
| } | } | ||||
| void mouseUp (const MouseEvent& e) | void mouseUp (const MouseEvent& e) | ||||
| @@ -524,10 +532,10 @@ public: | |||||
| } | } | ||||
| } | } | ||||
| void findLassoItemsInArea (Array <SelectedItems::ItemType>& itemsFound, int x, int y, int width, int height) | |||||
| void findLassoItemsInArea (Array <SelectedItems::ItemType>& itemsFound, const Rectangle<int>& area) | |||||
| { | { | ||||
| canvas.getComponentHolder()->findLassoItemsInArea (itemsFound, Rectangle<int> (x, y, width, height) | |||||
| + relativePositionToOtherComponent (canvas.getComponentHolder(), Point<int>())); | |||||
| canvas.getComponentHolder() | |||||
| ->findLassoItemsInArea (itemsFound, area + relativePositionToOtherComponent (canvas.getComponentHolder(), Point<int>())); | |||||
| } | } | ||||
| SelectedItems& getLassoSelection() { return canvas.getSelection(); } | SelectedItems& getLassoSelection() { return canvas.getSelection(); } | ||||
| @@ -770,7 +778,7 @@ ComponentEditorCanvas::~ComponentEditorCanvas() | |||||
| { | { | ||||
| dragger = 0; | dragger = 0; | ||||
| getDocument().getRoot().removeListener (this); | getDocument().getRoot().removeListener (this); | ||||
| componentHolder->deleteAllChildren(); | |||||
| //deleteAndZero (componentHolder); | |||||
| deleteAllChildren(); | deleteAllChildren(); | ||||
| } | } | ||||
| @@ -1006,6 +1014,7 @@ ComponentEditorCanvas::ComponentHolder::ComponentHolder() | |||||
| ComponentEditorCanvas::ComponentHolder::~ComponentHolder() | ComponentEditorCanvas::ComponentHolder::~ComponentHolder() | ||||
| { | { | ||||
| deleteAllChildren(); | |||||
| } | } | ||||
| void ComponentEditorCanvas::ComponentHolder::updateComponents (ComponentDocument& doc, SelectedItems& selection) | void ComponentEditorCanvas::ComponentHolder::updateComponents (ComponentDocument& doc, SelectedItems& selection) | ||||
| @@ -1055,7 +1064,6 @@ Component* ComponentEditorCanvas::ComponentHolder::getComponentForState (Compone | |||||
| for (int i = getNumChildComponents(); --i >= 0;) | for (int i = getNumChildComponents(); --i >= 0;) | ||||
| { | { | ||||
| Component* const c = getChildComponent (i); | Component* const c = getChildComponent (i); | ||||
| if (doc.isStateForComponent (state, c)) | if (doc.isStateForComponent (state, c)) | ||||
| return c; | return c; | ||||
| } | } | ||||
| @@ -1068,7 +1076,6 @@ Component* ComponentEditorCanvas::ComponentHolder::findComponentWithID (const St | |||||
| for (int i = getNumChildComponents(); --i >= 0;) | for (int i = getNumChildComponents(); --i >= 0;) | ||||
| { | { | ||||
| Component* const c = getChildComponent(i); | Component* const c = getChildComponent(i); | ||||
| if (ComponentDocument::getJucerIDFor (c) == uid) | if (ComponentDocument::getJucerIDFor (c) == uid) | ||||
| return c; | return c; | ||||
| } | } | ||||
| @@ -191,14 +191,14 @@ void DrawableEditor::Canvas::mouseUp (const MouseEvent& e) | |||||
| } | } | ||||
| } | } | ||||
| void DrawableEditor::Canvas::findLassoItemsInArea (Array <int64>& itemsFound, int x, int y, int width, int height) | |||||
| void DrawableEditor::Canvas::findLassoItemsInArea (Array <int64>& itemsFound, const Rectangle<int>& area) | |||||
| { | { | ||||
| for (int i = getNumChildComponents(); --i >= 0;) | for (int i = getNumChildComponents(); --i >= 0;) | ||||
| { | { | ||||
| DrawableObjectComponent* d = dynamic_cast <DrawableObjectComponent*> (getChildComponent(i)); | DrawableObjectComponent* d = dynamic_cast <DrawableObjectComponent*> (getChildComponent(i)); | ||||
| if (d != 0) | if (d != 0) | ||||
| d->findLassoItemsInArea (itemsFound, Rectangle<int> (x, y, width, height)); | |||||
| d->findLassoItemsInArea (itemsFound, area); | |||||
| } | } | ||||
| } | } | ||||
| @@ -67,7 +67,7 @@ public: | |||||
| void childBoundsChanged (Component* child); | void childBoundsChanged (Component* child); | ||||
| void updateSize(); | void updateSize(); | ||||
| void findLassoItemsInArea (Array <int64>& itemsFound, int x, int y, int width, int height); | |||||
| void findLassoItemsInArea (Array <int64>& itemsFound, const Rectangle<int>& area); | |||||
| SelectedItemSet <int64>& getLassoSelection(); | SelectedItemSet <int64>& getLassoSelection(); | ||||
| private: | private: | ||||
| @@ -73,6 +73,9 @@ void JuceDemoPluginAudioProcessorEditor::resized() | |||||
| midiKeyboard->setBounds (4, getHeight() - keyboardHeight - 4, getWidth() - 8, keyboardHeight); | midiKeyboard->setBounds (4, getHeight() - keyboardHeight - 4, getWidth() - 8, keyboardHeight); | ||||
| resizer->setBounds (getWidth() - 16, getHeight() - 16, 16, 16); | resizer->setBounds (getWidth() - 16, getHeight() - 16, 16, 16); | ||||
| getProcessor()->lastUIWidth = getWidth(); | |||||
| getProcessor()->lastUIHeight = getHeight(); | |||||
| } | } | ||||
| //============================================================================== | //============================================================================== | ||||
| @@ -402,10 +402,9 @@ ComponentOverlayComponent* ComponentLayoutEditor::getOverlayCompFor (Component* | |||||
| return 0; | return 0; | ||||
| } | } | ||||
| void ComponentLayoutEditor::findLassoItemsInArea (Array <Component*>& results, | |||||
| int x, int y, int w, int h) | |||||
| void ComponentLayoutEditor::findLassoItemsInArea (Array <Component*>& results, const Rectangle<int>& area) | |||||
| { | { | ||||
| const Rectangle<int> lasso (x - subCompHolder->getX(), y - subCompHolder->getY(), w, h); | |||||
| const Rectangle<int> lasso (area - subCompHolder->getPosition()); | |||||
| for (int i = 0; i < subCompHolder->getNumChildComponents(); ++i) | for (int i = 0; i < subCompHolder->getNumChildComponents(); ++i) | ||||
| { | { | ||||
| @@ -60,8 +60,7 @@ public: | |||||
| ComponentLayout& getLayout() const throw() { return layout; } | ComponentLayout& getLayout() const throw() { return layout; } | ||||
| void findLassoItemsInArea (Array <Component*>& results, | |||||
| int x, int y, int w, int h); | |||||
| void findLassoItemsInArea (Array <Component*>& results, const Rectangle<int>& area); | |||||
| SelectedItemSet <Component*>& getLassoSelection(); | SelectedItemSet <Component*>& getLassoSelection(); | ||||
| @@ -260,11 +260,8 @@ void PaintRoutineEditor::mouseUp (const MouseEvent& e) | |||||
| } | } | ||||
| } | } | ||||
| void PaintRoutineEditor::findLassoItemsInArea (Array <PaintElement*>& results, | |||||
| int x, int y, int w, int h) | |||||
| void PaintRoutineEditor::findLassoItemsInArea (Array <PaintElement*>& results, const Rectangle<int>& lasso) | |||||
| { | { | ||||
| const Rectangle<int> lasso (x, y, w, h); | |||||
| for (int i = 0; i < getNumChildComponents(); ++i) | for (int i = 0; i < getNumChildComponents(); ++i) | ||||
| { | { | ||||
| PaintElement* const e = dynamic_cast <PaintElement*> (getChildComponent (i)); | PaintElement* const e = dynamic_cast <PaintElement*> (getChildComponent (i)); | ||||
| @@ -58,8 +58,7 @@ public: | |||||
| void mouseUp (const MouseEvent& e); | void mouseUp (const MouseEvent& e); | ||||
| void visibilityChanged(); | void visibilityChanged(); | ||||
| void findLassoItemsInArea (Array <PaintElement*>& results, | |||||
| int x, int y, int w, int h); | |||||
| void findLassoItemsInArea (Array <PaintElement*>& results, const Rectangle<int>& area); | |||||
| SelectedItemSet <PaintElement*>& getLassoSelection(); | SelectedItemSet <PaintElement*>& getLassoSelection(); | ||||
| @@ -34316,7 +34316,7 @@ XmlElement* AudioProcessor::getXmlFromBinary (const void* data, | |||||
| const int sizeInBytes) | const int sizeInBytes) | ||||
| { | { | ||||
| if (sizeInBytes > 8 | if (sizeInBytes > 8 | ||||
| && ByteOrder::littleEndianInt ((const char*) data) == magicXmlNumber) | |||||
| && ByteOrder::littleEndianInt (data) == magicXmlNumber) | |||||
| { | { | ||||
| const int stringLength = (int) ByteOrder::littleEndianInt (((const char*) data) + 4); | const int stringLength = (int) ByteOrder::littleEndianInt (((const char*) data) + 4); | ||||
| @@ -54338,7 +54338,7 @@ class TreeViewContentComponent : public Component, | |||||
| public TooltipClient | public TooltipClient | ||||
| { | { | ||||
| public: | public: | ||||
| TreeViewContentComponent (TreeView* const owner_) | |||||
| TreeViewContentComponent (TreeView& owner_) | |||||
| : owner (owner_), | : owner (owner_), | ||||
| buttonUnderMouse (0), | buttonUnderMouse (0), | ||||
| isDragging (false) | isDragging (false) | ||||
| @@ -54365,9 +54365,9 @@ public: | |||||
| // (if the open/close buttons are hidden, we'll treat clicks to the left of the item | // (if the open/close buttons are hidden, we'll treat clicks to the left of the item | ||||
| // as selection clicks) | // as selection clicks) | ||||
| if (e.x < pos.getX() && owner->openCloseButtonsVisible) | |||||
| if (e.x < pos.getX() && owner.openCloseButtonsVisible) | |||||
| { | { | ||||
| if (e.x >= pos.getX() - owner->getIndentSize()) | |||||
| if (e.x >= pos.getX() - owner.getIndentSize()) | |||||
| item->setOpen (! item->isOpen()); | item->setOpen (! item->isOpen()); | ||||
| // (clicks to the left of an open/close button are ignored) | // (clicks to the left of an open/close button are ignored) | ||||
| @@ -54375,7 +54375,7 @@ public: | |||||
| else | else | ||||
| { | { | ||||
| // mouse-down inside the body of the item.. | // mouse-down inside the body of the item.. | ||||
| if (! owner->isMultiSelectEnabled()) | |||||
| if (! owner.isMultiSelectEnabled()) | |||||
| item->setSelected (true, true); | item->setSelected (true, true); | ||||
| else if (item->isSelected()) | else if (item->isSelected()) | ||||
| needSelectionOnMouseUp = ! e.mods.isPopupMenu(); | needSelectionOnMouseUp = ! e.mods.isPopupMenu(); | ||||
| @@ -54408,7 +54408,7 @@ public: | |||||
| Rectangle<int> pos; | Rectangle<int> pos; | ||||
| TreeViewItem* const item = findItemAt (e.y, pos); | TreeViewItem* const item = findItemAt (e.y, pos); | ||||
| if (item != 0 && (e.x >= pos.getX() || ! owner->openCloseButtonsVisible)) | |||||
| if (item != 0 && (e.x >= pos.getX() || ! owner.openCloseButtonsVisible)) | |||||
| item->itemDoubleClicked (e.withNewPosition (e.getPosition() - pos.getPosition())); | item->itemDoubleClicked (e.withNewPosition (e.getPosition() - pos.getPosition())); | ||||
| } | } | ||||
| } | } | ||||
| @@ -54441,7 +54441,7 @@ public: | |||||
| dragImage->multiplyAllAlphas (0.6f); | dragImage->multiplyAllAlphas (0.6f); | ||||
| Point<int> imageOffset (pos.getX() - e.x, pos.getY() - e.y); | Point<int> imageOffset (pos.getX() - e.x, pos.getY() - e.y); | ||||
| dragContainer->startDragging (dragDescription, owner, dragImage, true, &imageOffset); | |||||
| dragContainer->startDragging (dragDescription, &owner, dragImage, true, &imageOffset); | |||||
| } | } | ||||
| else | else | ||||
| { | { | ||||
| @@ -54464,25 +54464,37 @@ public: | |||||
| updateButtonUnderMouse (e); | updateButtonUnderMouse (e); | ||||
| } | } | ||||
| void paint (Graphics& g); | |||||
| TreeViewItem* findItemAt (int y, Rectangle<int>& itemPosition) const; | |||||
| void paint (Graphics& g) | |||||
| { | |||||
| if (owner.rootItem != 0) | |||||
| { | |||||
| owner.handleAsyncUpdate(); | |||||
| static bool isMouseDraggingInChildCompOf (Component* const comp) | |||||
| if (! owner.rootItemVisible) | |||||
| g.setOrigin (0, -owner.rootItem->itemHeight); | |||||
| owner.rootItem->paintRecursively (g, getWidth()); | |||||
| } | |||||
| } | |||||
| TreeViewItem* findItemAt (int y, Rectangle<int>& itemPosition) const | |||||
| { | { | ||||
| for (int i = Desktop::getInstance().getNumMouseSources(); --i >= 0;) | |||||
| if (owner.rootItem != 0) | |||||
| { | { | ||||
| MouseInputSource* source = Desktop::getInstance().getMouseSource(i); | |||||
| owner.handleAsyncUpdate(); | |||||
| if (source->isDragging()) | |||||
| { | |||||
| Component* const underMouse = source->getComponentUnderMouse(); | |||||
| if (! owner.rootItemVisible) | |||||
| y += owner.rootItem->itemHeight; | |||||
| if (underMouse != 0 && (comp == underMouse || comp->isParentOf (underMouse))) | |||||
| return true; | |||||
| } | |||||
| TreeViewItem* const ti = owner.rootItem->findItemRecursively (y); | |||||
| if (ti != 0) | |||||
| itemPosition = ti->getItemPosition (false); | |||||
| return ti; | |||||
| } | } | ||||
| return false; | |||||
| return 0; | |||||
| } | } | ||||
| void updateComponents() | void updateComponents() | ||||
| @@ -54491,8 +54503,8 @@ public: | |||||
| const int visibleBottom = visibleTop + getParentHeight(); | const int visibleBottom = visibleTop + getParentHeight(); | ||||
| BigInteger itemsToKeep; | BigInteger itemsToKeep; | ||||
| TreeViewItem* item = owner->rootItem; | |||||
| int y = (item != 0 && !owner->rootItemVisible) ? -item->itemHeight : 0; | |||||
| TreeViewItem* item = owner.rootItem; | |||||
| int y = (item != 0 && ! owner.rootItemVisible) ? -item->itemHeight : 0; | |||||
| while (item != 0 && y < visibleBottom) | while (item != 0 && y < visibleBottom) | ||||
| { | { | ||||
| @@ -54566,12 +54578,12 @@ public: | |||||
| { | { | ||||
| TreeViewItem* newItem = 0; | TreeViewItem* newItem = 0; | ||||
| if (owner->openCloseButtonsVisible) | |||||
| if (owner.openCloseButtonsVisible) | |||||
| { | { | ||||
| Rectangle<int> pos; | Rectangle<int> pos; | ||||
| TreeViewItem* item = findItemAt (e.y, pos); | TreeViewItem* item = findItemAt (e.y, pos); | ||||
| if (item != 0 && e.x < pos.getX() && e.x >= pos.getX() - owner->getIndentSize()) | |||||
| if (item != 0 && e.x < pos.getX() && e.x >= pos.getX() - owner.getIndentSize()) | |||||
| { | { | ||||
| newItem = item; | newItem = item; | ||||
| @@ -54598,14 +54610,14 @@ public: | |||||
| } | } | ||||
| } | } | ||||
| bool isMouseOverButton (TreeViewItem* item) const throw() | |||||
| bool isMouseOverButton (TreeViewItem* const item) const throw() | |||||
| { | { | ||||
| return item == buttonUnderMouse; | return item == buttonUnderMouse; | ||||
| } | } | ||||
| void resized() | void resized() | ||||
| { | { | ||||
| owner->itemsChanged(); | |||||
| owner.itemsChanged(); | |||||
| } | } | ||||
| const String getTooltip() | const String getTooltip() | ||||
| @@ -54616,30 +54628,26 @@ public: | |||||
| if (item != 0) | if (item != 0) | ||||
| return item->getTooltip(); | return item->getTooltip(); | ||||
| return owner->getTooltip(); | |||||
| return owner.getTooltip(); | |||||
| } | } | ||||
| juce_UseDebuggingNewOperator | juce_UseDebuggingNewOperator | ||||
| private: | private: | ||||
| TreeView* const owner; | |||||
| TreeView& owner; | |||||
| Array <TreeViewItem*> rowComponentItems; | Array <TreeViewItem*> rowComponentItems; | ||||
| Array <int> rowComponentIds; | Array <int> rowComponentIds; | ||||
| Array <Component*> rowComponents; | Array <Component*> rowComponents; | ||||
| TreeViewItem* buttonUnderMouse; | TreeViewItem* buttonUnderMouse; | ||||
| bool isDragging, needSelectionOnMouseUp; | bool isDragging, needSelectionOnMouseUp; | ||||
| TreeViewContentComponent (const TreeViewContentComponent&); | |||||
| TreeViewContentComponent& operator= (const TreeViewContentComponent&); | |||||
| void selectBasedOnModifiers (TreeViewItem* const item, const ModifierKeys& modifiers) | void selectBasedOnModifiers (TreeViewItem* const item, const ModifierKeys& modifiers) | ||||
| { | { | ||||
| TreeViewItem* firstSelected = 0; | TreeViewItem* firstSelected = 0; | ||||
| if (modifiers.isShiftDown() && ((firstSelected = owner->getSelectedItem (0)) != 0)) | |||||
| if (modifiers.isShiftDown() && ((firstSelected = owner.getSelectedItem (0)) != 0)) | |||||
| { | { | ||||
| TreeViewItem* const lastSelected = owner->getSelectedItem (owner->getNumSelectedItems() - 1); | |||||
| TreeViewItem* const lastSelected = owner.getSelectedItem (owner.getNumSelectedItems() - 1); | |||||
| jassert (lastSelected != 0); | jassert (lastSelected != 0); | ||||
| int rowStart = firstSelected->getRowNumberInTree(); | int rowStart = firstSelected->getRowNumberInTree(); | ||||
| @@ -54654,13 +54662,12 @@ private: | |||||
| swapVariables (ourRow, otherEnd); | swapVariables (ourRow, otherEnd); | ||||
| for (int i = ourRow; i <= otherEnd; ++i) | for (int i = ourRow; i <= otherEnd; ++i) | ||||
| owner->getItemOnRow (i)->setSelected (true, false); | |||||
| owner.getItemOnRow (i)->setSelected (true, false); | |||||
| } | } | ||||
| else | else | ||||
| { | { | ||||
| const bool cmd = modifiers.isCommandDown(); | |||||
| item->setSelected ((! cmd) || (! item->isSelected()), ! cmd); | |||||
| const bool cmd = modifiers.isCommandDown(); | |||||
| item->setSelected ((! cmd) || ! item->isSelected(), ! cmd); | |||||
| } | } | ||||
| } | } | ||||
| @@ -54672,31 +54679,61 @@ private: | |||||
| return false; | return false; | ||||
| } | } | ||||
| static bool isMouseDraggingInChildCompOf (Component* const comp) | |||||
| { | |||||
| for (int i = Desktop::getInstance().getNumMouseSources(); --i >= 0;) | |||||
| { | |||||
| MouseInputSource* const source = Desktop::getInstance().getMouseSource(i); | |||||
| if (source->isDragging()) | |||||
| { | |||||
| Component* const underMouse = source->getComponentUnderMouse(); | |||||
| if (underMouse != 0 && (comp == underMouse || comp->isParentOf (underMouse))) | |||||
| return true; | |||||
| } | |||||
| } | |||||
| return false; | |||||
| } | |||||
| TreeViewContentComponent (const TreeViewContentComponent&); | |||||
| TreeViewContentComponent& operator= (const TreeViewContentComponent&); | |||||
| }; | }; | ||||
| class TreeView::TreeViewport : public Viewport | class TreeView::TreeViewport : public Viewport | ||||
| { | { | ||||
| public: | public: | ||||
| TreeViewport() throw() {} | |||||
| ~TreeViewport() throw() {} | |||||
| TreeViewport() throw() : lastX (-1) {} | |||||
| ~TreeViewport() throw() {} | |||||
| void updateComponents() | |||||
| void updateComponents (const bool triggerResize = false) | |||||
| { | { | ||||
| TreeViewContentComponent* const tvc = static_cast <TreeViewContentComponent*> (getViewedComponent()); | TreeViewContentComponent* const tvc = static_cast <TreeViewContentComponent*> (getViewedComponent()); | ||||
| if (tvc != 0) | if (tvc != 0) | ||||
| tvc->updateComponents(); | |||||
| { | |||||
| if (triggerResize) | |||||
| tvc->resized(); | |||||
| else | |||||
| tvc->updateComponents(); | |||||
| } | |||||
| repaint(); | repaint(); | ||||
| } | } | ||||
| void visibleAreaChanged (int, int, int, int) | |||||
| void visibleAreaChanged (int x, int, int, int) | |||||
| { | { | ||||
| updateComponents(); | |||||
| const bool hasScrolledSideways = (x != lastX); | |||||
| lastX = x; | |||||
| updateComponents (hasScrolledSideways); | |||||
| } | } | ||||
| juce_UseDebuggingNewOperator | juce_UseDebuggingNewOperator | ||||
| private: | private: | ||||
| int lastX; | |||||
| TreeViewport (const TreeViewport&); | TreeViewport (const TreeViewport&); | ||||
| TreeViewport& operator= (const TreeViewport&); | TreeViewport& operator= (const TreeViewport&); | ||||
| }; | }; | ||||
| @@ -54714,7 +54751,7 @@ TreeView::TreeView (const String& componentName) | |||||
| openCloseButtonsVisible (true) | openCloseButtonsVisible (true) | ||||
| { | { | ||||
| addAndMakeVisible (viewport = new TreeViewport()); | addAndMakeVisible (viewport = new TreeViewport()); | ||||
| viewport->setViewedComponent (new TreeViewContentComponent (this)); | |||||
| viewport->setViewedComponent (new TreeViewContentComponent (*this)); | |||||
| viewport->setWantsKeyboardFocus (false); | viewport->setWantsKeyboardFocus (false); | ||||
| setWantsKeyboardFocus (true); | setWantsKeyboardFocus (true); | ||||
| } | } | ||||
| @@ -55340,39 +55377,6 @@ void TreeView::itemDropped (const String& sourceDescription, Component* sourceCo | |||||
| handleDrop (StringArray(), sourceDescription, sourceComponent, x, y); | handleDrop (StringArray(), sourceDescription, sourceComponent, x, y); | ||||
| } | } | ||||
| void TreeViewContentComponent::paint (Graphics& g) | |||||
| { | |||||
| if (owner->rootItem != 0) | |||||
| { | |||||
| owner->handleAsyncUpdate(); | |||||
| if (! owner->rootItemVisible) | |||||
| g.setOrigin (0, -owner->rootItem->itemHeight); | |||||
| owner->rootItem->paintRecursively (g, getWidth()); | |||||
| } | |||||
| } | |||||
| TreeViewItem* TreeViewContentComponent::findItemAt (int y, Rectangle<int>& itemPosition) const | |||||
| { | |||||
| if (owner->rootItem != 0) | |||||
| { | |||||
| owner->handleAsyncUpdate(); | |||||
| if (! owner->rootItemVisible) | |||||
| y += owner->rootItem->itemHeight; | |||||
| TreeViewItem* const ti = owner->rootItem->findItemRecursively (y); | |||||
| if (ti != 0) | |||||
| itemPosition = ti->getItemPosition (false); | |||||
| return ti; | |||||
| } | |||||
| return 0; | |||||
| } | |||||
| enum TreeViewOpenness | enum TreeViewOpenness | ||||
| { | { | ||||
| opennessDefault = 0, | opennessDefault = 0, | ||||
| @@ -55593,7 +55597,6 @@ void TreeViewItem::itemDropped (const String& /*sourceDescription*/, Component* | |||||
| const Rectangle<int> TreeViewItem::getItemPosition (const bool relativeToTreeViewTopLeft) const throw() | const Rectangle<int> TreeViewItem::getItemPosition (const bool relativeToTreeViewTopLeft) const throw() | ||||
| { | { | ||||
| const int indentX = getIndentX(); | const int indentX = getIndentX(); | ||||
| int width = itemWidth; | int width = itemWidth; | ||||
| if (ownerView != 0 && width < 0) | if (ownerView != 0 && width < 0) | ||||
| @@ -55602,8 +55605,7 @@ const Rectangle<int> TreeViewItem::getItemPosition (const bool relativeToTreeVie | |||||
| Rectangle<int> r (indentX, y, jmax (0, width), totalHeight); | Rectangle<int> r (indentX, y, jmax (0, width), totalHeight); | ||||
| if (relativeToTreeViewTopLeft) | if (relativeToTreeViewTopLeft) | ||||
| r.setPosition (r.getX() - ownerView->viewport->getViewPositionX(), | |||||
| r.getY() - ownerView->viewport->getViewPositionY()); | |||||
| r -= ownerView->viewport->getViewPosition(); | |||||
| return r; | return r; | ||||
| } | } | ||||
| @@ -56536,6 +56538,11 @@ const File FileBrowserComponent::getHighlightedFile() const throw() | |||||
| return fileListComponent->getSelectedFile (0); | return fileListComponent->getSelectedFile (0); | ||||
| } | } | ||||
| void FileBrowserComponent::deselectAllFiles() | |||||
| { | |||||
| fileListComponent->deselectAllFiles(); | |||||
| } | |||||
| bool FileBrowserComponent::isFileSuitable (const File& file) const | bool FileBrowserComponent::isFileSuitable (const File& file) const | ||||
| { | { | ||||
| return (flags & canSelectFiles) != 0 ? (fileFilter == 0 || fileFilter->isFileSuitable (file)) | return (flags & canSelectFiles) != 0 ? (fileFilter == 0 || fileFilter->isFileSuitable (file)) | ||||
| @@ -57215,6 +57222,11 @@ const File FileListComponent::getSelectedFile (int index) const | |||||
| return fileList.getFile (getSelectedRow (index)); | return fileList.getFile (getSelectedRow (index)); | ||||
| } | } | ||||
| void FileListComponent::deselectAllFiles() | |||||
| { | |||||
| deselectAllRows(); | |||||
| } | |||||
| void FileListComponent::scrollToTop() | void FileListComponent::scrollToTop() | ||||
| { | { | ||||
| getVerticalScrollBar()->setCurrentRangeStart (0); | getVerticalScrollBar()->setCurrentRangeStart (0); | ||||
| @@ -58097,10 +58109,13 @@ const File FileTreeComponent::getSelectedFile (const int index) const | |||||
| { | { | ||||
| const FileListTreeItem* const item = dynamic_cast <const FileListTreeItem*> (getSelectedItem (index)); | const FileListTreeItem* const item = dynamic_cast <const FileListTreeItem*> (getSelectedItem (index)); | ||||
| if (item != 0) | |||||
| return item->file; | |||||
| return item != 0 ? item->file | |||||
| : File::nonexistent; | |||||
| } | |||||
| return File::nonexistent; | |||||
| void FileTreeComponent::deselectAllFiles() | |||||
| { | |||||
| clearSelectedItems(); | |||||
| } | } | ||||
| void FileTreeComponent::scrollToTop() | void FileTreeComponent::scrollToTop() | ||||
| @@ -62786,10 +62801,6 @@ BEGIN_JUCE_NAMESPACE | |||||
| Viewport::Viewport (const String& componentName) | Viewport::Viewport (const String& componentName) | ||||
| : Component (componentName), | : Component (componentName), | ||||
| contentComp (0), | contentComp (0), | ||||
| lastVX (0), | |||||
| lastVY (0), | |||||
| lastVW (0), | |||||
| lastVH (0), | |||||
| scrollBarThickness (0), | scrollBarThickness (0), | ||||
| singleStepX (16), | singleStepX (16), | ||||
| singleStepY (16), | singleStepY (16), | ||||
| @@ -62855,16 +62866,14 @@ int Viewport::getMaximumVisibleHeight() const throw() | |||||
| return jmax (0, getHeight() - (horizontalScrollBar->isVisible() ? getScrollBarThickness() : 0)); | return jmax (0, getHeight() - (horizontalScrollBar->isVisible() ? getScrollBarThickness() : 0)); | ||||
| } | } | ||||
| void Viewport::setViewPosition (const int xPixelsOffset, | |||||
| const int yPixelsOffset) | |||||
| void Viewport::setViewPosition (const int xPixelsOffset, const int yPixelsOffset) | |||||
| { | { | ||||
| if (contentComp != 0) | if (contentComp != 0) | ||||
| contentComp->setTopLeftPosition (-xPixelsOffset, | contentComp->setTopLeftPosition (-xPixelsOffset, | ||||
| -yPixelsOffset); | -yPixelsOffset); | ||||
| } | } | ||||
| void Viewport::setViewPositionProportionately (const double x, | |||||
| const double y) | |||||
| void Viewport::setViewPositionProportionately (const double x, const double y) | |||||
| { | { | ||||
| if (contentComp != 0) | if (contentComp != 0) | ||||
| setViewPosition (jmax (0, roundToInt (x * (contentComp->getWidth() - getWidth()))), | setViewPosition (jmax (0, roundToInt (x * (contentComp->getWidth() - getWidth()))), | ||||
| @@ -62877,25 +62886,31 @@ bool Viewport::autoScroll (int mouseX, int mouseY, int activeBorderThickness, in | |||||
| { | { | ||||
| int dx = 0, dy = 0; | int dx = 0, dy = 0; | ||||
| if (mouseX < activeBorderThickness) | |||||
| dx = activeBorderThickness - mouseX; | |||||
| else if (mouseX >= contentHolder->getWidth() - activeBorderThickness) | |||||
| dx = (contentHolder->getWidth() - activeBorderThickness) - mouseX; | |||||
| if (horizontalScrollBar->isVisible()) | |||||
| { | |||||
| if (mouseX < activeBorderThickness) | |||||
| dx = activeBorderThickness - mouseX; | |||||
| else if (mouseX >= contentHolder->getWidth() - activeBorderThickness) | |||||
| dx = (contentHolder->getWidth() - activeBorderThickness) - mouseX; | |||||
| if (dx < 0) | |||||
| dx = jmax (dx, -maximumSpeed, contentHolder->getWidth() - contentComp->getRight()); | |||||
| else | |||||
| dx = jmin (dx, maximumSpeed, -contentComp->getX()); | |||||
| if (dx < 0) | |||||
| dx = jmax (dx, -maximumSpeed, contentHolder->getWidth() - contentComp->getRight()); | |||||
| else | |||||
| dx = jmin (dx, maximumSpeed, -contentComp->getX()); | |||||
| } | |||||
| if (mouseY < activeBorderThickness) | |||||
| dy = activeBorderThickness - mouseY; | |||||
| else if (mouseY >= contentHolder->getHeight() - activeBorderThickness) | |||||
| dy = (contentHolder->getHeight() - activeBorderThickness) - mouseY; | |||||
| if (verticalScrollBar->isVisible()) | |||||
| { | |||||
| if (mouseY < activeBorderThickness) | |||||
| dy = activeBorderThickness - mouseY; | |||||
| else if (mouseY >= contentHolder->getHeight() - activeBorderThickness) | |||||
| dy = (contentHolder->getHeight() - activeBorderThickness) - mouseY; | |||||
| if (dy < 0) | |||||
| dy = jmax (dy, -maximumSpeed, contentHolder->getHeight() - contentComp->getBottom()); | |||||
| else | |||||
| dy = jmin (dy, maximumSpeed, -contentComp->getY()); | |||||
| if (dy < 0) | |||||
| dy = jmax (dy, -maximumSpeed, contentHolder->getHeight() - contentComp->getBottom()); | |||||
| else | |||||
| dy = jmin (dy, maximumSpeed, -contentComp->getY()); | |||||
| } | |||||
| if (dx != 0 || dy != 0) | if (dx != 0 || dy != 0) | ||||
| { | { | ||||
| @@ -62923,10 +62938,10 @@ void Viewport::updateVisibleRegion() | |||||
| { | { | ||||
| if (contentComp != 0) | if (contentComp != 0) | ||||
| { | { | ||||
| const int newVX = -contentComp->getX(); | |||||
| const int newVY = -contentComp->getY(); | |||||
| Rectangle<int> newViewPos; | |||||
| newViewPos.setPosition (-contentComp->getPosition()); | |||||
| if (newVX == 0 && newVY == 0 | |||||
| if (newViewPos.getX() == 0 && newViewPos.getY() == 0 | |||||
| && contentComp->getWidth() <= getWidth() | && contentComp->getWidth() <= getWidth() | ||||
| && contentComp->getHeight() <= getHeight()) | && contentComp->getHeight() <= getHeight()) | ||||
| { | { | ||||
| @@ -62935,14 +62950,14 @@ void Viewport::updateVisibleRegion() | |||||
| } | } | ||||
| horizontalScrollBar->setRangeLimits (0.0, contentComp->getWidth()); | horizontalScrollBar->setRangeLimits (0.0, contentComp->getWidth()); | ||||
| horizontalScrollBar->setCurrentRange (newVX, getMaximumVisibleWidth()); | |||||
| horizontalScrollBar->setCurrentRange (newViewPos.getX(), getMaximumVisibleWidth()); | |||||
| horizontalScrollBar->setSingleStepSize (singleStepX); | horizontalScrollBar->setSingleStepSize (singleStepX); | ||||
| if (! (contentComp->getWidth() > 0 && showHScrollbar && getHeight() > getScrollBarThickness())) | if (! (contentComp->getWidth() > 0 && showHScrollbar && getHeight() > getScrollBarThickness())) | ||||
| horizontalScrollBar->setVisible (! horizontalScrollBar->autoHides()); | horizontalScrollBar->setVisible (! horizontalScrollBar->autoHides()); | ||||
| verticalScrollBar->setRangeLimits (0.0, contentComp->getHeight()); | verticalScrollBar->setRangeLimits (0.0, contentComp->getHeight()); | ||||
| verticalScrollBar->setCurrentRange (newVY, getMaximumVisibleHeight()); | |||||
| verticalScrollBar->setCurrentRange (newViewPos.getY(), getMaximumVisibleHeight()); | |||||
| verticalScrollBar->setSingleStepSize (singleStepY); | verticalScrollBar->setSingleStepSize (singleStepY); | ||||
| if (! (contentComp->getHeight() > 0 && showVScrollbar && getWidth() > getScrollBarThickness())) | if (! (contentComp->getHeight() > 0 && showVScrollbar && getWidth() > getScrollBarThickness())) | ||||
| @@ -62950,8 +62965,8 @@ void Viewport::updateVisibleRegion() | |||||
| if (verticalScrollBar->isVisible()) | if (verticalScrollBar->isVisible()) | ||||
| { | { | ||||
| horizontalScrollBar->setCurrentRange (newVX, getMaximumVisibleWidth()); | |||||
| verticalScrollBar->setCurrentRange (newVY, getMaximumVisibleHeight()); | |||||
| horizontalScrollBar->setCurrentRange (newViewPos.getX(), getMaximumVisibleWidth()); | |||||
| verticalScrollBar->setCurrentRange (newViewPos.getY(), getMaximumVisibleHeight()); | |||||
| verticalScrollBar | verticalScrollBar | ||||
| ->setBounds (getMaximumVisibleWidth(), 0, | ->setBounds (getMaximumVisibleWidth(), 0, | ||||
| @@ -62960,7 +62975,7 @@ void Viewport::updateVisibleRegion() | |||||
| if (horizontalScrollBar->isVisible()) | if (horizontalScrollBar->isVisible()) | ||||
| { | { | ||||
| horizontalScrollBar->setCurrentRange (newVX, getMaximumVisibleWidth()); | |||||
| horizontalScrollBar->setCurrentRange (newViewPos.getX(), getMaximumVisibleWidth()); | |||||
| horizontalScrollBar | horizontalScrollBar | ||||
| ->setBounds (0, getMaximumVisibleHeight(), | ->setBounds (0, getMaximumVisibleHeight(), | ||||
| @@ -62970,20 +62985,13 @@ void Viewport::updateVisibleRegion() | |||||
| contentHolder->setSize (getMaximumVisibleWidth(), | contentHolder->setSize (getMaximumVisibleWidth(), | ||||
| getMaximumVisibleHeight()); | getMaximumVisibleHeight()); | ||||
| const int newVW = jmin (contentComp->getRight(), getMaximumVisibleWidth()); | |||||
| const int newVH = jmin (contentComp->getBottom(), getMaximumVisibleHeight()); | |||||
| newViewPos.setSize (jmin (contentComp->getRight(), getMaximumVisibleWidth()), | |||||
| jmin (contentComp->getBottom(), getMaximumVisibleHeight())); | |||||
| if (newVX != lastVX | |||||
| || newVY != lastVY | |||||
| || newVW != lastVW | |||||
| || newVH != lastVH) | |||||
| if (lastViewPos != newViewPos) | |||||
| { | { | ||||
| lastVX = newVX; | |||||
| lastVY = newVY; | |||||
| lastVW = newVW; | |||||
| lastVH = newVH; | |||||
| visibleAreaChanged (newVX, newVY, newVW, newVH); | |||||
| lastViewPos = newViewPos; | |||||
| visibleAreaChanged (newViewPos.getX(), newViewPos.getY(), newViewPos.getWidth(), newViewPos.getHeight()); | |||||
| } | } | ||||
| horizontalScrollBar->handleUpdateNowIfNeeded(); | horizontalScrollBar->handleUpdateNowIfNeeded(); | ||||
| @@ -62996,8 +63004,7 @@ void Viewport::updateVisibleRegion() | |||||
| } | } | ||||
| } | } | ||||
| void Viewport::setSingleStepSizes (const int stepX, | |||||
| const int stepY) | |||||
| void Viewport::setSingleStepSizes (const int stepX, const int stepY) | |||||
| { | { | ||||
| singleStepX = stepX; | singleStepX = stepX; | ||||
| singleStepY = stepY; | singleStepY = stepY; | ||||
| @@ -247175,27 +247182,32 @@ public: | |||||
| { | { | ||||
| const KeyPress& kp = keyPresses.getReference(0); | const KeyPress& kp = keyPresses.getReference(0); | ||||
| juce_wchar key = kp.getTextCharacter(); | |||||
| if (kp.getKeyCode() == KeyPress::backspaceKey) | |||||
| key = NSBackspaceCharacter; | |||||
| else if (kp.getKeyCode() == KeyPress::deleteKey) | |||||
| key = NSDeleteCharacter; | |||||
| else if (key == 0) | |||||
| key = (juce_wchar) kp.getKeyCode(); | |||||
| unsigned int mods = 0; | |||||
| if (kp.getModifiers().isShiftDown()) | |||||
| mods |= NSShiftKeyMask; | |||||
| if (kp.getModifiers().isCtrlDown()) | |||||
| mods |= NSControlKeyMask; | |||||
| if (kp.getModifiers().isAltDown()) | |||||
| mods |= NSAlternateKeyMask; | |||||
| if (kp.getModifiers().isCommandDown()) | |||||
| mods |= NSCommandKeyMask; | |||||
| [item setKeyEquivalent: juceStringToNS (String::charToString (key))]; | |||||
| [item setKeyEquivalentModifierMask: mods]; | |||||
| if (kp.getKeyCode() != KeyPress::backspaceKey | |||||
| && kp.getKeyCode() != KeyPress::deleteKey) // (adding these is annoying because it flashes the menu bar | |||||
| // every time you press the key while editing text) | |||||
| { | |||||
| juce_wchar key = kp.getTextCharacter(); | |||||
| if (kp.getKeyCode() == KeyPress::backspaceKey) | |||||
| key = NSBackspaceCharacter; | |||||
| else if (kp.getKeyCode() == KeyPress::deleteKey) | |||||
| key = NSDeleteCharacter; | |||||
| else if (key == 0) | |||||
| key = (juce_wchar) kp.getKeyCode(); | |||||
| unsigned int mods = 0; | |||||
| if (kp.getModifiers().isShiftDown()) | |||||
| mods |= NSShiftKeyMask; | |||||
| if (kp.getModifiers().isCtrlDown()) | |||||
| mods |= NSControlKeyMask; | |||||
| if (kp.getModifiers().isAltDown()) | |||||
| mods |= NSAlternateKeyMask; | |||||
| if (kp.getModifiers().isCommandDown()) | |||||
| mods |= NSCommandKeyMask; | |||||
| [item setKeyEquivalent: juceStringToNS (String::charToString (key))]; | |||||
| [item setKeyEquivalentModifierMask: mods]; | |||||
| } | |||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| @@ -5035,7 +5035,7 @@ public: | |||||
| if (this != &other) | if (this != &other) | ||||
| { | { | ||||
| ReferenceCountedArray<ObjectClass, TypeOfCriticalSectionToUse> otherCopy (other); | ReferenceCountedArray<ObjectClass, TypeOfCriticalSectionToUse> otherCopy (other); | ||||
| swapWithArray (other); | |||||
| swapWithArray (otherCopy); | |||||
| } | } | ||||
| return *this; | return *this; | ||||
| @@ -10363,11 +10363,23 @@ public: | |||||
| return Rectangle (x + deltaPosition.getX(), y + deltaPosition.getY(), w, h); | return Rectangle (x + deltaPosition.getX(), y + deltaPosition.getY(), w, h); | ||||
| } | } | ||||
| Rectangle& operator+= (const Point<ValueType>& deltaPosition) throw() | |||||
| { | |||||
| x += deltaPosition.getX(); y += deltaPosition.getY(); | |||||
| return *this; | |||||
| } | |||||
| const Rectangle operator- (const Point<ValueType>& deltaPosition) const throw() | const Rectangle operator- (const Point<ValueType>& deltaPosition) const throw() | ||||
| { | { | ||||
| return Rectangle (x - deltaPosition.getX(), y - deltaPosition.getY(), w, h); | return Rectangle (x - deltaPosition.getX(), y - deltaPosition.getY(), w, h); | ||||
| } | } | ||||
| Rectangle& operator-= (const Point<ValueType>& deltaPosition) throw() | |||||
| { | |||||
| x -= deltaPosition.getX(); y -= deltaPosition.getY(); | |||||
| return *this; | |||||
| } | |||||
| void expand (const ValueType deltaX, | void expand (const ValueType deltaX, | ||||
| const ValueType deltaY) throw() | const ValueType deltaY) throw() | ||||
| { | { | ||||
| @@ -16449,13 +16461,15 @@ public: | |||||
| bool autoScroll (int mouseX, int mouseY, int distanceFromEdge, int maximumSpeed); | bool autoScroll (int mouseX, int mouseY, int distanceFromEdge, int maximumSpeed); | ||||
| int getViewPositionX() const throw() { return lastVX; } | |||||
| const Point<int> getViewPosition() const throw() { return lastViewPos.getPosition(); } | |||||
| int getViewPositionX() const throw() { return lastViewPos.getX(); } | |||||
| int getViewPositionY() const throw() { return lastVY; } | |||||
| int getViewPositionY() const throw() { return lastViewPos.getY(); } | |||||
| int getViewWidth() const throw() { return lastVW; } | |||||
| int getViewWidth() const throw() { return lastViewPos.getWidth(); } | |||||
| int getViewHeight() const throw() { return lastVH; } | |||||
| int getViewHeight() const throw() { return lastViewPos.getHeight(); } | |||||
| int getMaximumVisibleWidth() const throw(); | int getMaximumVisibleWidth() const throw(); | ||||
| @@ -16494,7 +16508,7 @@ public: | |||||
| private: | private: | ||||
| Component::SafePointer<Component> contentComp; | Component::SafePointer<Component> contentComp; | ||||
| int lastVX, lastVY, lastVW, lastVH; | |||||
| Rectangle<int> lastViewPos; | |||||
| int scrollBarThickness; | int scrollBarThickness; | ||||
| int singleStepX, singleStepY; | int singleStepX, singleStepY; | ||||
| bool showHScrollbar, showVScrollbar; | bool showHScrollbar, showVScrollbar; | ||||
| @@ -16503,6 +16517,7 @@ private: | |||||
| ScrollBar* horizontalScrollBar; | ScrollBar* horizontalScrollBar; | ||||
| void updateVisibleRegion(); | void updateVisibleRegion(); | ||||
| Viewport (const Viewport&); | Viewport (const Viewport&); | ||||
| Viewport& operator= (const Viewport&); | Viewport& operator= (const Viewport&); | ||||
| }; | }; | ||||
| @@ -22620,6 +22635,8 @@ public: | |||||
| virtual const File getSelectedFile (int index) const = 0; | virtual const File getSelectedFile (int index) const = 0; | ||||
| virtual void deselectAllFiles() = 0; | |||||
| virtual void scrollToTop() = 0; | virtual void scrollToTop() = 0; | ||||
| void addListener (FileBrowserListener* listener); | void addListener (FileBrowserListener* listener); | ||||
| @@ -22721,6 +22738,8 @@ public: | |||||
| const File getSelectedFile (int index) const throw(); | const File getSelectedFile (int index) const throw(); | ||||
| void deselectAllFiles(); | |||||
| bool currentFileIsValid() const; | bool currentFileIsValid() const; | ||||
| const File getHighlightedFile() const throw(); | const File getHighlightedFile() const throw(); | ||||
| @@ -23530,6 +23549,8 @@ public: | |||||
| const File getSelectedFile (int index = 0) const; | const File getSelectedFile (int index = 0) const; | ||||
| void deselectAllFiles(); | |||||
| void scrollToTop(); | void scrollToTop(); | ||||
| void changeListenerCallback (void*); | void changeListenerCallback (void*); | ||||
| @@ -23740,6 +23761,8 @@ public: | |||||
| const File getSelectedFile (int index = 0) const; | const File getSelectedFile (int index = 0) const; | ||||
| void deselectAllFiles(); | |||||
| void scrollToTop(); | void scrollToTop(); | ||||
| void setDragAndDropDescription (const String& description); | void setDragAndDropDescription (const String& description); | ||||
| @@ -25890,7 +25913,7 @@ public: | |||||
| virtual ~LassoSource() {} | virtual ~LassoSource() {} | ||||
| virtual void findLassoItemsInArea (Array <SelectableItemType>& itemsFound, | virtual void findLassoItemsInArea (Array <SelectableItemType>& itemsFound, | ||||
| int x, int y, int width, int height) = 0; | |||||
| const Rectangle<int>& area) = 0; | |||||
| virtual SelectedItemSet <SelectableItemType>& getLassoSelection() = 0; | virtual SelectedItemSet <SelectableItemType>& getLassoSelection() = 0; | ||||
| }; | }; | ||||
| @@ -25923,17 +25946,18 @@ public: | |||||
| originalSelection = lassoSource->getLassoSelection().getItemArray(); | originalSelection = lassoSource->getLassoSelection().getItemArray(); | ||||
| setSize (0, 0); | setSize (0, 0); | ||||
| dragStartPos = e.getMouseDownPosition(); | |||||
| } | } | ||||
| void dragLasso (const MouseEvent& e) | void dragLasso (const MouseEvent& e) | ||||
| { | { | ||||
| if (source != 0) | if (source != 0) | ||||
| { | { | ||||
| setBounds (Rectangle<int> (e.getMouseDownPosition(), e.getPosition())); | |||||
| setBounds (Rectangle<int> (dragStartPos, e.getPosition())); | |||||
| setVisible (true); | setVisible (true); | ||||
| Array <SelectableItemType> itemsInLasso; | Array <SelectableItemType> itemsInLasso; | ||||
| source->findLassoItemsInArea (itemsInLasso, getX(), getY(), getWidth(), getHeight()); | |||||
| source->findLassoItemsInArea (itemsInLasso, getBounds()); | |||||
| if (e.mods.isShiftDown()) | if (e.mods.isShiftDown()) | ||||
| { | { | ||||
| @@ -25987,6 +26011,7 @@ private: | |||||
| Array <SelectableItemType> originalSelection; | Array <SelectableItemType> originalSelection; | ||||
| LassoSource <SelectableItemType>* source; | LassoSource <SelectableItemType>* source; | ||||
| int outlineThickness; | int outlineThickness; | ||||
| Point<int> dragStartPos; | |||||
| }; | }; | ||||
| #endif // __JUCE_LASSOCOMPONENT_JUCEHEADER__ | #endif // __JUCE_LASSOCOMPONENT_JUCEHEADER__ | ||||
| @@ -277,7 +277,7 @@ XmlElement* AudioProcessor::getXmlFromBinary (const void* data, | |||||
| const int sizeInBytes) | const int sizeInBytes) | ||||
| { | { | ||||
| if (sizeInBytes > 8 | if (sizeInBytes > 8 | ||||
| && ByteOrder::littleEndianInt ((const char*) data) == magicXmlNumber) | |||||
| && ByteOrder::littleEndianInt (data) == magicXmlNumber) | |||||
| { | { | ||||
| const int stringLength = (int) ByteOrder::littleEndianInt (((const char*) data) + 4); | const int stringLength = (int) ByteOrder::littleEndianInt (((const char*) data) + 4); | ||||
| @@ -80,7 +80,7 @@ public: | |||||
| if (this != &other) | if (this != &other) | ||||
| { | { | ||||
| ReferenceCountedArray<ObjectClass, TypeOfCriticalSectionToUse> otherCopy (other); | ReferenceCountedArray<ObjectClass, TypeOfCriticalSectionToUse> otherCopy (other); | ||||
| swapWithArray (other); | |||||
| swapWithArray (otherCopy); | |||||
| } | } | ||||
| return *this; | return *this; | ||||
| @@ -40,7 +40,7 @@ class TreeViewContentComponent : public Component, | |||||
| public TooltipClient | public TooltipClient | ||||
| { | { | ||||
| public: | public: | ||||
| TreeViewContentComponent (TreeView* const owner_) | |||||
| TreeViewContentComponent (TreeView& owner_) | |||||
| : owner (owner_), | : owner (owner_), | ||||
| buttonUnderMouse (0), | buttonUnderMouse (0), | ||||
| isDragging (false) | isDragging (false) | ||||
| @@ -67,9 +67,9 @@ public: | |||||
| // (if the open/close buttons are hidden, we'll treat clicks to the left of the item | // (if the open/close buttons are hidden, we'll treat clicks to the left of the item | ||||
| // as selection clicks) | // as selection clicks) | ||||
| if (e.x < pos.getX() && owner->openCloseButtonsVisible) | |||||
| if (e.x < pos.getX() && owner.openCloseButtonsVisible) | |||||
| { | { | ||||
| if (e.x >= pos.getX() - owner->getIndentSize()) | |||||
| if (e.x >= pos.getX() - owner.getIndentSize()) | |||||
| item->setOpen (! item->isOpen()); | item->setOpen (! item->isOpen()); | ||||
| // (clicks to the left of an open/close button are ignored) | // (clicks to the left of an open/close button are ignored) | ||||
| @@ -77,7 +77,7 @@ public: | |||||
| else | else | ||||
| { | { | ||||
| // mouse-down inside the body of the item.. | // mouse-down inside the body of the item.. | ||||
| if (! owner->isMultiSelectEnabled()) | |||||
| if (! owner.isMultiSelectEnabled()) | |||||
| item->setSelected (true, true); | item->setSelected (true, true); | ||||
| else if (item->isSelected()) | else if (item->isSelected()) | ||||
| needSelectionOnMouseUp = ! e.mods.isPopupMenu(); | needSelectionOnMouseUp = ! e.mods.isPopupMenu(); | ||||
| @@ -110,7 +110,7 @@ public: | |||||
| Rectangle<int> pos; | Rectangle<int> pos; | ||||
| TreeViewItem* const item = findItemAt (e.y, pos); | TreeViewItem* const item = findItemAt (e.y, pos); | ||||
| if (item != 0 && (e.x >= pos.getX() || ! owner->openCloseButtonsVisible)) | |||||
| if (item != 0 && (e.x >= pos.getX() || ! owner.openCloseButtonsVisible)) | |||||
| item->itemDoubleClicked (e.withNewPosition (e.getPosition() - pos.getPosition())); | item->itemDoubleClicked (e.withNewPosition (e.getPosition() - pos.getPosition())); | ||||
| } | } | ||||
| } | } | ||||
| @@ -143,7 +143,7 @@ public: | |||||
| dragImage->multiplyAllAlphas (0.6f); | dragImage->multiplyAllAlphas (0.6f); | ||||
| Point<int> imageOffset (pos.getX() - e.x, pos.getY() - e.y); | Point<int> imageOffset (pos.getX() - e.x, pos.getY() - e.y); | ||||
| dragContainer->startDragging (dragDescription, owner, dragImage, true, &imageOffset); | |||||
| dragContainer->startDragging (dragDescription, &owner, dragImage, true, &imageOffset); | |||||
| } | } | ||||
| else | else | ||||
| { | { | ||||
| @@ -166,25 +166,37 @@ public: | |||||
| updateButtonUnderMouse (e); | updateButtonUnderMouse (e); | ||||
| } | } | ||||
| void paint (Graphics& g); | |||||
| TreeViewItem* findItemAt (int y, Rectangle<int>& itemPosition) const; | |||||
| void paint (Graphics& g) | |||||
| { | |||||
| if (owner.rootItem != 0) | |||||
| { | |||||
| owner.handleAsyncUpdate(); | |||||
| static bool isMouseDraggingInChildCompOf (Component* const comp) | |||||
| if (! owner.rootItemVisible) | |||||
| g.setOrigin (0, -owner.rootItem->itemHeight); | |||||
| owner.rootItem->paintRecursively (g, getWidth()); | |||||
| } | |||||
| } | |||||
| TreeViewItem* findItemAt (int y, Rectangle<int>& itemPosition) const | |||||
| { | { | ||||
| for (int i = Desktop::getInstance().getNumMouseSources(); --i >= 0;) | |||||
| if (owner.rootItem != 0) | |||||
| { | { | ||||
| MouseInputSource* source = Desktop::getInstance().getMouseSource(i); | |||||
| owner.handleAsyncUpdate(); | |||||
| if (source->isDragging()) | |||||
| { | |||||
| Component* const underMouse = source->getComponentUnderMouse(); | |||||
| if (! owner.rootItemVisible) | |||||
| y += owner.rootItem->itemHeight; | |||||
| if (underMouse != 0 && (comp == underMouse || comp->isParentOf (underMouse))) | |||||
| return true; | |||||
| } | |||||
| TreeViewItem* const ti = owner.rootItem->findItemRecursively (y); | |||||
| if (ti != 0) | |||||
| itemPosition = ti->getItemPosition (false); | |||||
| return ti; | |||||
| } | } | ||||
| return false; | |||||
| return 0; | |||||
| } | } | ||||
| void updateComponents() | void updateComponents() | ||||
| @@ -193,8 +205,8 @@ public: | |||||
| const int visibleBottom = visibleTop + getParentHeight(); | const int visibleBottom = visibleTop + getParentHeight(); | ||||
| BigInteger itemsToKeep; | BigInteger itemsToKeep; | ||||
| TreeViewItem* item = owner->rootItem; | |||||
| int y = (item != 0 && !owner->rootItemVisible) ? -item->itemHeight : 0; | |||||
| TreeViewItem* item = owner.rootItem; | |||||
| int y = (item != 0 && ! owner.rootItemVisible) ? -item->itemHeight : 0; | |||||
| while (item != 0 && y < visibleBottom) | while (item != 0 && y < visibleBottom) | ||||
| { | { | ||||
| @@ -268,12 +280,12 @@ public: | |||||
| { | { | ||||
| TreeViewItem* newItem = 0; | TreeViewItem* newItem = 0; | ||||
| if (owner->openCloseButtonsVisible) | |||||
| if (owner.openCloseButtonsVisible) | |||||
| { | { | ||||
| Rectangle<int> pos; | Rectangle<int> pos; | ||||
| TreeViewItem* item = findItemAt (e.y, pos); | TreeViewItem* item = findItemAt (e.y, pos); | ||||
| if (item != 0 && e.x < pos.getX() && e.x >= pos.getX() - owner->getIndentSize()) | |||||
| if (item != 0 && e.x < pos.getX() && e.x >= pos.getX() - owner.getIndentSize()) | |||||
| { | { | ||||
| newItem = item; | newItem = item; | ||||
| @@ -300,14 +312,14 @@ public: | |||||
| } | } | ||||
| } | } | ||||
| bool isMouseOverButton (TreeViewItem* item) const throw() | |||||
| bool isMouseOverButton (TreeViewItem* const item) const throw() | |||||
| { | { | ||||
| return item == buttonUnderMouse; | return item == buttonUnderMouse; | ||||
| } | } | ||||
| void resized() | void resized() | ||||
| { | { | ||||
| owner->itemsChanged(); | |||||
| owner.itemsChanged(); | |||||
| } | } | ||||
| const String getTooltip() | const String getTooltip() | ||||
| @@ -318,31 +330,27 @@ public: | |||||
| if (item != 0) | if (item != 0) | ||||
| return item->getTooltip(); | return item->getTooltip(); | ||||
| return owner->getTooltip(); | |||||
| return owner.getTooltip(); | |||||
| } | } | ||||
| //============================================================================== | //============================================================================== | ||||
| juce_UseDebuggingNewOperator | juce_UseDebuggingNewOperator | ||||
| private: | private: | ||||
| TreeView* const owner; | |||||
| TreeView& owner; | |||||
| Array <TreeViewItem*> rowComponentItems; | Array <TreeViewItem*> rowComponentItems; | ||||
| Array <int> rowComponentIds; | Array <int> rowComponentIds; | ||||
| Array <Component*> rowComponents; | Array <Component*> rowComponents; | ||||
| TreeViewItem* buttonUnderMouse; | TreeViewItem* buttonUnderMouse; | ||||
| bool isDragging, needSelectionOnMouseUp; | bool isDragging, needSelectionOnMouseUp; | ||||
| TreeViewContentComponent (const TreeViewContentComponent&); | |||||
| TreeViewContentComponent& operator= (const TreeViewContentComponent&); | |||||
| void selectBasedOnModifiers (TreeViewItem* const item, const ModifierKeys& modifiers) | void selectBasedOnModifiers (TreeViewItem* const item, const ModifierKeys& modifiers) | ||||
| { | { | ||||
| TreeViewItem* firstSelected = 0; | TreeViewItem* firstSelected = 0; | ||||
| if (modifiers.isShiftDown() && ((firstSelected = owner->getSelectedItem (0)) != 0)) | |||||
| if (modifiers.isShiftDown() && ((firstSelected = owner.getSelectedItem (0)) != 0)) | |||||
| { | { | ||||
| TreeViewItem* const lastSelected = owner->getSelectedItem (owner->getNumSelectedItems() - 1); | |||||
| TreeViewItem* const lastSelected = owner.getSelectedItem (owner.getNumSelectedItems() - 1); | |||||
| jassert (lastSelected != 0); | jassert (lastSelected != 0); | ||||
| int rowStart = firstSelected->getRowNumberInTree(); | int rowStart = firstSelected->getRowNumberInTree(); | ||||
| @@ -357,13 +365,12 @@ private: | |||||
| swapVariables (ourRow, otherEnd); | swapVariables (ourRow, otherEnd); | ||||
| for (int i = ourRow; i <= otherEnd; ++i) | for (int i = ourRow; i <= otherEnd; ++i) | ||||
| owner->getItemOnRow (i)->setSelected (true, false); | |||||
| owner.getItemOnRow (i)->setSelected (true, false); | |||||
| } | } | ||||
| else | else | ||||
| { | { | ||||
| const bool cmd = modifiers.isCommandDown(); | |||||
| item->setSelected ((! cmd) || (! item->isSelected()), ! cmd); | |||||
| const bool cmd = modifiers.isCommandDown(); | |||||
| item->setSelected ((! cmd) || ! item->isSelected(), ! cmd); | |||||
| } | } | ||||
| } | } | ||||
| @@ -375,33 +382,63 @@ private: | |||||
| return false; | return false; | ||||
| } | } | ||||
| static bool isMouseDraggingInChildCompOf (Component* const comp) | |||||
| { | |||||
| for (int i = Desktop::getInstance().getNumMouseSources(); --i >= 0;) | |||||
| { | |||||
| MouseInputSource* const source = Desktop::getInstance().getMouseSource(i); | |||||
| if (source->isDragging()) | |||||
| { | |||||
| Component* const underMouse = source->getComponentUnderMouse(); | |||||
| if (underMouse != 0 && (comp == underMouse || comp->isParentOf (underMouse))) | |||||
| return true; | |||||
| } | |||||
| } | |||||
| return false; | |||||
| } | |||||
| TreeViewContentComponent (const TreeViewContentComponent&); | |||||
| TreeViewContentComponent& operator= (const TreeViewContentComponent&); | |||||
| }; | }; | ||||
| //============================================================================== | //============================================================================== | ||||
| class TreeView::TreeViewport : public Viewport | class TreeView::TreeViewport : public Viewport | ||||
| { | { | ||||
| public: | public: | ||||
| TreeViewport() throw() {} | |||||
| ~TreeViewport() throw() {} | |||||
| TreeViewport() throw() : lastX (-1) {} | |||||
| ~TreeViewport() throw() {} | |||||
| void updateComponents() | |||||
| void updateComponents (const bool triggerResize = false) | |||||
| { | { | ||||
| TreeViewContentComponent* const tvc = static_cast <TreeViewContentComponent*> (getViewedComponent()); | TreeViewContentComponent* const tvc = static_cast <TreeViewContentComponent*> (getViewedComponent()); | ||||
| if (tvc != 0) | if (tvc != 0) | ||||
| tvc->updateComponents(); | |||||
| { | |||||
| if (triggerResize) | |||||
| tvc->resized(); | |||||
| else | |||||
| tvc->updateComponents(); | |||||
| } | |||||
| repaint(); | repaint(); | ||||
| } | } | ||||
| void visibleAreaChanged (int, int, int, int) | |||||
| void visibleAreaChanged (int x, int, int, int) | |||||
| { | { | ||||
| updateComponents(); | |||||
| const bool hasScrolledSideways = (x != lastX); | |||||
| lastX = x; | |||||
| updateComponents (hasScrolledSideways); | |||||
| } | } | ||||
| //============================================================================== | //============================================================================== | ||||
| juce_UseDebuggingNewOperator | juce_UseDebuggingNewOperator | ||||
| private: | private: | ||||
| int lastX; | |||||
| TreeViewport (const TreeViewport&); | TreeViewport (const TreeViewport&); | ||||
| TreeViewport& operator= (const TreeViewport&); | TreeViewport& operator= (const TreeViewport&); | ||||
| }; | }; | ||||
| @@ -421,7 +458,7 @@ TreeView::TreeView (const String& componentName) | |||||
| openCloseButtonsVisible (true) | openCloseButtonsVisible (true) | ||||
| { | { | ||||
| addAndMakeVisible (viewport = new TreeViewport()); | addAndMakeVisible (viewport = new TreeViewport()); | ||||
| viewport->setViewedComponent (new TreeViewContentComponent (this)); | |||||
| viewport->setViewedComponent (new TreeViewContentComponent (*this)); | |||||
| viewport->setWantsKeyboardFocus (false); | viewport->setWantsKeyboardFocus (false); | ||||
| setWantsKeyboardFocus (true); | setWantsKeyboardFocus (true); | ||||
| } | } | ||||
| @@ -1054,40 +1091,6 @@ void TreeView::itemDropped (const String& sourceDescription, Component* sourceCo | |||||
| handleDrop (StringArray(), sourceDescription, sourceComponent, x, y); | handleDrop (StringArray(), sourceDescription, sourceComponent, x, y); | ||||
| } | } | ||||
| //============================================================================== | |||||
| void TreeViewContentComponent::paint (Graphics& g) | |||||
| { | |||||
| if (owner->rootItem != 0) | |||||
| { | |||||
| owner->handleAsyncUpdate(); | |||||
| if (! owner->rootItemVisible) | |||||
| g.setOrigin (0, -owner->rootItem->itemHeight); | |||||
| owner->rootItem->paintRecursively (g, getWidth()); | |||||
| } | |||||
| } | |||||
| TreeViewItem* TreeViewContentComponent::findItemAt (int y, Rectangle<int>& itemPosition) const | |||||
| { | |||||
| if (owner->rootItem != 0) | |||||
| { | |||||
| owner->handleAsyncUpdate(); | |||||
| if (! owner->rootItemVisible) | |||||
| y += owner->rootItem->itemHeight; | |||||
| TreeViewItem* const ti = owner->rootItem->findItemRecursively (y); | |||||
| if (ti != 0) | |||||
| itemPosition = ti->getItemPosition (false); | |||||
| return ti; | |||||
| } | |||||
| return 0; | |||||
| } | |||||
| //============================================================================== | //============================================================================== | ||||
| enum TreeViewOpenness | enum TreeViewOpenness | ||||
| { | { | ||||
| @@ -1309,7 +1312,6 @@ void TreeViewItem::itemDropped (const String& /*sourceDescription*/, Component* | |||||
| const Rectangle<int> TreeViewItem::getItemPosition (const bool relativeToTreeViewTopLeft) const throw() | const Rectangle<int> TreeViewItem::getItemPosition (const bool relativeToTreeViewTopLeft) const throw() | ||||
| { | { | ||||
| const int indentX = getIndentX(); | const int indentX = getIndentX(); | ||||
| int width = itemWidth; | int width = itemWidth; | ||||
| if (ownerView != 0 && width < 0) | if (ownerView != 0 && width < 0) | ||||
| @@ -1318,8 +1320,7 @@ const Rectangle<int> TreeViewItem::getItemPosition (const bool relativeToTreeVie | |||||
| Rectangle<int> r (indentX, y, jmax (0, width), totalHeight); | Rectangle<int> r (indentX, y, jmax (0, width), totalHeight); | ||||
| if (relativeToTreeViewTopLeft) | if (relativeToTreeViewTopLeft) | ||||
| r.setPosition (r.getX() - ownerView->viewport->getViewPositionX(), | |||||
| r.getY() - ownerView->viewport->getViewPositionY()); | |||||
| r -= ownerView->viewport->getViewPosition(); | |||||
| return r; | return r; | ||||
| } | } | ||||
| @@ -59,6 +59,9 @@ public: | |||||
| */ | */ | ||||
| virtual const File getSelectedFile (int index) const = 0; | virtual const File getSelectedFile (int index) const = 0; | ||||
| /** Deselects any selected files. */ | |||||
| virtual void deselectAllFiles() = 0; | |||||
| /** Scrolls this view to the top. */ | /** Scrolls this view to the top. */ | ||||
| virtual void scrollToTop() = 0; | virtual void scrollToTop() = 0; | ||||
| @@ -195,6 +195,11 @@ const File FileBrowserComponent::getHighlightedFile() const throw() | |||||
| return fileListComponent->getSelectedFile (0); | return fileListComponent->getSelectedFile (0); | ||||
| } | } | ||||
| void FileBrowserComponent::deselectAllFiles() | |||||
| { | |||||
| fileListComponent->deselectAllFiles(); | |||||
| } | |||||
| //============================================================================== | //============================================================================== | ||||
| bool FileBrowserComponent::isFileSuitable (const File& file) const | bool FileBrowserComponent::isFileSuitable (const File& file) const | ||||
| { | { | ||||
| @@ -114,6 +114,10 @@ public: | |||||
| */ | */ | ||||
| const File getSelectedFile (int index) const throw(); | const File getSelectedFile (int index) const throw(); | ||||
| /** Deselects any files that are currently selected. | |||||
| */ | |||||
| void deselectAllFiles(); | |||||
| /** Returns true if the currently selected file(s) are usable. | /** Returns true if the currently selected file(s) are usable. | ||||
| This can be used to decide whether the user can press "ok" for the | This can be used to decide whether the user can press "ok" for the | ||||
| @@ -60,6 +60,11 @@ const File FileListComponent::getSelectedFile (int index) const | |||||
| return fileList.getFile (getSelectedRow (index)); | return fileList.getFile (getSelectedRow (index)); | ||||
| } | } | ||||
| void FileListComponent::deselectAllFiles() | |||||
| { | |||||
| deselectAllRows(); | |||||
| } | |||||
| void FileListComponent::scrollToTop() | void FileListComponent::scrollToTop() | ||||
| { | { | ||||
| getVerticalScrollBar()->setCurrentRangeStart (0); | getVerticalScrollBar()->setCurrentRangeStart (0); | ||||
| @@ -70,6 +70,9 @@ public: | |||||
| */ | */ | ||||
| const File getSelectedFile (int index = 0) const; | const File getSelectedFile (int index = 0) const; | ||||
| /** Deselects any files that are currently selected. */ | |||||
| void deselectAllFiles(); | |||||
| /** Scrolls to the top of the list. */ | /** Scrolls to the top of the list. */ | ||||
| void scrollToTop(); | void scrollToTop(); | ||||
| @@ -250,10 +250,13 @@ const File FileTreeComponent::getSelectedFile (const int index) const | |||||
| { | { | ||||
| const FileListTreeItem* const item = dynamic_cast <const FileListTreeItem*> (getSelectedItem (index)); | const FileListTreeItem* const item = dynamic_cast <const FileListTreeItem*> (getSelectedItem (index)); | ||||
| if (item != 0) | |||||
| return item->file; | |||||
| return item != 0 ? item->file | |||||
| : File::nonexistent; | |||||
| } | |||||
| return File::nonexistent; | |||||
| void FileTreeComponent::deselectAllFiles() | |||||
| { | |||||
| clearSelectedItems(); | |||||
| } | } | ||||
| void FileTreeComponent::scrollToTop() | void FileTreeComponent::scrollToTop() | ||||
| @@ -66,6 +66,9 @@ public: | |||||
| */ | */ | ||||
| const File getSelectedFile (int index = 0) const; | const File getSelectedFile (int index = 0) const; | ||||
| /** Deselects any files that are currently selected. */ | |||||
| void deselectAllFiles(); | |||||
| /** Scrolls the list to the top. */ | /** Scrolls the list to the top. */ | ||||
| void scrollToTop(); | void scrollToTop(); | ||||
| @@ -35,10 +35,6 @@ BEGIN_JUCE_NAMESPACE | |||||
| Viewport::Viewport (const String& componentName) | Viewport::Viewport (const String& componentName) | ||||
| : Component (componentName), | : Component (componentName), | ||||
| contentComp (0), | contentComp (0), | ||||
| lastVX (0), | |||||
| lastVY (0), | |||||
| lastVW (0), | |||||
| lastVH (0), | |||||
| scrollBarThickness (0), | scrollBarThickness (0), | ||||
| singleStepX (16), | singleStepX (16), | ||||
| singleStepY (16), | singleStepY (16), | ||||
| @@ -106,16 +102,14 @@ int Viewport::getMaximumVisibleHeight() const throw() | |||||
| return jmax (0, getHeight() - (horizontalScrollBar->isVisible() ? getScrollBarThickness() : 0)); | return jmax (0, getHeight() - (horizontalScrollBar->isVisible() ? getScrollBarThickness() : 0)); | ||||
| } | } | ||||
| void Viewport::setViewPosition (const int xPixelsOffset, | |||||
| const int yPixelsOffset) | |||||
| void Viewport::setViewPosition (const int xPixelsOffset, const int yPixelsOffset) | |||||
| { | { | ||||
| if (contentComp != 0) | if (contentComp != 0) | ||||
| contentComp->setTopLeftPosition (-xPixelsOffset, | contentComp->setTopLeftPosition (-xPixelsOffset, | ||||
| -yPixelsOffset); | -yPixelsOffset); | ||||
| } | } | ||||
| void Viewport::setViewPositionProportionately (const double x, | |||||
| const double y) | |||||
| void Viewport::setViewPositionProportionately (const double x, const double y) | |||||
| { | { | ||||
| if (contentComp != 0) | if (contentComp != 0) | ||||
| setViewPosition (jmax (0, roundToInt (x * (contentComp->getWidth() - getWidth()))), | setViewPosition (jmax (0, roundToInt (x * (contentComp->getWidth() - getWidth()))), | ||||
| @@ -128,25 +122,31 @@ bool Viewport::autoScroll (int mouseX, int mouseY, int activeBorderThickness, in | |||||
| { | { | ||||
| int dx = 0, dy = 0; | int dx = 0, dy = 0; | ||||
| if (mouseX < activeBorderThickness) | |||||
| dx = activeBorderThickness - mouseX; | |||||
| else if (mouseX >= contentHolder->getWidth() - activeBorderThickness) | |||||
| dx = (contentHolder->getWidth() - activeBorderThickness) - mouseX; | |||||
| if (dx < 0) | |||||
| dx = jmax (dx, -maximumSpeed, contentHolder->getWidth() - contentComp->getRight()); | |||||
| else | |||||
| dx = jmin (dx, maximumSpeed, -contentComp->getX()); | |||||
| if (mouseY < activeBorderThickness) | |||||
| dy = activeBorderThickness - mouseY; | |||||
| else if (mouseY >= contentHolder->getHeight() - activeBorderThickness) | |||||
| dy = (contentHolder->getHeight() - activeBorderThickness) - mouseY; | |||||
| if (horizontalScrollBar->isVisible()) | |||||
| { | |||||
| if (mouseX < activeBorderThickness) | |||||
| dx = activeBorderThickness - mouseX; | |||||
| else if (mouseX >= contentHolder->getWidth() - activeBorderThickness) | |||||
| dx = (contentHolder->getWidth() - activeBorderThickness) - mouseX; | |||||
| if (dx < 0) | |||||
| dx = jmax (dx, -maximumSpeed, contentHolder->getWidth() - contentComp->getRight()); | |||||
| else | |||||
| dx = jmin (dx, maximumSpeed, -contentComp->getX()); | |||||
| } | |||||
| if (dy < 0) | |||||
| dy = jmax (dy, -maximumSpeed, contentHolder->getHeight() - contentComp->getBottom()); | |||||
| else | |||||
| dy = jmin (dy, maximumSpeed, -contentComp->getY()); | |||||
| if (verticalScrollBar->isVisible()) | |||||
| { | |||||
| if (mouseY < activeBorderThickness) | |||||
| dy = activeBorderThickness - mouseY; | |||||
| else if (mouseY >= contentHolder->getHeight() - activeBorderThickness) | |||||
| dy = (contentHolder->getHeight() - activeBorderThickness) - mouseY; | |||||
| if (dy < 0) | |||||
| dy = jmax (dy, -maximumSpeed, contentHolder->getHeight() - contentComp->getBottom()); | |||||
| else | |||||
| dy = jmin (dy, maximumSpeed, -contentComp->getY()); | |||||
| } | |||||
| if (dx != 0 || dy != 0) | if (dx != 0 || dy != 0) | ||||
| { | { | ||||
| @@ -176,10 +176,10 @@ void Viewport::updateVisibleRegion() | |||||
| { | { | ||||
| if (contentComp != 0) | if (contentComp != 0) | ||||
| { | { | ||||
| const int newVX = -contentComp->getX(); | |||||
| const int newVY = -contentComp->getY(); | |||||
| Rectangle<int> newViewPos; | |||||
| newViewPos.setPosition (-contentComp->getPosition()); | |||||
| if (newVX == 0 && newVY == 0 | |||||
| if (newViewPos.getX() == 0 && newViewPos.getY() == 0 | |||||
| && contentComp->getWidth() <= getWidth() | && contentComp->getWidth() <= getWidth() | ||||
| && contentComp->getHeight() <= getHeight()) | && contentComp->getHeight() <= getHeight()) | ||||
| { | { | ||||
| @@ -188,14 +188,14 @@ void Viewport::updateVisibleRegion() | |||||
| } | } | ||||
| horizontalScrollBar->setRangeLimits (0.0, contentComp->getWidth()); | horizontalScrollBar->setRangeLimits (0.0, contentComp->getWidth()); | ||||
| horizontalScrollBar->setCurrentRange (newVX, getMaximumVisibleWidth()); | |||||
| horizontalScrollBar->setCurrentRange (newViewPos.getX(), getMaximumVisibleWidth()); | |||||
| horizontalScrollBar->setSingleStepSize (singleStepX); | horizontalScrollBar->setSingleStepSize (singleStepX); | ||||
| if (! (contentComp->getWidth() > 0 && showHScrollbar && getHeight() > getScrollBarThickness())) | if (! (contentComp->getWidth() > 0 && showHScrollbar && getHeight() > getScrollBarThickness())) | ||||
| horizontalScrollBar->setVisible (! horizontalScrollBar->autoHides()); | horizontalScrollBar->setVisible (! horizontalScrollBar->autoHides()); | ||||
| verticalScrollBar->setRangeLimits (0.0, contentComp->getHeight()); | verticalScrollBar->setRangeLimits (0.0, contentComp->getHeight()); | ||||
| verticalScrollBar->setCurrentRange (newVY, getMaximumVisibleHeight()); | |||||
| verticalScrollBar->setCurrentRange (newViewPos.getY(), getMaximumVisibleHeight()); | |||||
| verticalScrollBar->setSingleStepSize (singleStepY); | verticalScrollBar->setSingleStepSize (singleStepY); | ||||
| if (! (contentComp->getHeight() > 0 && showVScrollbar && getWidth() > getScrollBarThickness())) | if (! (contentComp->getHeight() > 0 && showVScrollbar && getWidth() > getScrollBarThickness())) | ||||
| @@ -203,8 +203,8 @@ void Viewport::updateVisibleRegion() | |||||
| if (verticalScrollBar->isVisible()) | if (verticalScrollBar->isVisible()) | ||||
| { | { | ||||
| horizontalScrollBar->setCurrentRange (newVX, getMaximumVisibleWidth()); | |||||
| verticalScrollBar->setCurrentRange (newVY, getMaximumVisibleHeight()); | |||||
| horizontalScrollBar->setCurrentRange (newViewPos.getX(), getMaximumVisibleWidth()); | |||||
| verticalScrollBar->setCurrentRange (newViewPos.getY(), getMaximumVisibleHeight()); | |||||
| verticalScrollBar | verticalScrollBar | ||||
| ->setBounds (getMaximumVisibleWidth(), 0, | ->setBounds (getMaximumVisibleWidth(), 0, | ||||
| @@ -213,7 +213,7 @@ void Viewport::updateVisibleRegion() | |||||
| if (horizontalScrollBar->isVisible()) | if (horizontalScrollBar->isVisible()) | ||||
| { | { | ||||
| horizontalScrollBar->setCurrentRange (newVX, getMaximumVisibleWidth()); | |||||
| horizontalScrollBar->setCurrentRange (newViewPos.getX(), getMaximumVisibleWidth()); | |||||
| horizontalScrollBar | horizontalScrollBar | ||||
| ->setBounds (0, getMaximumVisibleHeight(), | ->setBounds (0, getMaximumVisibleHeight(), | ||||
| @@ -223,20 +223,13 @@ void Viewport::updateVisibleRegion() | |||||
| contentHolder->setSize (getMaximumVisibleWidth(), | contentHolder->setSize (getMaximumVisibleWidth(), | ||||
| getMaximumVisibleHeight()); | getMaximumVisibleHeight()); | ||||
| const int newVW = jmin (contentComp->getRight(), getMaximumVisibleWidth()); | |||||
| const int newVH = jmin (contentComp->getBottom(), getMaximumVisibleHeight()); | |||||
| newViewPos.setSize (jmin (contentComp->getRight(), getMaximumVisibleWidth()), | |||||
| jmin (contentComp->getBottom(), getMaximumVisibleHeight())); | |||||
| if (newVX != lastVX | |||||
| || newVY != lastVY | |||||
| || newVW != lastVW | |||||
| || newVH != lastVH) | |||||
| if (lastViewPos != newViewPos) | |||||
| { | { | ||||
| lastVX = newVX; | |||||
| lastVY = newVY; | |||||
| lastVW = newVW; | |||||
| lastVH = newVH; | |||||
| visibleAreaChanged (newVX, newVY, newVW, newVH); | |||||
| lastViewPos = newViewPos; | |||||
| visibleAreaChanged (newViewPos.getX(), newViewPos.getY(), newViewPos.getWidth(), newViewPos.getHeight()); | |||||
| } | } | ||||
| horizontalScrollBar->handleUpdateNowIfNeeded(); | horizontalScrollBar->handleUpdateNowIfNeeded(); | ||||
| @@ -250,8 +243,7 @@ void Viewport::updateVisibleRegion() | |||||
| } | } | ||||
| //============================================================================== | //============================================================================== | ||||
| void Viewport::setSingleStepSizes (const int stepX, | |||||
| const int stepY) | |||||
| void Viewport::setSingleStepSizes (const int stepX, const int stepY) | |||||
| { | { | ||||
| singleStepX = stepX; | singleStepX = stepX; | ||||
| singleStepY = stepY; | singleStepY = stepY; | ||||
| @@ -119,29 +119,33 @@ public: | |||||
| */ | */ | ||||
| bool autoScroll (int mouseX, int mouseY, int distanceFromEdge, int maximumSpeed); | bool autoScroll (int mouseX, int mouseY, int distanceFromEdge, int maximumSpeed); | ||||
| /** Returns the position within the child component of the top-left of its visible area. | |||||
| */ | |||||
| const Point<int> getViewPosition() const throw() { return lastViewPos.getPosition(); } | |||||
| /** Returns the position within the child component of the top-left of its visible area. | /** Returns the position within the child component of the top-left of its visible area. | ||||
| @see getViewWidth, setViewPosition | @see getViewWidth, setViewPosition | ||||
| */ | */ | ||||
| int getViewPositionX() const throw() { return lastVX; } | |||||
| int getViewPositionX() const throw() { return lastViewPos.getX(); } | |||||
| /** Returns the position within the child component of the top-left of its visible area. | /** Returns the position within the child component of the top-left of its visible area. | ||||
| @see getViewHeight, setViewPosition | @see getViewHeight, setViewPosition | ||||
| */ | */ | ||||
| int getViewPositionY() const throw() { return lastVY; } | |||||
| int getViewPositionY() const throw() { return lastViewPos.getY(); } | |||||
| /** Returns the width of the visible area of the child component. | /** Returns the width of the visible area of the child component. | ||||
| This may be less than the width of this Viewport if there's a vertical scrollbar | This may be less than the width of this Viewport if there's a vertical scrollbar | ||||
| or if the child component is itself smaller. | or if the child component is itself smaller. | ||||
| */ | */ | ||||
| int getViewWidth() const throw() { return lastVW; } | |||||
| int getViewWidth() const throw() { return lastViewPos.getWidth(); } | |||||
| /** Returns the height of the visible area of the child component. | /** Returns the height of the visible area of the child component. | ||||
| This may be less than the height of this Viewport if there's a horizontal scrollbar | This may be less than the height of this Viewport if there's a horizontal scrollbar | ||||
| or if the child component is itself smaller. | or if the child component is itself smaller. | ||||
| */ | */ | ||||
| int getViewHeight() const throw() { return lastVH; } | |||||
| int getViewHeight() const throw() { return lastViewPos.getHeight(); } | |||||
| /** Returns the width available within this component for the contents. | /** Returns the width available within this component for the contents. | ||||
| @@ -241,7 +245,7 @@ public: | |||||
| private: | private: | ||||
| Component::SafePointer<Component> contentComp; | Component::SafePointer<Component> contentComp; | ||||
| int lastVX, lastVY, lastVW, lastVH; | |||||
| Rectangle<int> lastViewPos; | |||||
| int scrollBarThickness; | int scrollBarThickness; | ||||
| int singleStepX, singleStepY; | int singleStepX, singleStepY; | ||||
| bool showHScrollbar, showVScrollbar; | bool showHScrollbar, showVScrollbar; | ||||
| @@ -250,6 +254,7 @@ private: | |||||
| ScrollBar* horizontalScrollBar; | ScrollBar* horizontalScrollBar; | ||||
| void updateVisibleRegion(); | void updateVisibleRegion(); | ||||
| Viewport (const Viewport&); | Viewport (const Viewport&); | ||||
| Viewport& operator= (const Viewport&); | Viewport& operator= (const Viewport&); | ||||
| }; | }; | ||||
| @@ -56,7 +56,7 @@ public: | |||||
| component itself). | component itself). | ||||
| */ | */ | ||||
| virtual void findLassoItemsInArea (Array <SelectableItemType>& itemsFound, | virtual void findLassoItemsInArea (Array <SelectableItemType>& itemsFound, | ||||
| int x, int y, int width, int height) = 0; | |||||
| const Rectangle<int>& area) = 0; | |||||
| /** Returns the SelectedItemSet that the lasso should update. | /** Returns the SelectedItemSet that the lasso should update. | ||||
| @@ -141,6 +141,7 @@ public: | |||||
| originalSelection = lassoSource->getLassoSelection().getItemArray(); | originalSelection = lassoSource->getLassoSelection().getItemArray(); | ||||
| setSize (0, 0); | setSize (0, 0); | ||||
| dragStartPos = e.getMouseDownPosition(); | |||||
| } | } | ||||
| /** Call this in your mouseDrag event, to update the lasso's position. | /** Call this in your mouseDrag event, to update the lasso's position. | ||||
| @@ -159,11 +160,11 @@ public: | |||||
| { | { | ||||
| if (source != 0) | if (source != 0) | ||||
| { | { | ||||
| setBounds (Rectangle<int> (e.getMouseDownPosition(), e.getPosition())); | |||||
| setBounds (Rectangle<int> (dragStartPos, e.getPosition())); | |||||
| setVisible (true); | setVisible (true); | ||||
| Array <SelectableItemType> itemsInLasso; | Array <SelectableItemType> itemsInLasso; | ||||
| source->findLassoItemsInArea (itemsInLasso, getX(), getY(), getWidth(), getHeight()); | |||||
| source->findLassoItemsInArea (itemsInLasso, getBounds()); | |||||
| if (e.mods.isShiftDown()) | if (e.mods.isShiftDown()) | ||||
| { | { | ||||
| @@ -236,6 +237,7 @@ private: | |||||
| Array <SelectableItemType> originalSelection; | Array <SelectableItemType> originalSelection; | ||||
| LassoSource <SelectableItemType>* source; | LassoSource <SelectableItemType>* source; | ||||
| int outlineThickness; | int outlineThickness; | ||||
| Point<int> dragStartPos; | |||||
| }; | }; | ||||
| @@ -233,12 +233,26 @@ public: | |||||
| return Rectangle (x + deltaPosition.getX(), y + deltaPosition.getY(), w, h); | return Rectangle (x + deltaPosition.getX(), y + deltaPosition.getY(), w, h); | ||||
| } | } | ||||
| /** Moves this rectangle by a given amount. */ | |||||
| Rectangle& operator+= (const Point<ValueType>& deltaPosition) throw() | |||||
| { | |||||
| x += deltaPosition.getX(); y += deltaPosition.getY(); | |||||
| return *this; | |||||
| } | |||||
| /** Returns a rectangle which is the same as this one moved by a given amount. */ | /** Returns a rectangle which is the same as this one moved by a given amount. */ | ||||
| const Rectangle operator- (const Point<ValueType>& deltaPosition) const throw() | const Rectangle operator- (const Point<ValueType>& deltaPosition) const throw() | ||||
| { | { | ||||
| return Rectangle (x - deltaPosition.getX(), y - deltaPosition.getY(), w, h); | return Rectangle (x - deltaPosition.getX(), y - deltaPosition.getY(), w, h); | ||||
| } | } | ||||
| /** Moves this rectangle by a given amount. */ | |||||
| Rectangle& operator-= (const Point<ValueType>& deltaPosition) throw() | |||||
| { | |||||
| x -= deltaPosition.getX(); y -= deltaPosition.getY(); | |||||
| return *this; | |||||
| } | |||||
| /** Expands the rectangle by a given amount. | /** Expands the rectangle by a given amount. | ||||
| Effectively, its new size is (x - deltaX, y - deltaY, w + deltaX * 2, h + deltaY * 2). | Effectively, its new size is (x - deltaX, y - deltaY, w + deltaX * 2, h + deltaY * 2). | ||||
| @@ -302,27 +302,32 @@ public: | |||||
| { | { | ||||
| const KeyPress& kp = keyPresses.getReference(0); | const KeyPress& kp = keyPresses.getReference(0); | ||||
| juce_wchar key = kp.getTextCharacter(); | |||||
| if (kp.getKeyCode() == KeyPress::backspaceKey) | |||||
| key = NSBackspaceCharacter; | |||||
| else if (kp.getKeyCode() == KeyPress::deleteKey) | |||||
| key = NSDeleteCharacter; | |||||
| else if (key == 0) | |||||
| key = (juce_wchar) kp.getKeyCode(); | |||||
| unsigned int mods = 0; | |||||
| if (kp.getModifiers().isShiftDown()) | |||||
| mods |= NSShiftKeyMask; | |||||
| if (kp.getModifiers().isCtrlDown()) | |||||
| mods |= NSControlKeyMask; | |||||
| if (kp.getModifiers().isAltDown()) | |||||
| mods |= NSAlternateKeyMask; | |||||
| if (kp.getModifiers().isCommandDown()) | |||||
| mods |= NSCommandKeyMask; | |||||
| [item setKeyEquivalent: juceStringToNS (String::charToString (key))]; | |||||
| [item setKeyEquivalentModifierMask: mods]; | |||||
| if (kp.getKeyCode() != KeyPress::backspaceKey | |||||
| && kp.getKeyCode() != KeyPress::deleteKey) // (adding these is annoying because it flashes the menu bar | |||||
| // every time you press the key while editing text) | |||||
| { | |||||
| juce_wchar key = kp.getTextCharacter(); | |||||
| if (kp.getKeyCode() == KeyPress::backspaceKey) | |||||
| key = NSBackspaceCharacter; | |||||
| else if (kp.getKeyCode() == KeyPress::deleteKey) | |||||
| key = NSDeleteCharacter; | |||||
| else if (key == 0) | |||||
| key = (juce_wchar) kp.getKeyCode(); | |||||
| unsigned int mods = 0; | |||||
| if (kp.getModifiers().isShiftDown()) | |||||
| mods |= NSShiftKeyMask; | |||||
| if (kp.getModifiers().isCtrlDown()) | |||||
| mods |= NSControlKeyMask; | |||||
| if (kp.getModifiers().isAltDown()) | |||||
| mods |= NSAlternateKeyMask; | |||||
| if (kp.getModifiers().isCommandDown()) | |||||
| mods |= NSCommandKeyMask; | |||||
| [item setKeyEquivalent: juceStringToNS (String::charToString (key))]; | |||||
| [item setKeyEquivalentModifierMask: mods]; | |||||
| } | |||||
| } | } | ||||
| } | } | ||||
| } | } | ||||