diff --git a/extras/Jucer (experimental)/Source/model/jucer_ComponentDocument.cpp b/extras/Jucer (experimental)/Source/model/jucer_ComponentDocument.cpp index 626071e1ad..9e16f95b67 100644 --- a/extras/Jucer (experimental)/Source/model/jucer_ComponentDocument.cpp +++ b/extras/Jucer (experimental)/Source/model/jucer_ComponentDocument.cpp @@ -329,9 +329,9 @@ public: DragHandler (ComponentDocument& document_, const Array& items, const MouseEvent& e, - int zones_) + const ResizableBorderComponent::Zone& zone_) : document (document_), - zones (zones_) + zone (zone_) { for (int i = 0; i < items.size(); ++i) { @@ -349,48 +349,25 @@ public: void drag (const MouseEvent& e) { for (int i = 0; i < draggedComponents.size(); ++i) - { - if (zones == 0) - move (draggedComponents.getReference(i), e.getOffsetFromDragStart(), originalPositions.getReference(i)); - else - resize (draggedComponents.getReference(i), e.getOffsetFromDragStart(), originalPositions.getReference(i)); - } + move (draggedComponents.getReference(i), e.getOffsetFromDragStart(), originalPositions.getReference(i)); } void move (ValueTree& v, const Point& distance, const Rectangle& originalPos) { - v.setProperty (compBoundsProperty, componentBoundsToString (originalPos + distance), document.getUndoManager()); - } - - void resize (ValueTree& v, const Point& distance, const Rectangle& originalPos) - { - Rectangle r (originalPos); - - if ((zones & zoneL) != 0) - r.setLeft (r.getX() + distance.getX()); - - if ((zones & zoneT) != 0) - r.setTop (r.getY() + distance.getY()); - - if ((zones & zoneR) != 0) - r.setWidth (r.getWidth() + distance.getX()); - - if ((zones & zoneB) != 0) - r.setHeight (r.getHeight() + distance.getY()); - - v.setProperty (compBoundsProperty, componentBoundsToString (r), document.getUndoManager()); + Rectangle newBounds (zone.resizeRectangleBy (originalPos, distance)); + v.setProperty (compBoundsProperty, componentBoundsToString (newBounds), document.getUndoManager()); } private: ComponentDocument& document; Array draggedComponents; Array > originalPositions; - const int zones; + const ResizableBorderComponent::Zone zone; }; -void ComponentDocument::beginDrag (const Array& items, const MouseEvent& e, int zones) +void ComponentDocument::beginDrag (const Array& items, const MouseEvent& e, const ResizableBorderComponent::Zone& zone) { - dragger = new DragHandler (*this, items, e, zones); + dragger = new DragHandler (*this, items, e, zone); } void ComponentDocument::continueDrag (const MouseEvent& e) diff --git a/extras/Jucer (experimental)/Source/model/jucer_ComponentDocument.h b/extras/Jucer (experimental)/Source/model/jucer_ComponentDocument.h index a172ccb091..12ec77bda0 100644 --- a/extras/Jucer (experimental)/Source/model/jucer_ComponentDocument.h +++ b/extras/Jucer (experimental)/Source/model/jucer_ComponentDocument.h @@ -67,7 +67,8 @@ public: zoneB = 8 }; - void beginDrag (const Array& items, const MouseEvent& e, int zones); + void beginDrag (const Array& items, const MouseEvent& e, + const ResizableBorderComponent::Zone& zone); void continueDrag (const MouseEvent& e); void endDrag (const MouseEvent& e); 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 0f4d81496b..d1e35fa22e 100644 --- a/extras/Jucer (experimental)/Source/ui/Component Editor/jucer_ComponentEditor.cpp +++ b/extras/Jucer (experimental)/Source/ui/Component Editor/jucer_ComponentEditor.cpp @@ -33,7 +33,7 @@ class ComponentCanvas : public Component, { public: ComponentCanvas (ComponentEditor& editor_) - : editor (editor_) + : editor (editor_), borderThickness (4) { setOpaque (true); addAndMakeVisible (componentHolder = new Component()); @@ -54,12 +54,16 @@ public: void paint (Graphics& g) { g.fillAll (Colours::white); + g.setColour (Colour::greyLevel (0.9f)); + g.drawRect (0, 0, getWidth(), getHeight(), borderThickness); } void resized() { - componentHolder->setSize (getWidth(), getHeight()); - overlay->setSize (getWidth(), getHeight()); + componentHolder->setBounds (borderThickness, borderThickness, + getWidth() - borderThickness * 2, getHeight() - borderThickness * 2); + + overlay->setBounds (componentHolder->getBounds()); } void zoom (float newScale, const Point& centre) @@ -151,6 +155,7 @@ public: private: ComponentEditor& editor; + const int borderThickness; //============================================================================== class ComponentResizeFrame : public Component, @@ -237,54 +242,24 @@ private: private: ComponentCanvas& canvas; Component::SafePointer component; - int dragZone; + ResizableBorderComponent::Zone dragZone; const int borderThickness; const Rectangle getCentreArea() const { - return Rectangle (0, 0, getWidth(), getHeight()).reduced (borderThickness, borderThickness); + return getLocalBounds().reduced (borderThickness, borderThickness); } void updateDragZone (const Point& p) { - int newZone = 0; - - if (! getCentreArea().contains (p)) - { - const int bw = jmax (borderThickness, proportionOfWidth (0.1f), jmin (10, proportionOfWidth (0.33f))); - const int bh = jmax (borderThickness, proportionOfHeight (0.1f), jmin (10, proportionOfHeight (0.33f))); - - if (p.getX() < bw) - newZone |= ComponentDocument::zoneL; - else if (p.getX() >= getWidth() - bw) - newZone |= ComponentDocument::zoneR; - - if (p.getY() < bh) - newZone |= ComponentDocument::zoneT; - else if (p.getY() >= getHeight() - bh) - newZone |= ComponentDocument::zoneB; - } + ResizableBorderComponent::Zone newZone + = ResizableBorderComponent::Zone::fromPositionOnBorder (getLocalBounds(), + BorderSize (borderThickness), p); if (dragZone != newZone) { dragZone = newZone; - - MouseCursor::StandardCursorType mc = MouseCursor::NormalCursor; - - switch (newZone) - { - case (ComponentDocument::zoneL | ComponentDocument::zoneT): mc = MouseCursor::TopLeftCornerResizeCursor; break; - case ComponentDocument::zoneT: mc = MouseCursor::TopEdgeResizeCursor; break; - case (ComponentDocument::zoneR | ComponentDocument::zoneT): mc = MouseCursor::TopRightCornerResizeCursor; break; - case ComponentDocument::zoneL: mc = MouseCursor::LeftEdgeResizeCursor; break; - case ComponentDocument::zoneR: mc = MouseCursor::RightEdgeResizeCursor; break; - case (ComponentDocument::zoneL | ComponentDocument::zoneB): mc = MouseCursor::BottomLeftCornerResizeCursor; break; - case ComponentDocument::zoneB: mc = MouseCursor::BottomEdgeResizeCursor; break; - case (ComponentDocument::zoneR | ComponentDocument::zoneB): mc = MouseCursor::BottomRightCornerResizeCursor; break; - default: mc = MouseCursor::NormalCursor; break; - } - - setMouseCursor (mc); + setMouseCursor (newZone.getMouseCursor()); } } }; @@ -357,7 +332,8 @@ private: { isDraggingClickedComp = true; canvas.getSelection().addToSelectionOnMouseUp (mouseDownCompUID, e.mods, true, mouseDownResult); - canvas.getDocument().beginDrag (canvas.getSelectedComps(), e, 0); + canvas.getDocument().beginDrag (canvas.getSelectedComps(), e, + ResizableBorderComponent::Zone (ResizableBorderComponent::Zone::centre)); } canvas.getDocument().continueDrag (e); diff --git a/juce_amalgamated.cpp b/juce_amalgamated.cpp index 7da0e2b63e..8eb6f64859 100644 --- a/juce_amalgamated.cpp +++ b/juce_amalgamated.cpp @@ -10497,7 +10497,7 @@ namespace NumberToStringConverters else { #if JUCE_WIN32 - #if _MSC_VER <= 1200 + #if _MSC_VER <= 1400 len = _snwprintf (buffer, numChars, L"%.9g", n); #else len = _snwprintf_s (buffer, numChars, _TRUNCATE, L"%.9g", n); @@ -38363,7 +38363,7 @@ public: alpha (1.0f), scale (1.0f) { - image = comp->createComponentSnapshot (Rectangle (0, 0, comp->getWidth(), comp->getHeight())); + image = comp->createComponentSnapshot (comp->getLocalBounds()); setBounds (comp->getBounds()); comp->getParentComponent()->addAndMakeVisible (this); toBehind (comp); @@ -39811,7 +39811,7 @@ Image* Component::createComponentSnapshot (const Rectangle& areaToGrab, Rectangle r (areaToGrab); if (clipImageToComponentBounds) - r = r.getIntersection (Rectangle (0, 0, getWidth(), getHeight())); + r = r.getIntersection (getLocalBounds()); ScopedPointer componentImage (Image::createNativeImage (flags.opaqueFlag ? Image::RGB : Image::ARGB, jmax (1, r.getWidth()), @@ -39946,6 +39946,11 @@ void Component::colourChanged() { } +const Rectangle Component::getLocalBounds() const throw() +{ + return Rectangle (0, 0, getWidth(), getHeight()); +} + const Rectangle Component::getUnclippedArea() const { int x = 0, y = 0, w = getWidth(), h = getHeight(); @@ -39995,8 +40000,7 @@ void Component::clipObscuredRegions (Graphics& g, const Rectangle& clipRect } } -void Component::getVisibleArea (RectangleList& result, - const bool includeSiblings) const +void Component::getVisibleArea (RectangleList& result, const bool includeSiblings) const { result.clear(); const Rectangle unclipped (getUnclippedArea()); @@ -40010,8 +40014,7 @@ void Component::getVisibleArea (RectangleList& result, const Component* const c = getTopLevelComponent(); c->subtractObscuredRegions (result, c->relativePositionToOtherComponent (this, Point()), - Rectangle (0, 0, c->getWidth(), c->getHeight()), - this); + c->getLocalBounds(), this); } subtractObscuredRegions (result, Point(), unclipped, 0); @@ -47658,7 +47661,7 @@ Image* ListBox::createSnapshotOfSelectedRows (int& imageX, int& imageY) } } - imageArea = imageArea.getIntersection (Rectangle (0, 0, getWidth(), getHeight())); + imageArea = imageArea.getIntersection (getLocalBounds()); imageX = imageArea.getX(); imageY = imageArea.getY(); Image* snapshot = Image::createNativeImage (Image::ARGB, imageArea.getWidth(), imageArea.getHeight(), true); @@ -60865,13 +60868,80 @@ END_JUCE_NAMESPACE /*** Start of inlined file: juce_ResizableBorderComponent.cpp ***/ BEGIN_JUCE_NAMESPACE -enum ResizableBorderComponentZones +ResizableBorderComponent::Zone::Zone (int zoneFlags) throw() + : zone (zoneFlags) { - zoneL = 1, - zoneR = 2, - zoneT = 4, - zoneB = 8 -}; +} + +ResizableBorderComponent::Zone::Zone (const ResizableBorderComponent::Zone& other) throw() : zone (other.zone) {} +ResizableBorderComponent::Zone& ResizableBorderComponent::Zone::operator= (const ResizableBorderComponent::Zone& other) throw() { zone = other.zone; return *this; } +bool ResizableBorderComponent::Zone::operator== (const ResizableBorderComponent::Zone& other) const throw() { return zone == other.zone; } +bool ResizableBorderComponent::Zone::operator!= (const ResizableBorderComponent::Zone& other) const throw() { return zone != other.zone; } + +const ResizableBorderComponent::Zone::Zone ResizableBorderComponent::Zone::fromPositionOnBorder (const Rectangle& totalSize, + const BorderSize& border, + const Point& position) +{ + int z = 0; + + if (totalSize.contains (position) + && ! border.subtractedFrom (totalSize).contains (position)) + { + const int minW = jmax (totalSize.getWidth() / 10, jmin (10, totalSize.getWidth() / 3)); + if (position.getX() < jmax (border.getLeft(), minW)) + z |= left; + else if (position.getX() >= totalSize.getWidth() - jmax (border.getRight(), minW)) + z |= right; + + const int minH = jmax (totalSize.getHeight() / 10, jmin (10, totalSize.getHeight() / 3)); + if (position.getY() < jmax (border.getTop(), minH)) + z |= top; + else if (position.getY() >= totalSize.getHeight() - jmax (border.getBottom(), minH)) + z |= bottom; + } + + return Zone (z); +} + +const MouseCursor ResizableBorderComponent::Zone::getMouseCursor() const throw() +{ + MouseCursor::StandardCursorType mc = MouseCursor::NormalCursor; + + switch (zone) + { + case (left | top): mc = MouseCursor::TopLeftCornerResizeCursor; break; + case top: mc = MouseCursor::TopEdgeResizeCursor; break; + case (right | top): mc = MouseCursor::TopRightCornerResizeCursor; break; + case left: mc = MouseCursor::LeftEdgeResizeCursor; break; + case right: mc = MouseCursor::RightEdgeResizeCursor; break; + case (left | bottom): mc = MouseCursor::BottomLeftCornerResizeCursor; break; + case bottom: mc = MouseCursor::BottomEdgeResizeCursor; break; + case (right | bottom): mc = MouseCursor::BottomRightCornerResizeCursor; break; + default: break; + } + + return mc; +} + +const Rectangle ResizableBorderComponent::Zone::resizeRectangleBy (Rectangle b, const Point& offset) const throw() +{ + if (isDraggingWholeObject()) + return b + offset; + + if (isDraggingLeftEdge()) + b.setLeft (b.getX() + offset.getX()); + + if (isDraggingRightEdge()) + b.setWidth (b.getWidth() + offset.getX()); + + if (isDraggingTopEdge()) + b.setTop (b.getY() + offset.getY()); + + if (isDraggingBottomEdge()) + b.setHeight (b.getHeight() + offset.getY()); + + return b; +} ResizableBorderComponent::ResizableBorderComponent (Component* const componentToResize, ComponentBoundsConstrainer* const constrainer_) @@ -60925,26 +60995,14 @@ void ResizableBorderComponent::mouseDrag (const MouseEvent& e) return; } - Rectangle bounds (originalBounds); - - if ((mouseZone & zoneL) != 0) - bounds.setLeft (bounds.getX() + e.getDistanceFromDragStartX()); - - if ((mouseZone & zoneT) != 0) - bounds.setTop (bounds.getY() + e.getDistanceFromDragStartY()); - - if ((mouseZone & zoneR) != 0) - bounds.setWidth (bounds.getWidth() + e.getDistanceFromDragStartX()); - - if ((mouseZone & zoneB) != 0) - bounds.setHeight (bounds.getHeight() + e.getDistanceFromDragStartY()); + const Rectangle bounds (mouseZone.resizeRectangleBy (originalBounds, e.getOffsetFromDragStart())); if (constrainer != 0) constrainer->setBoundsForComponent (component, bounds, - (mouseZone & zoneT) != 0, - (mouseZone & zoneL) != 0, - (mouseZone & zoneB) != 0, - (mouseZone & zoneR) != 0); + mouseZone.isDraggingTopEdge(), + mouseZone.isDraggingLeftEdge(), + mouseZone.isDraggingBottomEdge(), + mouseZone.isDraggingRightEdge()); else component->setBounds (bounds); } @@ -60979,49 +61037,12 @@ const BorderSize ResizableBorderComponent::getBorderThickness() const void ResizableBorderComponent::updateMouseZone (const MouseEvent& e) { - int newZone = 0; - - if (ResizableBorderComponent::hitTest (e.x, e.y)) - { - if (e.x < jmax (borderSize.getLeft(), - proportionOfWidth (0.1f), - jmin (10, proportionOfWidth (0.33f)))) - newZone |= zoneL; - else if (e.x >= jmin (getWidth() - borderSize.getRight(), - proportionOfWidth (0.9f), - getWidth() - jmin (10, proportionOfWidth (0.33f)))) - newZone |= zoneR; - - if (e.y < jmax (borderSize.getTop(), - proportionOfHeight (0.1f), - jmin (10, proportionOfHeight (0.33f)))) - newZone |= zoneT; - else if (e.y >= jmin (getHeight() - borderSize.getBottom(), - proportionOfHeight (0.9f), - getHeight() - jmin (10, proportionOfHeight (0.33f)))) - newZone |= zoneB; - } + Zone newZone (Zone::fromPositionOnBorder (getLocalBounds(), borderSize, e.getPosition())); if (mouseZone != newZone) { mouseZone = newZone; - - MouseCursor::StandardCursorType mc = MouseCursor::NormalCursor; - - switch (newZone) - { - case (zoneL | zoneT): mc = MouseCursor::TopLeftCornerResizeCursor; break; - case zoneT: mc = MouseCursor::TopEdgeResizeCursor; break; - case (zoneR | zoneT): mc = MouseCursor::TopRightCornerResizeCursor; break; - case zoneL: mc = MouseCursor::LeftEdgeResizeCursor; break; - case zoneR: mc = MouseCursor::RightEdgeResizeCursor; break; - case (zoneL | zoneB): mc = MouseCursor::BottomLeftCornerResizeCursor; break; - case zoneB: mc = MouseCursor::BottomEdgeResizeCursor; break; - case (zoneR | zoneB): mc = MouseCursor::BottomRightCornerResizeCursor; break; - default: break; - } - - setMouseCursor (mc); + setMouseCursor (newZone.getMouseCursor()); } } @@ -61268,7 +61289,8 @@ void ScrollBar::removeListener (ScrollBarListener* const listener) void ScrollBar::handleAsyncUpdate() { - listeners.call (&ScrollBarListener::scrollBarMoved, this, visibleRange.getStart()); + double start = visibleRange.getStart(); // (need to use a temp variable for VC7 compatibility) + listeners.call (&ScrollBarListener::scrollBarMoved, this, start); } void ScrollBar::updateThumbPosition() @@ -62785,7 +62807,7 @@ void TabbedComponent::resized() indents.setRight (tabDepth + edgeIndent); } - const Rectangle bounds (indents.subtractedFrom (Rectangle (0, 0, getWidth(), getHeight()))); + const Rectangle bounds (indents.subtractedFrom (getLocalBounds())); for (int i = contentComponents.size(); --i >= 0;) if (contentComponents.getUnchecked (i) != 0) @@ -69259,7 +69281,7 @@ void DragAndDropContainer::startDragging (const String& sourceDescription, if (dragImage == 0) { - dragImage = sourceComponent->createComponentSnapshot (Rectangle (0, 0, sourceComponent->getWidth(), sourceComponent->getHeight())); + dragImage = sourceComponent->createComponentSnapshot (sourceComponent->getLocalBounds()); if (dragImage->getFormat() != Image::ARGB) { @@ -69276,8 +69298,7 @@ void DragAndDropContainer::startDragging (const String& sourceDescription, const int hi = 400; Point relPos (sourceComponent->globalPositionToRelative (lastMouseDown)); - Point clipped (Rectangle (0, 0, dragImage->getWidth(), dragImage->getHeight()) - .getConstrainedPoint (relPos)); + Point clipped (dragImage->getBounds().getConstrainedPoint (relPos)); for (int y = dragImage->getHeight(); --y >= 0;) { diff --git a/juce_amalgamated.h b/juce_amalgamated.h index 52426c5982..90e602af6f 100644 --- a/juce_amalgamated.h +++ b/juce_amalgamated.h @@ -12362,6 +12362,8 @@ public: const Rectangle& getBounds() const throw() { return bounds_; } + const Rectangle getLocalBounds() const throw(); + void getVisibleArea (RectangleList& result, bool includeSiblings) const; @@ -22839,6 +22841,46 @@ public: const BorderSize getBorderThickness() const; + class Zone + { + public: + + enum Zones + { + centre = 0, + left = 1, + top = 2, + right = 4, + bottom = 8 + }; + + explicit Zone (int zoneFlags = 0) throw(); + Zone (const Zone& other) throw(); + Zone& operator= (const Zone& other) throw(); + + bool operator== (const Zone& other) const throw(); + bool operator!= (const Zone& other) const throw(); + + static const Zone fromPositionOnBorder (const Rectangle& totalSize, + const BorderSize& border, + const Point& position); + + const MouseCursor getMouseCursor() const throw(); + + bool isDraggingWholeObject() const throw() { return zone == centre; } + bool isDraggingLeftEdge() const throw() { return (zone & left) != 0; } + bool isDraggingRightEdge() const throw() { return (zone & right) != 0; } + bool isDraggingTopEdge() const throw() { return (zone & top) != 0; } + bool isDraggingBottomEdge() const throw() { return (zone & bottom) != 0; } + + const Rectangle resizeRectangleBy (Rectangle original, + const Point& distance) const throw(); + + private: + + int zone; + }; + juce_UseDebuggingNewOperator protected: @@ -22855,7 +22897,7 @@ private: ComponentBoundsConstrainer* constrainer; BorderSize borderSize; Rectangle originalBounds; - int mouseZone; + Zone mouseZone; void updateMouseZone (const MouseEvent& e); diff --git a/src/gui/components/controls/juce_ListBox.cpp b/src/gui/components/controls/juce_ListBox.cpp index 15d0bf1611..ddd0b7af47 100644 --- a/src/gui/components/controls/juce_ListBox.cpp +++ b/src/gui/components/controls/juce_ListBox.cpp @@ -904,7 +904,7 @@ Image* ListBox::createSnapshotOfSelectedRows (int& imageX, int& imageY) } } - imageArea = imageArea.getIntersection (Rectangle (0, 0, getWidth(), getHeight())); + imageArea = imageArea.getIntersection (getLocalBounds()); imageX = imageArea.getX(); imageY = imageArea.getY(); Image* snapshot = Image::createNativeImage (Image::ARGB, imageArea.getWidth(), imageArea.getHeight(), true); diff --git a/src/gui/components/juce_Component.cpp b/src/gui/components/juce_Component.cpp index 2359a1fe9d..cd1620c8de 100644 --- a/src/gui/components/juce_Component.cpp +++ b/src/gui/components/juce_Component.cpp @@ -235,7 +235,7 @@ public: alpha (1.0f), scale (1.0f) { - image = comp->createComponentSnapshot (Rectangle (0, 0, comp->getWidth(), comp->getHeight())); + image = comp->createComponentSnapshot (comp->getLocalBounds()); setBounds (comp->getBounds()); comp->getParentComponent()->addAndMakeVisible (this); toBehind (comp); @@ -1703,7 +1703,7 @@ Image* Component::createComponentSnapshot (const Rectangle& areaToGrab, Rectangle r (areaToGrab); if (clipImageToComponentBounds) - r = r.getIntersection (Rectangle (0, 0, getWidth(), getHeight())); + r = r.getIntersection (getLocalBounds()); ScopedPointer componentImage (Image::createNativeImage (flags.opaqueFlag ? Image::RGB : Image::ARGB, jmax (1, r.getWidth()), @@ -1840,6 +1840,11 @@ void Component::colourChanged() } //============================================================================== +const Rectangle Component::getLocalBounds() const throw() +{ + return Rectangle (0, 0, getWidth(), getHeight()); +} + const Rectangle Component::getUnclippedArea() const { int x = 0, y = 0, w = getWidth(), h = getHeight(); @@ -1889,8 +1894,7 @@ void Component::clipObscuredRegions (Graphics& g, const Rectangle& clipRect } } -void Component::getVisibleArea (RectangleList& result, - const bool includeSiblings) const +void Component::getVisibleArea (RectangleList& result, const bool includeSiblings) const { result.clear(); const Rectangle unclipped (getUnclippedArea()); @@ -1904,8 +1908,7 @@ void Component::getVisibleArea (RectangleList& result, const Component* const c = getTopLevelComponent(); c->subtractObscuredRegions (result, c->relativePositionToOtherComponent (this, Point()), - Rectangle (0, 0, c->getWidth(), c->getHeight()), - this); + c->getLocalBounds(), this); } subtractObscuredRegions (result, Point(), unclipped, 0); diff --git a/src/gui/components/juce_Component.h b/src/gui/components/juce_Component.h index c85f12fb52..c2ac825f0c 100644 --- a/src/gui/components/juce_Component.h +++ b/src/gui/components/juce_Component.h @@ -288,17 +288,13 @@ public: //============================================================================== /** Returns the x co-ordinate of the component's left edge. - This is a distance in pixels from the left edge of the component's parent. - @see getScreenX */ inline int getX() const throw() { return bounds_.getX(); } /** Returns the y co-ordinate of the top of this component. - This is a distance in pixels from the top edge of the component's parent. - @see getScreenY */ inline int getY() const throw() { return bounds_.getY(); } @@ -310,7 +306,6 @@ public: inline int getHeight() const throw() { return bounds_.getHeight(); } /** Returns the x co-ordinate of the component's right-hand edge. - This is a distance in pixels from the left edge of the component's parent. */ int getRight() const throw() { return bounds_.getRight(); } @@ -319,17 +314,21 @@ public: const Point getPosition() const throw() { return bounds_.getPosition(); } /** Returns the y co-ordinate of the bottom edge of this component. - This is a distance in pixels from the top edge of the component's parent. */ int getBottom() const throw() { return bounds_.getBottom(); } /** Returns this component's bounding box. - The rectangle returned is relative to the top-left of the component's parent. */ const Rectangle& getBounds() const throw() { return bounds_; } + /** Returns the component's bounds, relative to its own origin. + This is like getBounds(), but returns the rectangle in local co-ordinates, In practice, it'll + return a rectangle with position (0, 0), and the same size as this component. + */ + const Rectangle getLocalBounds() const throw(); + /** Returns the region of this component that's not obscured by other, opaque components. The RectangleList that is returned represents the area of this component diff --git a/src/gui/components/layout/juce_ResizableBorderComponent.cpp b/src/gui/components/layout/juce_ResizableBorderComponent.cpp index 48093333f4..be87d45bca 100644 --- a/src/gui/components/layout/juce_ResizableBorderComponent.cpp +++ b/src/gui/components/layout/juce_ResizableBorderComponent.cpp @@ -33,13 +33,83 @@ BEGIN_JUCE_NAMESPACE #include "../../graphics/geometry/juce_Line.h" #include "../lookandfeel/juce_LookAndFeel.h" -enum ResizableBorderComponentZones + +//============================================================================== +ResizableBorderComponent::Zone::Zone (int zoneFlags) throw() + : zone (zoneFlags) +{ +} + +ResizableBorderComponent::Zone::Zone (const ResizableBorderComponent::Zone& other) throw() : zone (other.zone) {} +ResizableBorderComponent::Zone& ResizableBorderComponent::Zone::operator= (const ResizableBorderComponent::Zone& other) throw() { zone = other.zone; return *this; } +bool ResizableBorderComponent::Zone::operator== (const ResizableBorderComponent::Zone& other) const throw() { return zone == other.zone; } +bool ResizableBorderComponent::Zone::operator!= (const ResizableBorderComponent::Zone& other) const throw() { return zone != other.zone; } + +const ResizableBorderComponent::Zone::Zone ResizableBorderComponent::Zone::fromPositionOnBorder (const Rectangle& totalSize, + const BorderSize& border, + const Point& position) +{ + int z = 0; + + if (totalSize.contains (position) + && ! border.subtractedFrom (totalSize).contains (position)) + { + const int minW = jmax (totalSize.getWidth() / 10, jmin (10, totalSize.getWidth() / 3)); + if (position.getX() < jmax (border.getLeft(), minW)) + z |= left; + else if (position.getX() >= totalSize.getWidth() - jmax (border.getRight(), minW)) + z |= right; + + const int minH = jmax (totalSize.getHeight() / 10, jmin (10, totalSize.getHeight() / 3)); + if (position.getY() < jmax (border.getTop(), minH)) + z |= top; + else if (position.getY() >= totalSize.getHeight() - jmax (border.getBottom(), minH)) + z |= bottom; + } + + return Zone (z); +} + +const MouseCursor ResizableBorderComponent::Zone::getMouseCursor() const throw() { - zoneL = 1, - zoneR = 2, - zoneT = 4, - zoneB = 8 -}; + MouseCursor::StandardCursorType mc = MouseCursor::NormalCursor; + + switch (zone) + { + case (left | top): mc = MouseCursor::TopLeftCornerResizeCursor; break; + case top: mc = MouseCursor::TopEdgeResizeCursor; break; + case (right | top): mc = MouseCursor::TopRightCornerResizeCursor; break; + case left: mc = MouseCursor::LeftEdgeResizeCursor; break; + case right: mc = MouseCursor::RightEdgeResizeCursor; break; + case (left | bottom): mc = MouseCursor::BottomLeftCornerResizeCursor; break; + case bottom: mc = MouseCursor::BottomEdgeResizeCursor; break; + case (right | bottom): mc = MouseCursor::BottomRightCornerResizeCursor; break; + default: break; + } + + return mc; +} + +const Rectangle ResizableBorderComponent::Zone::resizeRectangleBy (Rectangle b, const Point& offset) const throw() +{ + if (isDraggingWholeObject()) + return b + offset; + + if (isDraggingLeftEdge()) + b.setLeft (b.getX() + offset.getX()); + + if (isDraggingRightEdge()) + b.setWidth (b.getWidth() + offset.getX()); + + if (isDraggingTopEdge()) + b.setTop (b.getY() + offset.getY()); + + if (isDraggingBottomEdge()) + b.setHeight (b.getHeight() + offset.getY()); + + return b; +} + //============================================================================== ResizableBorderComponent::ResizableBorderComponent (Component* const componentToResize, @@ -95,26 +165,14 @@ void ResizableBorderComponent::mouseDrag (const MouseEvent& e) return; } - Rectangle bounds (originalBounds); - - if ((mouseZone & zoneL) != 0) - bounds.setLeft (bounds.getX() + e.getDistanceFromDragStartX()); - - if ((mouseZone & zoneT) != 0) - bounds.setTop (bounds.getY() + e.getDistanceFromDragStartY()); - - if ((mouseZone & zoneR) != 0) - bounds.setWidth (bounds.getWidth() + e.getDistanceFromDragStartX()); - - if ((mouseZone & zoneB) != 0) - bounds.setHeight (bounds.getHeight() + e.getDistanceFromDragStartY()); + const Rectangle bounds (mouseZone.resizeRectangleBy (originalBounds, e.getOffsetFromDragStart())); if (constrainer != 0) constrainer->setBoundsForComponent (component, bounds, - (mouseZone & zoneT) != 0, - (mouseZone & zoneL) != 0, - (mouseZone & zoneB) != 0, - (mouseZone & zoneR) != 0); + mouseZone.isDraggingTopEdge(), + mouseZone.isDraggingLeftEdge(), + mouseZone.isDraggingBottomEdge(), + mouseZone.isDraggingRightEdge()); else component->setBounds (bounds); } @@ -149,49 +207,12 @@ const BorderSize ResizableBorderComponent::getBorderThickness() const void ResizableBorderComponent::updateMouseZone (const MouseEvent& e) { - int newZone = 0; - - if (ResizableBorderComponent::hitTest (e.x, e.y)) - { - if (e.x < jmax (borderSize.getLeft(), - proportionOfWidth (0.1f), - jmin (10, proportionOfWidth (0.33f)))) - newZone |= zoneL; - else if (e.x >= jmin (getWidth() - borderSize.getRight(), - proportionOfWidth (0.9f), - getWidth() - jmin (10, proportionOfWidth (0.33f)))) - newZone |= zoneR; - - if (e.y < jmax (borderSize.getTop(), - proportionOfHeight (0.1f), - jmin (10, proportionOfHeight (0.33f)))) - newZone |= zoneT; - else if (e.y >= jmin (getHeight() - borderSize.getBottom(), - proportionOfHeight (0.9f), - getHeight() - jmin (10, proportionOfHeight (0.33f)))) - newZone |= zoneB; - } + Zone newZone (Zone::fromPositionOnBorder (getLocalBounds(), borderSize, e.getPosition())); if (mouseZone != newZone) { mouseZone = newZone; - - MouseCursor::StandardCursorType mc = MouseCursor::NormalCursor; - - switch (newZone) - { - case (zoneL | zoneT): mc = MouseCursor::TopLeftCornerResizeCursor; break; - case zoneT: mc = MouseCursor::TopEdgeResizeCursor; break; - case (zoneR | zoneT): mc = MouseCursor::TopRightCornerResizeCursor; break; - case zoneL: mc = MouseCursor::LeftEdgeResizeCursor; break; - case zoneR: mc = MouseCursor::RightEdgeResizeCursor; break; - case (zoneL | zoneB): mc = MouseCursor::BottomLeftCornerResizeCursor; break; - case zoneB: mc = MouseCursor::BottomEdgeResizeCursor; break; - case (zoneR | zoneB): mc = MouseCursor::BottomRightCornerResizeCursor; break; - default: break; - } - - setMouseCursor (mc); + setMouseCursor (newZone.getMouseCursor()); } } diff --git a/src/gui/components/layout/juce_ResizableBorderComponent.h b/src/gui/components/layout/juce_ResizableBorderComponent.h index 73e2b36da1..25d7db2eae 100644 --- a/src/gui/components/layout/juce_ResizableBorderComponent.h +++ b/src/gui/components/layout/juce_ResizableBorderComponent.h @@ -87,6 +87,65 @@ public: const BorderSize getBorderThickness() const; + //============================================================================== + /** Represents the different sections of a resizable border, which allow it to + resized in different ways. + */ + class Zone + { + public: + //============================================================================== + enum Zones + { + centre = 0, + left = 1, + top = 2, + right = 4, + bottom = 8 + }; + + //============================================================================== + /** Creates a Zone from a combination of the flags in \enum Zones. */ + explicit Zone (int zoneFlags = 0) throw(); + Zone (const Zone& other) throw(); + Zone& operator= (const Zone& other) throw(); + + bool operator== (const Zone& other) const throw(); + bool operator!= (const Zone& other) const throw(); + + //============================================================================== + /** Given a point within a rectangle with a resizable border, this returns the + zone that the point lies within. + */ + static const Zone fromPositionOnBorder (const Rectangle& totalSize, + const BorderSize& border, + const Point& position); + + /** Returns an appropriate mouse-cursor for this resize zone. */ + const MouseCursor getMouseCursor() const throw(); + + /** Returns true if dragging this zone will move the enire object without resizing it. */ + bool isDraggingWholeObject() const throw() { return zone == centre; } + /** Returns true if dragging this zone will move the object's left edge. */ + bool isDraggingLeftEdge() const throw() { return (zone & left) != 0; } + /** Returns true if dragging this zone will move the object's right edge. */ + bool isDraggingRightEdge() const throw() { return (zone & right) != 0; } + /** Returns true if dragging this zone will move the object's top edge. */ + bool isDraggingTopEdge() const throw() { return (zone & top) != 0; } + /** Returns true if dragging this zone will move the object's bottom edge. */ + bool isDraggingBottomEdge() const throw() { return (zone & bottom) != 0; } + + /** Resizes this rectangle by the given amount, moving just the edges that this zone + applies to. + */ + const Rectangle resizeRectangleBy (Rectangle original, + const Point& distance) const throw(); + + private: + //============================================================================== + int zone; + }; + //============================================================================== juce_UseDebuggingNewOperator @@ -111,7 +170,7 @@ private: ComponentBoundsConstrainer* constrainer; BorderSize borderSize; Rectangle originalBounds; - int mouseZone; + Zone mouseZone; void updateMouseZone (const MouseEvent& e); diff --git a/src/gui/components/layout/juce_ScrollBar.cpp b/src/gui/components/layout/juce_ScrollBar.cpp index 25003f9ceb..a2fb1c0e14 100644 --- a/src/gui/components/layout/juce_ScrollBar.cpp +++ b/src/gui/components/layout/juce_ScrollBar.cpp @@ -199,7 +199,8 @@ void ScrollBar::removeListener (ScrollBarListener* const listener) void ScrollBar::handleAsyncUpdate() { - listeners.call (&ScrollBarListener::scrollBarMoved, this, visibleRange.getStart()); + double start = visibleRange.getStart(); // (need to use a temp variable for VC7 compatibility) + listeners.call (&ScrollBarListener::scrollBarMoved, this, start); } //============================================================================== diff --git a/src/gui/components/layout/juce_TabbedComponent.cpp b/src/gui/components/layout/juce_TabbedComponent.cpp index cad234693a..10d807dc1a 100644 --- a/src/gui/components/layout/juce_TabbedComponent.cpp +++ b/src/gui/components/layout/juce_TabbedComponent.cpp @@ -302,7 +302,7 @@ void TabbedComponent::resized() indents.setRight (tabDepth + edgeIndent); } - const Rectangle bounds (indents.subtractedFrom (Rectangle (0, 0, getWidth(), getHeight()))); + const Rectangle bounds (indents.subtractedFrom (getLocalBounds())); for (int i = contentComponents.size(); --i >= 0;) if (contentComponents.getUnchecked (i) != 0) diff --git a/src/gui/components/mouse/juce_DragAndDropContainer.cpp b/src/gui/components/mouse/juce_DragAndDropContainer.cpp index 6fa145233b..5ff07ceeee 100644 --- a/src/gui/components/mouse/juce_DragAndDropContainer.cpp +++ b/src/gui/components/mouse/juce_DragAndDropContainer.cpp @@ -342,7 +342,7 @@ void DragAndDropContainer::startDragging (const String& sourceDescription, if (dragImage == 0) { - dragImage = sourceComponent->createComponentSnapshot (Rectangle (0, 0, sourceComponent->getWidth(), sourceComponent->getHeight())); + dragImage = sourceComponent->createComponentSnapshot (sourceComponent->getLocalBounds()); if (dragImage->getFormat() != Image::ARGB) { @@ -359,8 +359,7 @@ void DragAndDropContainer::startDragging (const String& sourceDescription, const int hi = 400; Point relPos (sourceComponent->globalPositionToRelative (lastMouseDown)); - Point clipped (Rectangle (0, 0, dragImage->getWidth(), dragImage->getHeight()) - .getConstrainedPoint (relPos)); + Point clipped (dragImage->getBounds().getConstrainedPoint (relPos)); for (int y = dragImage->getHeight(); --y >= 0;) { diff --git a/src/text/juce_String.cpp b/src/text/juce_String.cpp index 29c63f9eef..3414b4dbf1 100644 --- a/src/text/juce_String.cpp +++ b/src/text/juce_String.cpp @@ -400,7 +400,7 @@ namespace NumberToStringConverters else { #if JUCE_WIN32 - #if _MSC_VER <= 1200 + #if _MSC_VER <= 1400 len = _snwprintf (buffer, numChars, L"%.9g", n); #else len = _snwprintf_s (buffer, numChars, _TRUNCATE, L"%.9g", n);