| @@ -329,9 +329,9 @@ public: | |||
| DragHandler (ComponentDocument& document_, | |||
| const Array<Component*>& 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<int>& distance, const Rectangle<int>& originalPos) | |||
| { | |||
| v.setProperty (compBoundsProperty, componentBoundsToString (originalPos + distance), document.getUndoManager()); | |||
| } | |||
| void resize (ValueTree& v, const Point<int>& distance, const Rectangle<int>& originalPos) | |||
| { | |||
| Rectangle<int> 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<int> newBounds (zone.resizeRectangleBy (originalPos, distance)); | |||
| v.setProperty (compBoundsProperty, componentBoundsToString (newBounds), document.getUndoManager()); | |||
| } | |||
| private: | |||
| ComponentDocument& document; | |||
| Array <ValueTree> draggedComponents; | |||
| Array <Rectangle<int> > originalPositions; | |||
| const int zones; | |||
| const ResizableBorderComponent::Zone zone; | |||
| }; | |||
| void ComponentDocument::beginDrag (const Array<Component*>& items, const MouseEvent& e, int zones) | |||
| void ComponentDocument::beginDrag (const Array<Component*>& 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) | |||
| @@ -67,7 +67,8 @@ public: | |||
| zoneB = 8 | |||
| }; | |||
| void beginDrag (const Array<Component*>& items, const MouseEvent& e, int zones); | |||
| void beginDrag (const Array<Component*>& items, const MouseEvent& e, | |||
| const ResizableBorderComponent::Zone& zone); | |||
| void continueDrag (const MouseEvent& e); | |||
| void endDrag (const MouseEvent& e); | |||
| @@ -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<int>& 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> component; | |||
| int dragZone; | |||
| ResizableBorderComponent::Zone dragZone; | |||
| const int borderThickness; | |||
| const Rectangle<int> getCentreArea() const | |||
| { | |||
| return Rectangle<int> (0, 0, getWidth(), getHeight()).reduced (borderThickness, borderThickness); | |||
| return getLocalBounds().reduced (borderThickness, borderThickness); | |||
| } | |||
| void updateDragZone (const Point<int>& 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); | |||
| @@ -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<int> (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<int>& areaToGrab, | |||
| Rectangle<int> r (areaToGrab); | |||
| if (clipImageToComponentBounds) | |||
| r = r.getIntersection (Rectangle<int> (0, 0, getWidth(), getHeight())); | |||
| r = r.getIntersection (getLocalBounds()); | |||
| ScopedPointer<Image> componentImage (Image::createNativeImage (flags.opaqueFlag ? Image::RGB : Image::ARGB, | |||
| jmax (1, r.getWidth()), | |||
| @@ -39946,6 +39946,11 @@ void Component::colourChanged() | |||
| { | |||
| } | |||
| const Rectangle<int> Component::getLocalBounds() const throw() | |||
| { | |||
| return Rectangle<int> (0, 0, getWidth(), getHeight()); | |||
| } | |||
| const Rectangle<int> Component::getUnclippedArea() const | |||
| { | |||
| int x = 0, y = 0, w = getWidth(), h = getHeight(); | |||
| @@ -39995,8 +40000,7 @@ void Component::clipObscuredRegions (Graphics& g, const Rectangle<int>& clipRect | |||
| } | |||
| } | |||
| void Component::getVisibleArea (RectangleList& result, | |||
| const bool includeSiblings) const | |||
| void Component::getVisibleArea (RectangleList& result, const bool includeSiblings) const | |||
| { | |||
| result.clear(); | |||
| const Rectangle<int> unclipped (getUnclippedArea()); | |||
| @@ -40010,8 +40014,7 @@ void Component::getVisibleArea (RectangleList& result, | |||
| const Component* const c = getTopLevelComponent(); | |||
| c->subtractObscuredRegions (result, c->relativePositionToOtherComponent (this, Point<int>()), | |||
| Rectangle<int> (0, 0, c->getWidth(), c->getHeight()), | |||
| this); | |||
| c->getLocalBounds(), this); | |||
| } | |||
| subtractObscuredRegions (result, Point<int>(), unclipped, 0); | |||
| @@ -47658,7 +47661,7 @@ Image* ListBox::createSnapshotOfSelectedRows (int& imageX, int& imageY) | |||
| } | |||
| } | |||
| imageArea = imageArea.getIntersection (Rectangle<int> (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<int>& totalSize, | |||
| const BorderSize& border, | |||
| const Point<int>& 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<int> ResizableBorderComponent::Zone::resizeRectangleBy (Rectangle<int> b, const Point<int>& 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<int> 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<int> 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<int> bounds (indents.subtractedFrom (Rectangle<int> (0, 0, getWidth(), getHeight()))); | |||
| const Rectangle<int> 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<int> (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<int> relPos (sourceComponent->globalPositionToRelative (lastMouseDown)); | |||
| Point<int> clipped (Rectangle<int> (0, 0, dragImage->getWidth(), dragImage->getHeight()) | |||
| .getConstrainedPoint (relPos)); | |||
| Point<int> clipped (dragImage->getBounds().getConstrainedPoint (relPos)); | |||
| for (int y = dragImage->getHeight(); --y >= 0;) | |||
| { | |||
| @@ -12362,6 +12362,8 @@ public: | |||
| const Rectangle<int>& getBounds() const throw() { return bounds_; } | |||
| const Rectangle<int> 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<int>& totalSize, | |||
| const BorderSize& border, | |||
| const Point<int>& 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<int> resizeRectangleBy (Rectangle<int> original, | |||
| const Point<int>& distance) const throw(); | |||
| private: | |||
| int zone; | |||
| }; | |||
| juce_UseDebuggingNewOperator | |||
| protected: | |||
| @@ -22855,7 +22897,7 @@ private: | |||
| ComponentBoundsConstrainer* constrainer; | |||
| BorderSize borderSize; | |||
| Rectangle<int> originalBounds; | |||
| int mouseZone; | |||
| Zone mouseZone; | |||
| void updateMouseZone (const MouseEvent& e); | |||
| @@ -904,7 +904,7 @@ Image* ListBox::createSnapshotOfSelectedRows (int& imageX, int& imageY) | |||
| } | |||
| } | |||
| imageArea = imageArea.getIntersection (Rectangle<int> (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); | |||
| @@ -235,7 +235,7 @@ public: | |||
| alpha (1.0f), | |||
| scale (1.0f) | |||
| { | |||
| image = comp->createComponentSnapshot (Rectangle<int> (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<int>& areaToGrab, | |||
| Rectangle<int> r (areaToGrab); | |||
| if (clipImageToComponentBounds) | |||
| r = r.getIntersection (Rectangle<int> (0, 0, getWidth(), getHeight())); | |||
| r = r.getIntersection (getLocalBounds()); | |||
| ScopedPointer<Image> componentImage (Image::createNativeImage (flags.opaqueFlag ? Image::RGB : Image::ARGB, | |||
| jmax (1, r.getWidth()), | |||
| @@ -1840,6 +1840,11 @@ void Component::colourChanged() | |||
| } | |||
| //============================================================================== | |||
| const Rectangle<int> Component::getLocalBounds() const throw() | |||
| { | |||
| return Rectangle<int> (0, 0, getWidth(), getHeight()); | |||
| } | |||
| const Rectangle<int> Component::getUnclippedArea() const | |||
| { | |||
| int x = 0, y = 0, w = getWidth(), h = getHeight(); | |||
| @@ -1889,8 +1894,7 @@ void Component::clipObscuredRegions (Graphics& g, const Rectangle<int>& clipRect | |||
| } | |||
| } | |||
| void Component::getVisibleArea (RectangleList& result, | |||
| const bool includeSiblings) const | |||
| void Component::getVisibleArea (RectangleList& result, const bool includeSiblings) const | |||
| { | |||
| result.clear(); | |||
| const Rectangle<int> unclipped (getUnclippedArea()); | |||
| @@ -1904,8 +1908,7 @@ void Component::getVisibleArea (RectangleList& result, | |||
| const Component* const c = getTopLevelComponent(); | |||
| c->subtractObscuredRegions (result, c->relativePositionToOtherComponent (this, Point<int>()), | |||
| Rectangle<int> (0, 0, c->getWidth(), c->getHeight()), | |||
| this); | |||
| c->getLocalBounds(), this); | |||
| } | |||
| subtractObscuredRegions (result, Point<int>(), unclipped, 0); | |||
| @@ -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<int> 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<int>& 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<int> 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 | |||
| @@ -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<int>& totalSize, | |||
| const BorderSize& border, | |||
| const Point<int>& 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<int> ResizableBorderComponent::Zone::resizeRectangleBy (Rectangle<int> b, const Point<int>& 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<int> 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<int> 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()); | |||
| } | |||
| } | |||
| @@ -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<int>& totalSize, | |||
| const BorderSize& border, | |||
| const Point<int>& 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<int> resizeRectangleBy (Rectangle<int> original, | |||
| const Point<int>& distance) const throw(); | |||
| private: | |||
| //============================================================================== | |||
| int zone; | |||
| }; | |||
| //============================================================================== | |||
| juce_UseDebuggingNewOperator | |||
| @@ -111,7 +170,7 @@ private: | |||
| ComponentBoundsConstrainer* constrainer; | |||
| BorderSize borderSize; | |||
| Rectangle<int> originalBounds; | |||
| int mouseZone; | |||
| Zone mouseZone; | |||
| void updateMouseZone (const MouseEvent& e); | |||
| @@ -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); | |||
| } | |||
| //============================================================================== | |||
| @@ -302,7 +302,7 @@ void TabbedComponent::resized() | |||
| indents.setRight (tabDepth + edgeIndent); | |||
| } | |||
| const Rectangle<int> bounds (indents.subtractedFrom (Rectangle<int> (0, 0, getWidth(), getHeight()))); | |||
| const Rectangle<int> bounds (indents.subtractedFrom (getLocalBounds())); | |||
| for (int i = contentComponents.size(); --i >= 0;) | |||
| if (contentComponents.getUnchecked (i) != 0) | |||
| @@ -342,7 +342,7 @@ void DragAndDropContainer::startDragging (const String& sourceDescription, | |||
| if (dragImage == 0) | |||
| { | |||
| dragImage = sourceComponent->createComponentSnapshot (Rectangle<int> (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<int> relPos (sourceComponent->globalPositionToRelative (lastMouseDown)); | |||
| Point<int> clipped (Rectangle<int> (0, 0, dragImage->getWidth(), dragImage->getHeight()) | |||
| .getConstrainedPoint (relPos)); | |||
| Point<int> clipped (dragImage->getBounds().getConstrainedPoint (relPos)); | |||
| for (int y = dragImage->getHeight(); --y >= 0;) | |||
| { | |||
| @@ -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); | |||