diff --git a/extras/Jucer (experimental)/Source/model/jucer_CodeGenerator.cpp b/extras/Jucer (experimental)/Source/model/jucer_CodeGenerator.cpp index fe7e937913..0ab89ec6b1 100644 --- a/extras/Jucer (experimental)/Source/model/jucer_CodeGenerator.cpp +++ b/extras/Jucer (experimental)/Source/model/jucer_CodeGenerator.cpp @@ -378,9 +378,9 @@ CodeGenerator::CustomCodeList::~CustomCodeList() void CodeGenerator::CustomCodeList::reloadFrom (const String& fileContent) { - sectionNames.clear(); - sectionContent.clear(); - + StringArray newNames; + ReferenceCountedArray newContent; + StringArray lines; lines.addLines (fileContent); @@ -400,22 +400,28 @@ void CodeGenerator::CustomCodeList::reloadFrom (const String& fileContent) if (endLine > i) { 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; } } } } - + + sectionNames = newNames; + sectionContent = newContent; + sendSynchronousChangeMessage (this); } diff --git a/extras/Jucer (experimental)/Source/model/jucer_CodeGenerator.h b/extras/Jucer (experimental)/Source/model/jucer_CodeGenerator.h index d46ecad288..609beb1367 100644 --- a/extras/Jucer (experimental)/Source/model/jucer_CodeGenerator.h +++ b/extras/Jucer (experimental)/Source/model/jucer_CodeGenerator.h @@ -90,14 +90,13 @@ public: class CodeDocumentRef : public ReferenceCountedObject { 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 Ptr; private: - CodeDocument* doc; + CodeDocument* const doc; }; //============================================================================== diff --git a/extras/Jucer (experimental)/Source/model/jucer_ComponentDocument.cpp b/extras/Jucer (experimental)/Source/model/jucer_ComponentDocument.cpp index bf31f2af18..c05a303d5c 100644 --- a/extras/Jucer (experimental)/Source/model/jucer_ComponentDocument.cpp +++ b/extras/Jucer (experimental)/Source/model/jucer_ComponentDocument.cpp @@ -122,6 +122,20 @@ bool ComponentDocument::isComponentFile (const File& file) 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::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) { CodeGenerator codeGen; diff --git a/extras/Jucer (experimental)/Source/model/jucer_ComponentDocument.h b/extras/Jucer (experimental)/Source/model/jucer_ComponentDocument.h index 0af094740f..47f0752390 100644 --- a/extras/Jucer (experimental)/Source/model/jucer_ComponentDocument.h +++ b/extras/Jucer (experimental)/Source/model/jucer_ComponentDocument.h @@ -142,6 +142,9 @@ public: const String getCppTemplate() const; const String getHeaderTemplate() const; + const String getCppContent(); + const String getHeaderContent(); + //============================================================================== ValueTree& getRoot() { return root; } ValueTree getComponentGroup() const; diff --git a/extras/Jucer (experimental)/Source/ui/Component Editor/jucer_ComponentEditor.cpp b/extras/Jucer (experimental)/Source/ui/Component Editor/jucer_ComponentEditor.cpp index 48aed649d6..7fa3bdc603 100644 --- a/extras/Jucer (experimental)/Source/ui/Component Editor/jucer_ComponentEditor.cpp +++ b/extras/Jucer (experimental)/Source/ui/Component Editor/jucer_ComponentEditor.cpp @@ -530,15 +530,20 @@ private: }; //============================================================================== -class ComponentEditor::CodeEditorHolder : public Component +class ComponentEditor::CodeEditorHolder : public Component, + public ButtonListener { public: 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() @@ -547,26 +552,36 @@ public: void resized() { - viewport->setBounds (getLocalBounds()); + viewport.setBounds (getLocalBounds()); - int visWidth = viewport->getMaximumVisibleWidth(); - dynamic_cast (viewport->getViewedComponent())->updateSize (visWidth); + int visWidth = viewport.getMaximumVisibleWidth(); + dynamic_cast (viewport.getViewedComponent())->updateSize (visWidth); - if (viewport->getMaximumVisibleWidth() != visWidth) - dynamic_cast (viewport->getViewedComponent())->updateSize (viewport->getMaximumVisibleWidth()); + if (viewport.getMaximumVisibleWidth() != visWidth) + dynamic_cast (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: - 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) + const String& textBefore, const String& textAfter) + : document (doc), cppTokeniser(), codeEditor (doc->getDocument(), &cppTokeniser) { linesBefore.addLines (textBefore); linesAfter.addLines (textAfter); @@ -603,7 +618,7 @@ private: codeEditor.setBounds (0, fontHeight * linesBefore.size() + 1, 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()); } @@ -616,27 +631,29 @@ private: getParentComponent()->handleCommandMessage (updateCommandId); } + private: 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_) + ContentHolder (ComponentDocument& document_, bool isHeader_) + : document (document_), isHeader (isHeader_) { setOpaque (true); - editor.getDocument().getCustomCodeList().addChangeListener (this); + document.getCustomCodeList().addChangeListener (this); changeListenerCallback (0); } ~ContentHolder() { - editor.getDocument().getCustomCodeList().removeChangeListener (this); + document.getCustomCodeList().removeChangeListener (this); } void paint (Graphics& g) @@ -647,12 +664,12 @@ private: 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; + EditorHolder* const ed = editors.getUnchecked(i); + ed->updateSize (width - 8); + ed->setTopLeftPosition (4, y + 1); + y = ed->getBottom() + 1; } setSize (width, y + 2); @@ -662,12 +679,13 @@ private: { 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()) { - 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); addAndMakeVisible (ed); } @@ -683,11 +701,16 @@ private: Component::handleCommandMessage (commandId); } + private: OwnedArray editors; - ComponentEditor& editor; + ComponentDocument& document; + bool isHeader; }; - Viewport* viewport; + ComponentEditor& editor; + Viewport viewport; + TextButton switchFileButton; + bool showingHeader; }; //============================================================================== diff --git a/extras/Jucer (experimental)/Source/ui/Component Editor/jucer_ComponentEditorCanvas.cpp b/extras/Jucer (experimental)/Source/ui/Component Editor/jucer_ComponentEditorCanvas.cpp index ce10febf8f..e44f8da7f8 100644 --- a/extras/Jucer (experimental)/Source/ui/Component Editor/jucer_ComponentEditorCanvas.cpp +++ b/extras/Jucer (experimental)/Source/ui/Component Editor/jucer_ComponentEditorCanvas.cpp @@ -485,6 +485,14 @@ public: canvas.continueDrag (e); 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) @@ -524,10 +532,10 @@ public: } } - void findLassoItemsInArea (Array & itemsFound, int x, int y, int width, int height) + void findLassoItemsInArea (Array & itemsFound, const Rectangle& area) { - canvas.getComponentHolder()->findLassoItemsInArea (itemsFound, Rectangle (x, y, width, height) - + relativePositionToOtherComponent (canvas.getComponentHolder(), Point())); + canvas.getComponentHolder() + ->findLassoItemsInArea (itemsFound, area + relativePositionToOtherComponent (canvas.getComponentHolder(), Point())); } SelectedItems& getLassoSelection() { return canvas.getSelection(); } @@ -770,7 +778,7 @@ ComponentEditorCanvas::~ComponentEditorCanvas() { dragger = 0; getDocument().getRoot().removeListener (this); - componentHolder->deleteAllChildren(); + //deleteAndZero (componentHolder); deleteAllChildren(); } @@ -1006,6 +1014,7 @@ ComponentEditorCanvas::ComponentHolder::ComponentHolder() ComponentEditorCanvas::ComponentHolder::~ComponentHolder() { + deleteAllChildren(); } void ComponentEditorCanvas::ComponentHolder::updateComponents (ComponentDocument& doc, SelectedItems& selection) @@ -1055,7 +1064,6 @@ Component* ComponentEditorCanvas::ComponentHolder::getComponentForState (Compone for (int i = getNumChildComponents(); --i >= 0;) { Component* const c = getChildComponent (i); - if (doc.isStateForComponent (state, c)) return c; } @@ -1068,7 +1076,6 @@ Component* ComponentEditorCanvas::ComponentHolder::findComponentWithID (const St for (int i = getNumChildComponents(); --i >= 0;) { Component* const c = getChildComponent(i); - if (ComponentDocument::getJucerIDFor (c) == uid) return c; } diff --git a/extras/Jucer (experimental)/Source/ui/Drawable Editor/jucer_DrawableEditor.cpp b/extras/Jucer (experimental)/Source/ui/Drawable Editor/jucer_DrawableEditor.cpp index 6020bda0bb..38bde2ef9d 100644 --- a/extras/Jucer (experimental)/Source/ui/Drawable Editor/jucer_DrawableEditor.cpp +++ b/extras/Jucer (experimental)/Source/ui/Drawable Editor/jucer_DrawableEditor.cpp @@ -191,14 +191,14 @@ void DrawableEditor::Canvas::mouseUp (const MouseEvent& e) } } -void DrawableEditor::Canvas::findLassoItemsInArea (Array & itemsFound, int x, int y, int width, int height) +void DrawableEditor::Canvas::findLassoItemsInArea (Array & itemsFound, const Rectangle& area) { for (int i = getNumChildComponents(); --i >= 0;) { DrawableObjectComponent* d = dynamic_cast (getChildComponent(i)); if (d != 0) - d->findLassoItemsInArea (itemsFound, Rectangle (x, y, width, height)); + d->findLassoItemsInArea (itemsFound, area); } } diff --git a/extras/Jucer (experimental)/Source/ui/Drawable Editor/jucer_DrawableEditor.h b/extras/Jucer (experimental)/Source/ui/Drawable Editor/jucer_DrawableEditor.h index 49fbfb01a1..31a6f35dc2 100644 --- a/extras/Jucer (experimental)/Source/ui/Drawable Editor/jucer_DrawableEditor.h +++ b/extras/Jucer (experimental)/Source/ui/Drawable Editor/jucer_DrawableEditor.h @@ -67,7 +67,7 @@ public: void childBoundsChanged (Component* child); void updateSize(); - void findLassoItemsInArea (Array & itemsFound, int x, int y, int width, int height); + void findLassoItemsInArea (Array & itemsFound, const Rectangle& area); SelectedItemSet & getLassoSelection(); private: diff --git a/extras/audio plugins/demo/Source/PluginEditor.cpp b/extras/audio plugins/demo/Source/PluginEditor.cpp index 9581cbc3f9..dc62ec54b1 100644 --- a/extras/audio plugins/demo/Source/PluginEditor.cpp +++ b/extras/audio plugins/demo/Source/PluginEditor.cpp @@ -73,6 +73,9 @@ void JuceDemoPluginAudioProcessorEditor::resized() midiKeyboard->setBounds (4, getHeight() - keyboardHeight - 4, getWidth() - 8, keyboardHeight); resizer->setBounds (getWidth() - 16, getHeight() - 16, 16, 16); + + getProcessor()->lastUIWidth = getWidth(); + getProcessor()->lastUIHeight = getHeight(); } //============================================================================== diff --git a/extras/the jucer/src/ui/jucer_ComponentLayoutEditor.cpp b/extras/the jucer/src/ui/jucer_ComponentLayoutEditor.cpp index 1977f741c7..25c9102cfd 100644 --- a/extras/the jucer/src/ui/jucer_ComponentLayoutEditor.cpp +++ b/extras/the jucer/src/ui/jucer_ComponentLayoutEditor.cpp @@ -402,10 +402,9 @@ ComponentOverlayComponent* ComponentLayoutEditor::getOverlayCompFor (Component* return 0; } -void ComponentLayoutEditor::findLassoItemsInArea (Array & results, - int x, int y, int w, int h) +void ComponentLayoutEditor::findLassoItemsInArea (Array & results, const Rectangle& area) { - const Rectangle lasso (x - subCompHolder->getX(), y - subCompHolder->getY(), w, h); + const Rectangle lasso (area - subCompHolder->getPosition()); for (int i = 0; i < subCompHolder->getNumChildComponents(); ++i) { diff --git a/extras/the jucer/src/ui/jucer_ComponentLayoutEditor.h b/extras/the jucer/src/ui/jucer_ComponentLayoutEditor.h index 29aad35c6b..37b47ff239 100644 --- a/extras/the jucer/src/ui/jucer_ComponentLayoutEditor.h +++ b/extras/the jucer/src/ui/jucer_ComponentLayoutEditor.h @@ -60,8 +60,7 @@ public: ComponentLayout& getLayout() const throw() { return layout; } - void findLassoItemsInArea (Array & results, - int x, int y, int w, int h); + void findLassoItemsInArea (Array & results, const Rectangle& area); SelectedItemSet & getLassoSelection(); diff --git a/extras/the jucer/src/ui/jucer_PaintRoutineEditor.cpp b/extras/the jucer/src/ui/jucer_PaintRoutineEditor.cpp index 20cf25ac64..c1e189051b 100644 --- a/extras/the jucer/src/ui/jucer_PaintRoutineEditor.cpp +++ b/extras/the jucer/src/ui/jucer_PaintRoutineEditor.cpp @@ -260,11 +260,8 @@ void PaintRoutineEditor::mouseUp (const MouseEvent& e) } } -void PaintRoutineEditor::findLassoItemsInArea (Array & results, - int x, int y, int w, int h) +void PaintRoutineEditor::findLassoItemsInArea (Array & results, const Rectangle& lasso) { - const Rectangle lasso (x, y, w, h); - for (int i = 0; i < getNumChildComponents(); ++i) { PaintElement* const e = dynamic_cast (getChildComponent (i)); diff --git a/extras/the jucer/src/ui/jucer_PaintRoutineEditor.h b/extras/the jucer/src/ui/jucer_PaintRoutineEditor.h index cd4fde2785..3f7a968efa 100644 --- a/extras/the jucer/src/ui/jucer_PaintRoutineEditor.h +++ b/extras/the jucer/src/ui/jucer_PaintRoutineEditor.h @@ -58,8 +58,7 @@ public: void mouseUp (const MouseEvent& e); void visibilityChanged(); - void findLassoItemsInArea (Array & results, - int x, int y, int w, int h); + void findLassoItemsInArea (Array & results, const Rectangle& area); SelectedItemSet & getLassoSelection(); diff --git a/juce_amalgamated.cpp b/juce_amalgamated.cpp index eb4e637563..0d6eac02f3 100644 --- a/juce_amalgamated.cpp +++ b/juce_amalgamated.cpp @@ -34316,7 +34316,7 @@ XmlElement* AudioProcessor::getXmlFromBinary (const void* data, const int sizeInBytes) { if (sizeInBytes > 8 - && ByteOrder::littleEndianInt ((const char*) data) == magicXmlNumber) + && ByteOrder::littleEndianInt (data) == magicXmlNumber) { const int stringLength = (int) ByteOrder::littleEndianInt (((const char*) data) + 4); @@ -54338,7 +54338,7 @@ class TreeViewContentComponent : public Component, public TooltipClient { public: - TreeViewContentComponent (TreeView* const owner_) + TreeViewContentComponent (TreeView& owner_) : owner (owner_), buttonUnderMouse (0), isDragging (false) @@ -54365,9 +54365,9 @@ public: // (if the open/close buttons are hidden, we'll treat clicks to the left of the item // 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()); // (clicks to the left of an open/close button are ignored) @@ -54375,7 +54375,7 @@ public: else { // mouse-down inside the body of the item.. - if (! owner->isMultiSelectEnabled()) + if (! owner.isMultiSelectEnabled()) item->setSelected (true, true); else if (item->isSelected()) needSelectionOnMouseUp = ! e.mods.isPopupMenu(); @@ -54408,7 +54408,7 @@ public: Rectangle 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())); } } @@ -54441,7 +54441,7 @@ public: dragImage->multiplyAllAlphas (0.6f); Point imageOffset (pos.getX() - e.x, pos.getY() - e.y); - dragContainer->startDragging (dragDescription, owner, dragImage, true, &imageOffset); + dragContainer->startDragging (dragDescription, &owner, dragImage, true, &imageOffset); } else { @@ -54464,25 +54464,37 @@ public: updateButtonUnderMouse (e); } - void paint (Graphics& g); - TreeViewItem* findItemAt (int y, Rectangle& itemPosition) const; - - static bool isMouseDraggingInChildCompOf (Component* const comp) + void paint (Graphics& g) { - 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) + g.setOrigin (0, -owner.rootItem->itemHeight); - if (underMouse != 0 && (comp == underMouse || comp->isParentOf (underMouse))) - return true; - } + owner.rootItem->paintRecursively (g, getWidth()); + } + } + + TreeViewItem* findItemAt (int y, Rectangle& 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 false; + return 0; } void updateComponents() @@ -54491,8 +54503,8 @@ public: const int visibleBottom = visibleTop + getParentHeight(); 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) { @@ -54566,12 +54578,12 @@ public: { TreeViewItem* newItem = 0; - if (owner->openCloseButtonsVisible) + if (owner.openCloseButtonsVisible) { Rectangle 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; @@ -54598,14 +54610,14 @@ public: } } - bool isMouseOverButton (TreeViewItem* item) const throw() + bool isMouseOverButton (TreeViewItem* const item) const throw() { return item == buttonUnderMouse; } void resized() { - owner->itemsChanged(); + owner.itemsChanged(); } const String getTooltip() @@ -54616,30 +54628,26 @@ public: if (item != 0) return item->getTooltip(); - return owner->getTooltip(); + return owner.getTooltip(); } juce_UseDebuggingNewOperator private: - TreeView* const owner; - + TreeView& owner; Array rowComponentItems; Array rowComponentIds; Array rowComponents; TreeViewItem* buttonUnderMouse; bool isDragging, needSelectionOnMouseUp; - TreeViewContentComponent (const TreeViewContentComponent&); - TreeViewContentComponent& operator= (const TreeViewContentComponent&); - void selectBasedOnModifiers (TreeViewItem* const item, const ModifierKeys& modifiers) { 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); int rowStart = firstSelected->getRowNumberInTree(); @@ -54654,13 +54662,12 @@ private: swapVariables (ourRow, otherEnd); for (int i = ourRow; i <= otherEnd; ++i) - owner->getItemOnRow (i)->setSelected (true, false); + owner.getItemOnRow (i)->setSelected (true, false); } 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; } + + 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 { public: - TreeViewport() throw() {} - ~TreeViewport() throw() {} + TreeViewport() throw() : lastX (-1) {} + ~TreeViewport() throw() {} - void updateComponents() + void updateComponents (const bool triggerResize = false) { TreeViewContentComponent* const tvc = static_cast (getViewedComponent()); if (tvc != 0) - tvc->updateComponents(); + { + if (triggerResize) + tvc->resized(); + else + tvc->updateComponents(); + } 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 private: + int lastX; + TreeViewport (const TreeViewport&); TreeViewport& operator= (const TreeViewport&); }; @@ -54714,7 +54751,7 @@ TreeView::TreeView (const String& componentName) openCloseButtonsVisible (true) { addAndMakeVisible (viewport = new TreeViewport()); - viewport->setViewedComponent (new TreeViewContentComponent (this)); + viewport->setViewedComponent (new TreeViewContentComponent (*this)); viewport->setWantsKeyboardFocus (false); setWantsKeyboardFocus (true); } @@ -55340,39 +55377,6 @@ void TreeView::itemDropped (const String& sourceDescription, Component* sourceCo 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& 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 { opennessDefault = 0, @@ -55593,7 +55597,6 @@ void TreeViewItem::itemDropped (const String& /*sourceDescription*/, Component* const Rectangle TreeViewItem::getItemPosition (const bool relativeToTreeViewTopLeft) const throw() { const int indentX = getIndentX(); - int width = itemWidth; if (ownerView != 0 && width < 0) @@ -55602,8 +55605,7 @@ const Rectangle TreeViewItem::getItemPosition (const bool relativeToTreeVie Rectangle r (indentX, y, jmax (0, width), totalHeight); if (relativeToTreeViewTopLeft) - r.setPosition (r.getX() - ownerView->viewport->getViewPositionX(), - r.getY() - ownerView->viewport->getViewPositionY()); + r -= ownerView->viewport->getViewPosition(); return r; } @@ -56536,6 +56538,11 @@ const File FileBrowserComponent::getHighlightedFile() const throw() return fileListComponent->getSelectedFile (0); } +void FileBrowserComponent::deselectAllFiles() +{ + fileListComponent->deselectAllFiles(); +} + bool FileBrowserComponent::isFileSuitable (const File& file) const { 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)); } +void FileListComponent::deselectAllFiles() +{ + deselectAllRows(); +} + void FileListComponent::scrollToTop() { getVerticalScrollBar()->setCurrentRangeStart (0); @@ -58097,10 +58109,13 @@ const File FileTreeComponent::getSelectedFile (const int index) const { const FileListTreeItem* const item = dynamic_cast (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() @@ -62786,10 +62801,6 @@ BEGIN_JUCE_NAMESPACE Viewport::Viewport (const String& componentName) : Component (componentName), contentComp (0), - lastVX (0), - lastVY (0), - lastVW (0), - lastVH (0), scrollBarThickness (0), singleStepX (16), singleStepY (16), @@ -62855,16 +62866,14 @@ int Viewport::getMaximumVisibleHeight() const throw() 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) contentComp->setTopLeftPosition (-xPixelsOffset, -yPixelsOffset); } -void Viewport::setViewPositionProportionately (const double x, - const double y) +void Viewport::setViewPositionProportionately (const double x, const double y) { if (contentComp != 0) 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; - 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) { @@ -62923,10 +62938,10 @@ void Viewport::updateVisibleRegion() { if (contentComp != 0) { - const int newVX = -contentComp->getX(); - const int newVY = -contentComp->getY(); + Rectangle newViewPos; + newViewPos.setPosition (-contentComp->getPosition()); - if (newVX == 0 && newVY == 0 + if (newViewPos.getX() == 0 && newViewPos.getY() == 0 && contentComp->getWidth() <= getWidth() && contentComp->getHeight() <= getHeight()) { @@ -62935,14 +62950,14 @@ void Viewport::updateVisibleRegion() } horizontalScrollBar->setRangeLimits (0.0, contentComp->getWidth()); - horizontalScrollBar->setCurrentRange (newVX, getMaximumVisibleWidth()); + horizontalScrollBar->setCurrentRange (newViewPos.getX(), getMaximumVisibleWidth()); horizontalScrollBar->setSingleStepSize (singleStepX); if (! (contentComp->getWidth() > 0 && showHScrollbar && getHeight() > getScrollBarThickness())) horizontalScrollBar->setVisible (! horizontalScrollBar->autoHides()); verticalScrollBar->setRangeLimits (0.0, contentComp->getHeight()); - verticalScrollBar->setCurrentRange (newVY, getMaximumVisibleHeight()); + verticalScrollBar->setCurrentRange (newViewPos.getY(), getMaximumVisibleHeight()); verticalScrollBar->setSingleStepSize (singleStepY); if (! (contentComp->getHeight() > 0 && showVScrollbar && getWidth() > getScrollBarThickness())) @@ -62950,8 +62965,8 @@ void Viewport::updateVisibleRegion() if (verticalScrollBar->isVisible()) { - horizontalScrollBar->setCurrentRange (newVX, getMaximumVisibleWidth()); - verticalScrollBar->setCurrentRange (newVY, getMaximumVisibleHeight()); + horizontalScrollBar->setCurrentRange (newViewPos.getX(), getMaximumVisibleWidth()); + verticalScrollBar->setCurrentRange (newViewPos.getY(), getMaximumVisibleHeight()); verticalScrollBar ->setBounds (getMaximumVisibleWidth(), 0, @@ -62960,7 +62975,7 @@ void Viewport::updateVisibleRegion() if (horizontalScrollBar->isVisible()) { - horizontalScrollBar->setCurrentRange (newVX, getMaximumVisibleWidth()); + horizontalScrollBar->setCurrentRange (newViewPos.getX(), getMaximumVisibleWidth()); horizontalScrollBar ->setBounds (0, getMaximumVisibleHeight(), @@ -62970,20 +62985,13 @@ void Viewport::updateVisibleRegion() contentHolder->setSize (getMaximumVisibleWidth(), 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(); @@ -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; singleStepY = stepY; @@ -247175,27 +247182,32 @@ public: { const KeyPress& kp = keyPresses.getReference(0); - juce_wchar key = kp.getTextCharacter(); + 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(); + 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; + 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]; + [item setKeyEquivalent: juceStringToNS (String::charToString (key))]; + [item setKeyEquivalentModifierMask: mods]; + } } } } diff --git a/juce_amalgamated.h b/juce_amalgamated.h index e05a6855a8..59abc10b04 100644 --- a/juce_amalgamated.h +++ b/juce_amalgamated.h @@ -5035,7 +5035,7 @@ public: if (this != &other) { ReferenceCountedArray otherCopy (other); - swapWithArray (other); + swapWithArray (otherCopy); } return *this; @@ -10363,11 +10363,23 @@ public: return Rectangle (x + deltaPosition.getX(), y + deltaPosition.getY(), w, h); } + Rectangle& operator+= (const Point& deltaPosition) throw() + { + x += deltaPosition.getX(); y += deltaPosition.getY(); + return *this; + } + const Rectangle operator- (const Point& deltaPosition) const throw() { return Rectangle (x - deltaPosition.getX(), y - deltaPosition.getY(), w, h); } + Rectangle& operator-= (const Point& deltaPosition) throw() + { + x -= deltaPosition.getX(); y -= deltaPosition.getY(); + return *this; + } + void expand (const ValueType deltaX, const ValueType deltaY) throw() { @@ -16449,13 +16461,15 @@ public: bool autoScroll (int mouseX, int mouseY, int distanceFromEdge, int maximumSpeed); - int getViewPositionX() const throw() { return lastVX; } + const Point getViewPosition() const throw() { return lastViewPos.getPosition(); } - int getViewPositionY() const throw() { return lastVY; } + int getViewPositionX() const throw() { return lastViewPos.getX(); } - int getViewWidth() const throw() { return lastVW; } + int getViewPositionY() const throw() { return lastViewPos.getY(); } - int getViewHeight() const throw() { return lastVH; } + int getViewWidth() const throw() { return lastViewPos.getWidth(); } + + int getViewHeight() const throw() { return lastViewPos.getHeight(); } int getMaximumVisibleWidth() const throw(); @@ -16494,7 +16508,7 @@ public: private: Component::SafePointer contentComp; - int lastVX, lastVY, lastVW, lastVH; + Rectangle lastViewPos; int scrollBarThickness; int singleStepX, singleStepY; bool showHScrollbar, showVScrollbar; @@ -16503,6 +16517,7 @@ private: ScrollBar* horizontalScrollBar; void updateVisibleRegion(); + Viewport (const Viewport&); Viewport& operator= (const Viewport&); }; @@ -22620,6 +22635,8 @@ public: virtual const File getSelectedFile (int index) const = 0; + virtual void deselectAllFiles() = 0; + virtual void scrollToTop() = 0; void addListener (FileBrowserListener* listener); @@ -22721,6 +22738,8 @@ public: const File getSelectedFile (int index) const throw(); + void deselectAllFiles(); + bool currentFileIsValid() const; const File getHighlightedFile() const throw(); @@ -23530,6 +23549,8 @@ public: const File getSelectedFile (int index = 0) const; + void deselectAllFiles(); + void scrollToTop(); void changeListenerCallback (void*); @@ -23740,6 +23761,8 @@ public: const File getSelectedFile (int index = 0) const; + void deselectAllFiles(); + void scrollToTop(); void setDragAndDropDescription (const String& description); @@ -25890,7 +25913,7 @@ public: virtual ~LassoSource() {} virtual void findLassoItemsInArea (Array & itemsFound, - int x, int y, int width, int height) = 0; + const Rectangle& area) = 0; virtual SelectedItemSet & getLassoSelection() = 0; }; @@ -25923,17 +25946,18 @@ public: originalSelection = lassoSource->getLassoSelection().getItemArray(); setSize (0, 0); + dragStartPos = e.getMouseDownPosition(); } void dragLasso (const MouseEvent& e) { if (source != 0) { - setBounds (Rectangle (e.getMouseDownPosition(), e.getPosition())); + setBounds (Rectangle (dragStartPos, e.getPosition())); setVisible (true); Array itemsInLasso; - source->findLassoItemsInArea (itemsInLasso, getX(), getY(), getWidth(), getHeight()); + source->findLassoItemsInArea (itemsInLasso, getBounds()); if (e.mods.isShiftDown()) { @@ -25987,6 +26011,7 @@ private: Array originalSelection; LassoSource * source; int outlineThickness; + Point dragStartPos; }; #endif // __JUCE_LASSOCOMPONENT_JUCEHEADER__ diff --git a/src/audio/processors/juce_AudioProcessor.cpp b/src/audio/processors/juce_AudioProcessor.cpp index 73cee0dc2d..996001b49d 100644 --- a/src/audio/processors/juce_AudioProcessor.cpp +++ b/src/audio/processors/juce_AudioProcessor.cpp @@ -277,7 +277,7 @@ XmlElement* AudioProcessor::getXmlFromBinary (const void* data, const int sizeInBytes) { if (sizeInBytes > 8 - && ByteOrder::littleEndianInt ((const char*) data) == magicXmlNumber) + && ByteOrder::littleEndianInt (data) == magicXmlNumber) { const int stringLength = (int) ByteOrder::littleEndianInt (((const char*) data) + 4); diff --git a/src/containers/juce_ReferenceCountedArray.h b/src/containers/juce_ReferenceCountedArray.h index bca4c3b9d7..331529a145 100644 --- a/src/containers/juce_ReferenceCountedArray.h +++ b/src/containers/juce_ReferenceCountedArray.h @@ -80,7 +80,7 @@ public: if (this != &other) { ReferenceCountedArray otherCopy (other); - swapWithArray (other); + swapWithArray (otherCopy); } return *this; diff --git a/src/gui/components/controls/juce_TreeView.cpp b/src/gui/components/controls/juce_TreeView.cpp index ad2351bda1..5c1b1df568 100644 --- a/src/gui/components/controls/juce_TreeView.cpp +++ b/src/gui/components/controls/juce_TreeView.cpp @@ -40,7 +40,7 @@ class TreeViewContentComponent : public Component, public TooltipClient { public: - TreeViewContentComponent (TreeView* const owner_) + TreeViewContentComponent (TreeView& owner_) : owner (owner_), buttonUnderMouse (0), isDragging (false) @@ -67,9 +67,9 @@ public: // (if the open/close buttons are hidden, we'll treat clicks to the left of the item // 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()); // (clicks to the left of an open/close button are ignored) @@ -77,7 +77,7 @@ public: else { // mouse-down inside the body of the item.. - if (! owner->isMultiSelectEnabled()) + if (! owner.isMultiSelectEnabled()) item->setSelected (true, true); else if (item->isSelected()) needSelectionOnMouseUp = ! e.mods.isPopupMenu(); @@ -110,7 +110,7 @@ public: Rectangle 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())); } } @@ -143,7 +143,7 @@ public: dragImage->multiplyAllAlphas (0.6f); Point imageOffset (pos.getX() - e.x, pos.getY() - e.y); - dragContainer->startDragging (dragDescription, owner, dragImage, true, &imageOffset); + dragContainer->startDragging (dragDescription, &owner, dragImage, true, &imageOffset); } else { @@ -166,25 +166,37 @@ public: updateButtonUnderMouse (e); } - void paint (Graphics& g); - TreeViewItem* findItemAt (int y, Rectangle& itemPosition) const; - - static bool isMouseDraggingInChildCompOf (Component* const comp) + void paint (Graphics& g) { - 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) + g.setOrigin (0, -owner.rootItem->itemHeight); - if (underMouse != 0 && (comp == underMouse || comp->isParentOf (underMouse))) - return true; - } + owner.rootItem->paintRecursively (g, getWidth()); + } + } + + TreeViewItem* findItemAt (int y, Rectangle& 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 false; + return 0; } void updateComponents() @@ -193,8 +205,8 @@ public: const int visibleBottom = visibleTop + getParentHeight(); 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) { @@ -268,12 +280,12 @@ public: { TreeViewItem* newItem = 0; - if (owner->openCloseButtonsVisible) + if (owner.openCloseButtonsVisible) { Rectangle 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; @@ -300,14 +312,14 @@ public: } } - bool isMouseOverButton (TreeViewItem* item) const throw() + bool isMouseOverButton (TreeViewItem* const item) const throw() { return item == buttonUnderMouse; } void resized() { - owner->itemsChanged(); + owner.itemsChanged(); } const String getTooltip() @@ -318,31 +330,27 @@ public: if (item != 0) return item->getTooltip(); - return owner->getTooltip(); + return owner.getTooltip(); } //============================================================================== juce_UseDebuggingNewOperator private: - TreeView* const owner; - + TreeView& owner; Array rowComponentItems; Array rowComponentIds; Array rowComponents; TreeViewItem* buttonUnderMouse; bool isDragging, needSelectionOnMouseUp; - TreeViewContentComponent (const TreeViewContentComponent&); - TreeViewContentComponent& operator= (const TreeViewContentComponent&); - void selectBasedOnModifiers (TreeViewItem* const item, const ModifierKeys& modifiers) { 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); int rowStart = firstSelected->getRowNumberInTree(); @@ -357,13 +365,12 @@ private: swapVariables (ourRow, otherEnd); for (int i = ourRow; i <= otherEnd; ++i) - owner->getItemOnRow (i)->setSelected (true, false); + owner.getItemOnRow (i)->setSelected (true, false); } 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; } + + 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 { public: - TreeViewport() throw() {} - ~TreeViewport() throw() {} + TreeViewport() throw() : lastX (-1) {} + ~TreeViewport() throw() {} - void updateComponents() + void updateComponents (const bool triggerResize = false) { TreeViewContentComponent* const tvc = static_cast (getViewedComponent()); if (tvc != 0) - tvc->updateComponents(); + { + if (triggerResize) + tvc->resized(); + else + tvc->updateComponents(); + } 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 private: + int lastX; + TreeViewport (const TreeViewport&); TreeViewport& operator= (const TreeViewport&); }; @@ -421,7 +458,7 @@ TreeView::TreeView (const String& componentName) openCloseButtonsVisible (true) { addAndMakeVisible (viewport = new TreeViewport()); - viewport->setViewedComponent (new TreeViewContentComponent (this)); + viewport->setViewedComponent (new TreeViewContentComponent (*this)); viewport->setWantsKeyboardFocus (false); setWantsKeyboardFocus (true); } @@ -1054,40 +1091,6 @@ void TreeView::itemDropped (const String& sourceDescription, Component* sourceCo 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& 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 { @@ -1309,7 +1312,6 @@ void TreeViewItem::itemDropped (const String& /*sourceDescription*/, Component* const Rectangle TreeViewItem::getItemPosition (const bool relativeToTreeViewTopLeft) const throw() { const int indentX = getIndentX(); - int width = itemWidth; if (ownerView != 0 && width < 0) @@ -1318,8 +1320,7 @@ const Rectangle TreeViewItem::getItemPosition (const bool relativeToTreeVie Rectangle r (indentX, y, jmax (0, width), totalHeight); if (relativeToTreeViewTopLeft) - r.setPosition (r.getX() - ownerView->viewport->getViewPositionX(), - r.getY() - ownerView->viewport->getViewPositionY()); + r -= ownerView->viewport->getViewPosition(); return r; } diff --git a/src/gui/components/filebrowser/juce_DirectoryContentsDisplayComponent.h b/src/gui/components/filebrowser/juce_DirectoryContentsDisplayComponent.h index 14fb26ccac..103620b6f5 100644 --- a/src/gui/components/filebrowser/juce_DirectoryContentsDisplayComponent.h +++ b/src/gui/components/filebrowser/juce_DirectoryContentsDisplayComponent.h @@ -59,6 +59,9 @@ public: */ virtual const File getSelectedFile (int index) const = 0; + /** Deselects any selected files. */ + virtual void deselectAllFiles() = 0; + /** Scrolls this view to the top. */ virtual void scrollToTop() = 0; diff --git a/src/gui/components/filebrowser/juce_FileBrowserComponent.cpp b/src/gui/components/filebrowser/juce_FileBrowserComponent.cpp index b264ebc209..abf1d46975 100644 --- a/src/gui/components/filebrowser/juce_FileBrowserComponent.cpp +++ b/src/gui/components/filebrowser/juce_FileBrowserComponent.cpp @@ -195,6 +195,11 @@ const File FileBrowserComponent::getHighlightedFile() const throw() return fileListComponent->getSelectedFile (0); } +void FileBrowserComponent::deselectAllFiles() +{ + fileListComponent->deselectAllFiles(); +} + //============================================================================== bool FileBrowserComponent::isFileSuitable (const File& file) const { diff --git a/src/gui/components/filebrowser/juce_FileBrowserComponent.h b/src/gui/components/filebrowser/juce_FileBrowserComponent.h index 0dcf21bd07..7d782db227 100644 --- a/src/gui/components/filebrowser/juce_FileBrowserComponent.h +++ b/src/gui/components/filebrowser/juce_FileBrowserComponent.h @@ -114,6 +114,10 @@ public: */ 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. This can be used to decide whether the user can press "ok" for the diff --git a/src/gui/components/filebrowser/juce_FileListComponent.cpp b/src/gui/components/filebrowser/juce_FileListComponent.cpp index 84c91d7eb4..4e0038006a 100644 --- a/src/gui/components/filebrowser/juce_FileListComponent.cpp +++ b/src/gui/components/filebrowser/juce_FileListComponent.cpp @@ -60,6 +60,11 @@ const File FileListComponent::getSelectedFile (int index) const return fileList.getFile (getSelectedRow (index)); } +void FileListComponent::deselectAllFiles() +{ + deselectAllRows(); +} + void FileListComponent::scrollToTop() { getVerticalScrollBar()->setCurrentRangeStart (0); diff --git a/src/gui/components/filebrowser/juce_FileListComponent.h b/src/gui/components/filebrowser/juce_FileListComponent.h index c34018411a..dd58e4c5e9 100644 --- a/src/gui/components/filebrowser/juce_FileListComponent.h +++ b/src/gui/components/filebrowser/juce_FileListComponent.h @@ -70,6 +70,9 @@ public: */ const File getSelectedFile (int index = 0) const; + /** Deselects any files that are currently selected. */ + void deselectAllFiles(); + /** Scrolls to the top of the list. */ void scrollToTop(); diff --git a/src/gui/components/filebrowser/juce_FileTreeComponent.cpp b/src/gui/components/filebrowser/juce_FileTreeComponent.cpp index 8a2ba0ea09..7aa7fb0a3f 100644 --- a/src/gui/components/filebrowser/juce_FileTreeComponent.cpp +++ b/src/gui/components/filebrowser/juce_FileTreeComponent.cpp @@ -250,10 +250,13 @@ const File FileTreeComponent::getSelectedFile (const int index) const { const FileListTreeItem* const item = dynamic_cast (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() diff --git a/src/gui/components/filebrowser/juce_FileTreeComponent.h b/src/gui/components/filebrowser/juce_FileTreeComponent.h index 4f7ea2c61d..5595497cc8 100644 --- a/src/gui/components/filebrowser/juce_FileTreeComponent.h +++ b/src/gui/components/filebrowser/juce_FileTreeComponent.h @@ -66,6 +66,9 @@ public: */ const File getSelectedFile (int index = 0) const; + /** Deselects any files that are currently selected. */ + void deselectAllFiles(); + /** Scrolls the list to the top. */ void scrollToTop(); diff --git a/src/gui/components/layout/juce_Viewport.cpp b/src/gui/components/layout/juce_Viewport.cpp index 7ae5e60d72..924b390b35 100644 --- a/src/gui/components/layout/juce_Viewport.cpp +++ b/src/gui/components/layout/juce_Viewport.cpp @@ -35,10 +35,6 @@ BEGIN_JUCE_NAMESPACE Viewport::Viewport (const String& componentName) : Component (componentName), contentComp (0), - lastVX (0), - lastVY (0), - lastVW (0), - lastVH (0), scrollBarThickness (0), singleStepX (16), singleStepY (16), @@ -106,16 +102,14 @@ int Viewport::getMaximumVisibleHeight() const throw() 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) contentComp->setTopLeftPosition (-xPixelsOffset, -yPixelsOffset); } -void Viewport::setViewPositionProportionately (const double x, - const double y) +void Viewport::setViewPositionProportionately (const double x, const double y) { if (contentComp != 0) 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; - 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) { @@ -176,10 +176,10 @@ void Viewport::updateVisibleRegion() { if (contentComp != 0) { - const int newVX = -contentComp->getX(); - const int newVY = -contentComp->getY(); + Rectangle newViewPos; + newViewPos.setPosition (-contentComp->getPosition()); - if (newVX == 0 && newVY == 0 + if (newViewPos.getX() == 0 && newViewPos.getY() == 0 && contentComp->getWidth() <= getWidth() && contentComp->getHeight() <= getHeight()) { @@ -188,14 +188,14 @@ void Viewport::updateVisibleRegion() } horizontalScrollBar->setRangeLimits (0.0, contentComp->getWidth()); - horizontalScrollBar->setCurrentRange (newVX, getMaximumVisibleWidth()); + horizontalScrollBar->setCurrentRange (newViewPos.getX(), getMaximumVisibleWidth()); horizontalScrollBar->setSingleStepSize (singleStepX); if (! (contentComp->getWidth() > 0 && showHScrollbar && getHeight() > getScrollBarThickness())) horizontalScrollBar->setVisible (! horizontalScrollBar->autoHides()); verticalScrollBar->setRangeLimits (0.0, contentComp->getHeight()); - verticalScrollBar->setCurrentRange (newVY, getMaximumVisibleHeight()); + verticalScrollBar->setCurrentRange (newViewPos.getY(), getMaximumVisibleHeight()); verticalScrollBar->setSingleStepSize (singleStepY); if (! (contentComp->getHeight() > 0 && showVScrollbar && getWidth() > getScrollBarThickness())) @@ -203,8 +203,8 @@ void Viewport::updateVisibleRegion() if (verticalScrollBar->isVisible()) { - horizontalScrollBar->setCurrentRange (newVX, getMaximumVisibleWidth()); - verticalScrollBar->setCurrentRange (newVY, getMaximumVisibleHeight()); + horizontalScrollBar->setCurrentRange (newViewPos.getX(), getMaximumVisibleWidth()); + verticalScrollBar->setCurrentRange (newViewPos.getY(), getMaximumVisibleHeight()); verticalScrollBar ->setBounds (getMaximumVisibleWidth(), 0, @@ -213,7 +213,7 @@ void Viewport::updateVisibleRegion() if (horizontalScrollBar->isVisible()) { - horizontalScrollBar->setCurrentRange (newVX, getMaximumVisibleWidth()); + horizontalScrollBar->setCurrentRange (newViewPos.getX(), getMaximumVisibleWidth()); horizontalScrollBar ->setBounds (0, getMaximumVisibleHeight(), @@ -223,20 +223,13 @@ void Viewport::updateVisibleRegion() contentHolder->setSize (getMaximumVisibleWidth(), 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(); @@ -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; singleStepY = stepY; diff --git a/src/gui/components/layout/juce_Viewport.h b/src/gui/components/layout/juce_Viewport.h index b18cd21ad2..5ed7477904 100644 --- a/src/gui/components/layout/juce_Viewport.h +++ b/src/gui/components/layout/juce_Viewport.h @@ -119,29 +119,33 @@ public: */ 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 getViewPosition() const throw() { return lastViewPos.getPosition(); } + /** Returns the position within the child component of the top-left of its visible area. @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. @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. This may be less than the width of this Viewport if there's a vertical scrollbar 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. This may be less than the height of this Viewport if there's a horizontal scrollbar 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. @@ -241,7 +245,7 @@ public: private: Component::SafePointer contentComp; - int lastVX, lastVY, lastVW, lastVH; + Rectangle lastViewPos; int scrollBarThickness; int singleStepX, singleStepY; bool showHScrollbar, showVScrollbar; @@ -250,6 +254,7 @@ private: ScrollBar* horizontalScrollBar; void updateVisibleRegion(); + Viewport (const Viewport&); Viewport& operator= (const Viewport&); }; diff --git a/src/gui/components/mouse/juce_LassoComponent.h b/src/gui/components/mouse/juce_LassoComponent.h index 8e80cc1125..0c40410547 100644 --- a/src/gui/components/mouse/juce_LassoComponent.h +++ b/src/gui/components/mouse/juce_LassoComponent.h @@ -56,7 +56,7 @@ public: component itself). */ virtual void findLassoItemsInArea (Array & itemsFound, - int x, int y, int width, int height) = 0; + const Rectangle& area) = 0; /** Returns the SelectedItemSet that the lasso should update. @@ -141,6 +141,7 @@ public: originalSelection = lassoSource->getLassoSelection().getItemArray(); setSize (0, 0); + dragStartPos = e.getMouseDownPosition(); } /** Call this in your mouseDrag event, to update the lasso's position. @@ -159,11 +160,11 @@ public: { if (source != 0) { - setBounds (Rectangle (e.getMouseDownPosition(), e.getPosition())); + setBounds (Rectangle (dragStartPos, e.getPosition())); setVisible (true); Array itemsInLasso; - source->findLassoItemsInArea (itemsInLasso, getX(), getY(), getWidth(), getHeight()); + source->findLassoItemsInArea (itemsInLasso, getBounds()); if (e.mods.isShiftDown()) { @@ -236,6 +237,7 @@ private: Array originalSelection; LassoSource * source; int outlineThickness; + Point dragStartPos; }; diff --git a/src/gui/graphics/geometry/juce_Rectangle.h b/src/gui/graphics/geometry/juce_Rectangle.h index 031931a8d8..4dce382fe9 100644 --- a/src/gui/graphics/geometry/juce_Rectangle.h +++ b/src/gui/graphics/geometry/juce_Rectangle.h @@ -233,12 +233,26 @@ public: return Rectangle (x + deltaPosition.getX(), y + deltaPosition.getY(), w, h); } + /** Moves this rectangle by a given amount. */ + Rectangle& operator+= (const Point& 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. */ const Rectangle operator- (const Point& deltaPosition) const throw() { return Rectangle (x - deltaPosition.getX(), y - deltaPosition.getY(), w, h); } + /** Moves this rectangle by a given amount. */ + Rectangle& operator-= (const Point& deltaPosition) throw() + { + x -= deltaPosition.getX(); y -= deltaPosition.getY(); + return *this; + } + /** Expands the rectangle by a given amount. Effectively, its new size is (x - deltaX, y - deltaY, w + deltaX * 2, h + deltaY * 2). diff --git a/src/native/mac/juce_mac_MainMenu.mm b/src/native/mac/juce_mac_MainMenu.mm index 297c53989a..cb6b5d2eeb 100644 --- a/src/native/mac/juce_mac_MainMenu.mm +++ b/src/native/mac/juce_mac_MainMenu.mm @@ -302,27 +302,32 @@ public: { const KeyPress& kp = keyPresses.getReference(0); - juce_wchar key = kp.getTextCharacter(); + 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(); + 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; + 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]; + [item setKeyEquivalent: juceStringToNS (String::charToString (key))]; + [item setKeyEquivalentModifierMask: mods]; + } } } }