@@ -499,8 +499,15 @@ bool DrawableDocument::MarkerList::createProperties (Array <PropertyComponent*>& | |||||
if (marker.isValid()) | if (marker.isValid()) | ||||
{ | { | ||||
props.add (new TextPropertyComponent (marker.getPropertyAsValue (DrawableComposite::ValueTreeWrapper::nameProperty, getUndoManager()), | |||||
"Marker Name", 256, false)); | |||||
const String markerName (marker [DrawableComposite::ValueTreeWrapper::nameProperty].toString()); | |||||
TextPropertyComponent* nameProp = new TextPropertyComponent (Value (new MarkerListBase::MarkerNameValueSource (this, marker.getPropertyAsValue (DrawableComposite::ValueTreeWrapper::nameProperty, getUndoManager()))), | |||||
"Marker Name", 256, false); | |||||
nameProp->setEnabled (markerName != DrawableComposite::contentLeftMarkerName | |||||
&& markerName != DrawableComposite::contentRightMarkerName | |||||
&& markerName != DrawableComposite::contentTopMarkerName | |||||
&& markerName != DrawableComposite::contentBottomMarkerName); | |||||
props.add (nameProp); | |||||
props.add (new MarkerListBase::PositionPropertyComponent (*this, "Position", marker, | props.add (new MarkerListBase::PositionPropertyComponent (*this, "Position", marker, | ||||
marker.getPropertyAsValue (DrawableComposite::ValueTreeWrapper::posProperty, getUndoManager()))); | marker.getPropertyAsValue (DrawableComposite::ValueTreeWrapper::posProperty, getUndoManager()))); | ||||
@@ -575,4 +582,27 @@ void DrawableDocument::MarkerList::renameAnchor (const String& oldName, const St | |||||
void DrawableDocument::renameAnchor (const String& oldName, const String& newName) | void DrawableDocument::renameAnchor (const String& oldName, const String& newName) | ||||
{ | { | ||||
markersX->renameAnchorInMarkers (oldName, newName); | |||||
markersY->renameAnchorInMarkers (oldName, newName); | |||||
DrawableComposite::ValueTreeWrapper root (getRootDrawableNode()); | |||||
DrawableTypeInstance rootItem (*this, root.getState()); | |||||
for (int i = root.getNumDrawables(); --i >= 0;) | |||||
{ | |||||
DrawableTypeInstance item (*this, root.getDrawableState(i)); | |||||
OwnedArray <ControlPoint> points; | |||||
item.getAllControlPoints (points); | |||||
for (int j = points.size(); --j >= 0;) | |||||
{ | |||||
const RelativePoint oldPoint (points.getUnchecked(j)->getPosition()); | |||||
RelativePoint newPoint (oldPoint); | |||||
newPoint.renameAnchorIfUsed (oldName, newName, &rootItem); | |||||
if (newPoint != oldPoint) | |||||
points.getUnchecked(j)->setPosition (newPoint, getUndoManager()); | |||||
} | |||||
} | |||||
} | } |
@@ -36,6 +36,8 @@ public: | |||||
ComponentEditorCanvas (ComponentEditor& editor_) | ComponentEditorCanvas (ComponentEditor& editor_) | ||||
: editor (editor_) | : editor (editor_) | ||||
{ | { | ||||
background = ImageCache::getFromMemory (BinaryData::brushed_aluminium_png, BinaryData::brushed_aluminium_pngSize); | |||||
initialise(); | initialise(); | ||||
getDocument().getRoot().addListener (this); | getDocument().getRoot().addListener (this); | ||||
} | } | ||||
@@ -68,6 +70,12 @@ public: | |||||
startTimer (500); | startTimer (500); | ||||
} | } | ||||
void fillBackground (Graphics& g) | |||||
{ | |||||
g.setTiledImageFill (background, 0, 0, 1.0f); | |||||
g.fillAll(); | |||||
} | |||||
const Rectangle<int> getCanvasBounds() | const Rectangle<int> getCanvasBounds() | ||||
{ | { | ||||
return Rectangle<int> (0, 0, getDocument().getCanvasWidth().getValue(), | return Rectangle<int> (0, 0, getDocument().getCanvasWidth().getValue(), | ||||
@@ -298,6 +306,7 @@ public: | |||||
private: | private: | ||||
//============================================================================== | //============================================================================== | ||||
ComponentEditor& editor; | ComponentEditor& editor; | ||||
Image background; | |||||
class ComponentHolder : public Component, | class ComponentHolder : public Component, | ||||
public Value::Listener | public Value::Listener | ||||
@@ -38,7 +38,9 @@ class DrawableEditorCanvas : public EditorCanvasBase, | |||||
public: | public: | ||||
//============================================================================== | //============================================================================== | ||||
DrawableEditorCanvas (DrawableEditor& editor_) | DrawableEditorCanvas (DrawableEditor& editor_) | ||||
: editor (editor_) | |||||
: editor (editor_), | |||||
backgroundColour (Colour::greyLevel (0.95f)), | |||||
contentAreaColour (Colours::white) | |||||
{ | { | ||||
initialise(); | initialise(); | ||||
getDocument().getRoot().addListener (this); | getDocument().getRoot().addListener (this); | ||||
@@ -83,6 +85,11 @@ public: | |||||
startTimer (500); | startTimer (500); | ||||
} | } | ||||
void fillBackground (Graphics& g) | |||||
{ | |||||
g.fillAll (backgroundColour); | |||||
} | |||||
const Rectangle<int> getCanvasBounds() | const Rectangle<int> getCanvasBounds() | ||||
{ | { | ||||
return drawable->getBounds().getSmallestIntegerContainer(); | return drawable->getBounds().getSmallestIntegerContainer(); | ||||
@@ -91,6 +98,11 @@ public: | |||||
void setCanvasBounds (const Rectangle<int>& newBounds) {} | void setCanvasBounds (const Rectangle<int>& newBounds) {} | ||||
bool canResizeCanvas() const { return false; } | bool canResizeCanvas() const { return false; } | ||||
const Rectangle<float> getContentArea() const | |||||
{ | |||||
return drawable->getContentArea().resolve (drawable->getParent()); | |||||
} | |||||
//============================================================================== | //============================================================================== | ||||
const ValueTree getObjectState (const String& objectId) | const ValueTree getObjectState (const String& objectId) | ||||
{ | { | ||||
@@ -705,27 +717,23 @@ public: | |||||
DrawableComponent (DrawableEditorCanvas* canvas_) | DrawableComponent (DrawableEditorCanvas* canvas_) | ||||
: canvas (canvas_) | : canvas (canvas_) | ||||
{ | { | ||||
setOpaque (true); | |||||
} | } | ||||
~DrawableComponent() | ~DrawableComponent() | ||||
{ | { | ||||
} | } | ||||
void updateDrawable() | |||||
{ | |||||
repaint(); | |||||
} | |||||
void paint (Graphics& g) | void paint (Graphics& g) | ||||
{ | { | ||||
canvas->handleUpdateNowIfNeeded(); | |||||
g.fillAll (Colours::white); | |||||
// do not call canvas->handleUpdateNowIfNeeded() here! It resizes the component while we're painting it! | |||||
const Point<int> origin (canvas->getScale().origin); | const Point<int> origin (canvas->getScale().origin); | ||||
g.setOrigin (origin.getX(), origin.getY()); | g.setOrigin (origin.getX(), origin.getY()); | ||||
if (origin.getX() > 0) | |||||
g.setColour (canvas->contentAreaColour); | |||||
g.fillRect (canvas->getContentArea().getSmallestIntegerContainer()); | |||||
/* if (origin.getX() > 0) | |||||
{ | { | ||||
g.setColour (Colour::greyLevel (0.87f)); | g.setColour (Colour::greyLevel (0.87f)); | ||||
g.drawVerticalLine (0, -10000.0f, 10000.0f); | g.drawVerticalLine (0, -10000.0f, 10000.0f); | ||||
@@ -736,7 +744,7 @@ public: | |||||
g.setColour (Colour::greyLevel (0.87f)); | g.setColour (Colour::greyLevel (0.87f)); | ||||
g.drawHorizontalLine (0, -10000.0f, 10000.0f); | g.drawHorizontalLine (0, -10000.0f, 10000.0f); | ||||
} | } | ||||
*/ | |||||
canvas->drawable->draw (g, 1.0f); | canvas->drawable->draw (g, 1.0f); | ||||
} | } | ||||
@@ -746,6 +754,7 @@ public: | |||||
}; | }; | ||||
ScopedPointer<DrawableComposite> drawable; | ScopedPointer<DrawableComposite> drawable; | ||||
Colour backgroundColour, contentAreaColour; | |||||
private: | private: | ||||
//============================================================================== | //============================================================================== | ||||
@@ -597,6 +597,7 @@ EditorCanvasBase::EditorCanvasBase() | |||||
: border (8, 8, 14, 14) | : border (8, 8, 14, 14) | ||||
{ | { | ||||
//setOpaque (true); | //setOpaque (true); | ||||
trimCanvasTimer.owner = this; | |||||
addChildComponent (&spacebarDragOverlay); | addChildComponent (&spacebarDragOverlay); | ||||
} | } | ||||
@@ -609,7 +610,9 @@ void EditorCanvasBase::initialise() | |||||
{ | { | ||||
addAndMakeVisible (componentHolder = createComponentHolder()); | addAndMakeVisible (componentHolder = createComponentHolder()); | ||||
addAndMakeVisible (overlay = new OverlayComponent (this)); | addAndMakeVisible (overlay = new OverlayComponent (this)); | ||||
overlay->addAndMakeVisible (resizeFrame = new DocumentResizeFrame (this)); | |||||
if (canResizeCanvas()) | |||||
overlay->addAndMakeVisible (resizeFrame = new DocumentResizeFrame (this)); | |||||
handleAsyncUpdate(); | handleAsyncUpdate(); | ||||
} | } | ||||
@@ -706,50 +709,79 @@ const Rectangle<int> EditorCanvasBase::getContentArea() const | |||||
void EditorCanvasBase::handleAsyncUpdate() | void EditorCanvasBase::handleAsyncUpdate() | ||||
{ | { | ||||
documentChanged(); | documentChanged(); | ||||
updateCanvasArea (false, false); | |||||
const Rectangle<int> canvasBounds (getCanvasBounds()); | |||||
EditorPanelBase* panel = getPanel(); | |||||
if (panel != 0) | |||||
panel->updateRulers(); // also updates markers | |||||
overlay->update(); | |||||
} | |||||
const Point<int> newOrigin (jmax (0, -canvasBounds.getX()), jmax (0, -canvasBounds.getY())); | |||||
const int newWidth = jmax (canvasBounds.getWidth(), canvasBounds.getRight()) + border.getLeftAndRight(); | |||||
const int newHeight = jmax (canvasBounds.getHeight(), canvasBounds.getBottom()) + border.getTopAndBottom(); | |||||
void EditorCanvasBase::updateCanvasArea (bool trimIfPossible, bool updateOverlay) | |||||
{ | |||||
const Rectangle<int> canvasBounds (getCanvasBounds()); | |||||
if (scale.origin != newOrigin) | |||||
if (lastCanvasBounds != canvasBounds || trimIfPossible) | |||||
{ | { | ||||
repaint(); | |||||
lastCanvasBounds = canvasBounds; | |||||
const Point<int> oldOrigin (scale.origin); | |||||
scale.origin = newOrigin; | |||||
if (! canResizeCanvas()) | |||||
{ | |||||
Rectangle<int> bounds (getBounds()); | |||||
const Point<int> originInParent (scale.origin + componentHolder->getPosition() + bounds.getPosition()); | |||||
bounds = border.addedTo (canvasBounds) + originInParent; | |||||
if (getParentComponent() != 0) | |||||
bounds = bounds.getUnion (getParentComponent()->getLocalBounds()); | |||||
setBounds (jmin (0, getX() + oldOrigin.getX() - scale.origin.getX()), | |||||
jmin (0, getY() + oldOrigin.getY() - scale.origin.getY()), | |||||
newWidth, newHeight); | |||||
const Point<int> newOrigin (originInParent - bounds.getPosition() - componentHolder->getPosition()); | |||||
if (scale.origin != newOrigin) | |||||
{ | |||||
repaint(); | |||||
scale.origin = newOrigin; | |||||
} | |||||
if (getBounds() != bounds) | |||||
{ | |||||
setBounds (bounds); | |||||
EditorPanelBase* panel = getPanel(); | |||||
if (panel != 0) | |||||
panel->updateRulers(); | |||||
if (updateOverlay) | |||||
overlay->update(); | |||||
} | |||||
} | |||||
else if (getWidth() != canvasBounds.getWidth() || getHeight() != canvasBounds.getHeight()) | |||||
{ | |||||
setBounds (canvasBounds); | |||||
} | |||||
} | } | ||||
else if (getWidth() != newWidth || getHeight() != newHeight) | |||||
} | |||||
void EditorCanvasBase::TrimCanvasTimer::timerCallback() | |||||
{ | |||||
if (! isMouseButtonDownAnywhere()) | |||||
{ | { | ||||
setSize (newWidth, newHeight); | |||||
stopTimer(); | |||||
owner->updateCanvasArea (true, true); | |||||
} | } | ||||
else | |||||
{ | |||||
overlay->update(); | |||||
} | |||||
EditorPanelBase* panel = getPanel(); | |||||
if (panel != 0) | |||||
panel->updateMarkers(); | |||||
} | |||||
void EditorCanvasBase::moved() | |||||
{ | |||||
trimCanvasTimer.startTimer (500); | |||||
} | } | ||||
void EditorCanvasBase::resized() | void EditorCanvasBase::resized() | ||||
{ | { | ||||
componentHolder->setBounds (getContentArea()); | componentHolder->setBounds (getContentArea()); | ||||
overlay->setBounds (getLocalBounds()); | overlay->setBounds (getLocalBounds()); | ||||
resizeFrame->setBounds (getLocalBounds()); | |||||
if (resizeFrame != 0) | |||||
resizeFrame->setBounds (getLocalBounds()); | |||||
spacebarDragOverlay.setBounds (getLocalBounds()); | spacebarDragOverlay.setBounds (getLocalBounds()); | ||||
overlay->update(); | |||||
handleUpdateNowIfNeeded(); | |||||
trimCanvasTimer.startTimer (500); | |||||
} | } | ||||
//============================================================================== | //============================================================================== | ||||
@@ -49,6 +49,7 @@ public: | |||||
//============================================================================== | //============================================================================== | ||||
void paint (Graphics& g); | void paint (Graphics& g); | ||||
void resized(); | void resized(); | ||||
void moved(); | |||||
bool keyStateChanged (bool isKeyDown); | bool keyStateChanged (bool isKeyDown); | ||||
bool keyPressed (const KeyPress& key); | bool keyPressed (const KeyPress& key); | ||||
@@ -79,6 +80,7 @@ public: | |||||
virtual void documentChanged() = 0; | virtual void documentChanged() = 0; | ||||
virtual Component* createComponentHolder() = 0; | virtual Component* createComponentHolder() = 0; | ||||
virtual void fillBackground (Graphics& g) = 0; | |||||
virtual const Rectangle<int> getCanvasBounds() = 0; | virtual const Rectangle<int> getCanvasBounds() = 0; | ||||
virtual void setCanvasBounds (const Rectangle<int>& newBounds) = 0; | virtual void setCanvasBounds (const Rectangle<int>& newBounds) = 0; | ||||
virtual bool canResizeCanvas() const = 0; | virtual bool canResizeCanvas() const = 0; | ||||
@@ -164,6 +166,7 @@ protected: | |||||
const BorderSize border; | const BorderSize border; | ||||
Scale scale; | Scale scale; | ||||
ValueTree controlPointEditingTarget; | ValueTree controlPointEditingTarget; | ||||
Rectangle<int> lastCanvasBounds; | |||||
friend class OverlayItemComponent; | friend class OverlayItemComponent; | ||||
class ResizeFrame; | class ResizeFrame; | ||||
@@ -196,7 +199,21 @@ protected: | |||||
SpacebarDragOverlay spacebarDragOverlay; | SpacebarDragOverlay spacebarDragOverlay; | ||||
ScopedPointer<DragOperation> dragger; | ScopedPointer<DragOperation> dragger; | ||||
class TrimCanvasTimer : public Timer | |||||
{ | |||||
public: | |||||
TrimCanvasTimer() {} | |||||
~TrimCanvasTimer() {} | |||||
void timerCallback(); | |||||
EditorCanvasBase* owner; | |||||
}; | |||||
friend class TrimCanvasTimer; | |||||
TrimCanvasTimer trimCanvasTimer; | |||||
void handleAsyncUpdate(); | void handleAsyncUpdate(); | ||||
void updateCanvasArea (bool trimIfPossible, bool updateOverlay); | |||||
}; | }; | ||||
@@ -235,6 +235,8 @@ public: | |||||
for (int i = 0; i < updateList.size(); ++i) | for (int i = 0; i < updateList.size(); ++i) | ||||
dragItem (updateList.getReference(i), distance, originalPositions.getReference(i)); | dragItem (updateList.getReference(i), distance, originalPositions.getReference(i)); | ||||
} | } | ||||
canvas->handleUpdateNowIfNeeded(); | |||||
} | } | ||||
protected: | protected: | ||||
@@ -38,6 +38,7 @@ public: | |||||
: rulerX (true), rulerY (false), markersVisible (true), snappingEnabled (true), canvas (0) | : rulerX (true), rulerY (false), markersVisible (true), snappingEnabled (true), canvas (0) | ||||
{ | { | ||||
setOpaque (true); | setOpaque (true); | ||||
background = ImageCache::getFromMemory (BinaryData::brushed_aluminium_png, BinaryData::brushed_aluminium_pngSize); | background = ImageCache::getFromMemory (BinaryData::brushed_aluminium_png, BinaryData::brushed_aluminium_pngSize); | ||||
addAndMakeVisible (&toolbar); | addAndMakeVisible (&toolbar); | ||||
@@ -525,8 +526,8 @@ private: | |||||
{ | { | ||||
public: | public: | ||||
CanvasViewport() | CanvasViewport() | ||||
: canvas (0) | |||||
{ | { | ||||
background = ImageCache::getFromMemory (BinaryData::brushed_aluminium_png, BinaryData::brushed_aluminium_pngSize); | |||||
setOpaque (true); | setOpaque (true); | ||||
} | } | ||||
@@ -536,8 +537,11 @@ private: | |||||
void paint (Graphics& g) | void paint (Graphics& g) | ||||
{ | { | ||||
g.setTiledImageFill (background, 0, 0, 1.0f); | |||||
g.fillAll(); | |||||
if (canvas == 0) | |||||
canvas = dynamic_cast <EditorCanvasBase*> (getViewedComponent()); | |||||
if (canvas != 0) | |||||
canvas->fillBackground (g); | |||||
} | } | ||||
void paintOverChildren (Graphics& g) | void paintOverChildren (Graphics& g) | ||||
@@ -554,7 +558,7 @@ private: | |||||
} | } | ||||
private: | private: | ||||
Image background; | |||||
EditorCanvasBase* canvas; | |||||
}; | }; | ||||
//============================================================================== | //============================================================================== | ||||
@@ -235,7 +235,7 @@ void PaintElementPath::rescalePoint (RelativePositionedRectangle& pos, int dx, i | |||||
//============================================================================== | //============================================================================== | ||||
static void drawArrow (Graphics& g, float x1, float y1, float x2, float y2) | static void drawArrow (Graphics& g, float x1, float y1, float x2, float y2) | ||||
{ | { | ||||
g.drawArrow (x1, y1, (x1 + x2) * 0.5f, (y1 + y2) * 0.5f, 1.0f, 8.0f, 10.0f); | |||||
g.drawArrow (Line<float> (x1, y1, (x1 + x2) * 0.5f, (y1 + y2) * 0.5f), 1.0f, 8.0f, 10.0f); | |||||
g.drawLine (x1 + (x2 - x1) * 0.49f, y1 + (y2 - y1) * 0.49f, x2, y2); | g.drawLine (x1 + (x2 - x1) * 0.49f, y1 + (y2 - y1) * 0.49f, x2, y2); | ||||
} | } | ||||
@@ -1052,7 +1052,7 @@ int PaintElementPath::findSegmentAtXY (int x, int y) const | |||||
case Path::Iterator::lineTo: | case Path::Iterator::lineTo: | ||||
positionToXY (p->pos [0], x1, y1, area, layout); | positionToXY (p->pos [0], x1, y1, area, layout); | ||||
segmentPath.addLineSegment ((float) lastX, (float) lastY, (float) x1, (float) y1, thickness); | |||||
segmentPath.addLineSegment (Line<float> ((float) lastX, (float) lastY, (float) x1, (float) y1), thickness); | |||||
if (segmentPath.contains ((float) x, (float) y)) | if (segmentPath.contains ((float) x, (float) y)) | ||||
return i; | return i; | ||||
@@ -1092,7 +1092,7 @@ int PaintElementPath::findSegmentAtXY (int x, int y) const | |||||
break; | break; | ||||
case Path::Iterator::closePath: | case Path::Iterator::closePath: | ||||
segmentPath.addLineSegment ((float) lastX, (float) lastY, (float) subPathStartX, (float) subPathStartY, thickness); | |||||
segmentPath.addLineSegment (Line<float> ((float) lastX, (float) lastY, (float) subPathStartX, (float) subPathStartY), thickness); | |||||
if (segmentPath.contains ((float) x, (float) y)) | if (segmentPath.contains ((float) x, (float) y)) | ||||
return subpathStartIndex; | return subpathStartIndex; | ||||
@@ -63710,6 +63710,7 @@ void Viewport::updateVisibleArea() | |||||
horizontalScrollBar.setRangeLimits (0.0, contentBounds.getWidth()); | horizontalScrollBar.setRangeLimits (0.0, contentBounds.getWidth()); | ||||
horizontalScrollBar.setCurrentRange (visibleOrigin.getX(), contentArea.getWidth()); | horizontalScrollBar.setCurrentRange (visibleOrigin.getX(), contentArea.getWidth()); | ||||
horizontalScrollBar.setSingleStepSize (singleStepX); | horizontalScrollBar.setSingleStepSize (singleStepX); | ||||
horizontalScrollBar.cancelPendingUpdate(); | |||||
} | } | ||||
if (vBarVisible) | if (vBarVisible) | ||||
@@ -63718,6 +63719,7 @@ void Viewport::updateVisibleArea() | |||||
verticalScrollBar.setRangeLimits (0.0, contentBounds.getHeight()); | verticalScrollBar.setRangeLimits (0.0, contentBounds.getHeight()); | ||||
verticalScrollBar.setCurrentRange (visibleOrigin.getY(), contentArea.getHeight()); | verticalScrollBar.setCurrentRange (visibleOrigin.getY(), contentArea.getHeight()); | ||||
verticalScrollBar.setSingleStepSize (singleStepY); | verticalScrollBar.setSingleStepSize (singleStepY); | ||||
verticalScrollBar.cancelPendingUpdate(); | |||||
} | } | ||||
// Force the visibility *after* setting the ranges to avoid flicker caused by edge conditions in the numbers. | // Force the visibility *after* setting the ranges to avoid flicker caused by edge conditions in the numbers. | ||||
@@ -63808,20 +63810,46 @@ bool Viewport::useMouseWheelMoveIfNeeded (const MouseEvent& e, float wheelIncrem | |||||
const bool hasVertBar = verticalScrollBar.isVisible(); | const bool hasVertBar = verticalScrollBar.isVisible(); | ||||
const bool hasHorzBar = horizontalScrollBar.isVisible(); | const bool hasHorzBar = horizontalScrollBar.isVisible(); | ||||
if (hasHorzBar && (wheelIncrementX != 0 || e.mods.isShiftDown() || ! hasVertBar)) | |||||
if (hasHorzBar || hasVertBar) | |||||
{ | { | ||||
if (wheelIncrementX == 0 && ! hasVertBar) | |||||
wheelIncrementX = wheelIncrementY; | |||||
if (wheelIncrementX != 0) | |||||
{ | |||||
wheelIncrementX *= 14.0f * singleStepX; | |||||
wheelIncrementX = (wheelIncrementX < 0) ? jmin (wheelIncrementX, -1.0f) | |||||
: jmax (wheelIncrementX, 1.0f); | |||||
} | |||||
horizontalScrollBar.mouseWheelMove (e.getEventRelativeTo (&horizontalScrollBar), | |||||
wheelIncrementX, wheelIncrementY); | |||||
return true; | |||||
} | |||||
else if (hasVertBar && wheelIncrementY != 0) | |||||
{ | |||||
verticalScrollBar.mouseWheelMove (e.getEventRelativeTo (&verticalScrollBar), | |||||
wheelIncrementX, wheelIncrementY); | |||||
return true; | |||||
if (wheelIncrementY != 0) | |||||
{ | |||||
wheelIncrementY *= 14.0f * singleStepY; | |||||
wheelIncrementY = (wheelIncrementY < 0) ? jmin (wheelIncrementY, -1.0f) | |||||
: jmax (wheelIncrementY, 1.0f); | |||||
} | |||||
Point<int> pos (getViewPosition()); | |||||
if (wheelIncrementX != 0 && wheelIncrementY != 0 && hasHorzBar && hasVertBar) | |||||
{ | |||||
pos.setX (pos.getX() - roundToInt (wheelIncrementX)); | |||||
pos.setY (pos.getY() - roundToInt (wheelIncrementY)); | |||||
} | |||||
else if (hasHorzBar && (wheelIncrementX != 0 || e.mods.isShiftDown() || ! hasVertBar)) | |||||
{ | |||||
if (wheelIncrementX == 0 && ! hasVertBar) | |||||
wheelIncrementX = wheelIncrementY; | |||||
pos.setX (pos.getX() - roundToInt (wheelIncrementX)); | |||||
} | |||||
else if (hasVertBar && wheelIncrementY != 0) | |||||
{ | |||||
pos.setY (pos.getY() - roundToInt (wheelIncrementY)); | |||||
} | |||||
if (pos != getViewPosition()) | |||||
{ | |||||
setViewPosition (pos); | |||||
return true; | |||||
} | |||||
} | } | ||||
} | } | ||||
@@ -69297,7 +69325,7 @@ int PopupMenu::showMenu (const Rectangle<int>& target, | |||||
callback->component = Window::create (*this, ModifierKeys::getCurrentModifiers().isAnyMouseButtonDown(), | callback->component = Window::create (*this, ModifierKeys::getCurrentModifiers().isAnyMouseButtonDown(), | ||||
0, target, minimumWidth, maximumNumColumns > 0 ? maximumNumColumns : 7, | 0, target, minimumWidth, maximumNumColumns > 0 ? maximumNumColumns : 7, | ||||
standardItemHeight, alignToRectangle, 0, | |||||
standardItemHeight, alignToRectangle, itemIdThatMustBeVisible, | |||||
&callback->managerOfChosenCommand, componentAttachedTo); | &callback->managerOfChosenCommand, componentAttachedTo); | ||||
if (callback->component == 0) | if (callback->component == 0) | ||||
@@ -76449,10 +76477,35 @@ bool CallOutBox::hitTest (int x, int y) | |||||
return outline.contains ((float) x, (float) y); | return outline.contains ((float) x, (float) y); | ||||
} | } | ||||
enum { callOutBoxDismissCommandId = 0x4f83a04b }; | |||||
void CallOutBox::inputAttemptWhenModal() | void CallOutBox::inputAttemptWhenModal() | ||||
{ | { | ||||
exitModalState (0); | |||||
setVisible (false); | |||||
const Point<int> mousePos (getMouseXYRelative() + getBounds().getPosition()); | |||||
if (targetArea.contains (mousePos)) | |||||
{ | |||||
// if you click on the area that originally popped-up the callout, you expect it | |||||
// to get rid of the box, but deleting the box here allows the click to pass through and | |||||
// probably re-trigger it, so we need to dismiss the box asynchronously to consume the click.. | |||||
postCommandMessage (callOutBoxDismissCommandId); | |||||
} | |||||
else | |||||
{ | |||||
exitModalState (0); | |||||
setVisible (false); | |||||
} | |||||
} | |||||
void CallOutBox::handleCommandMessage (int commandId) | |||||
{ | |||||
Component::handleCommandMessage (commandId); | |||||
if (commandId == callOutBoxDismissCommandId) | |||||
{ | |||||
exitModalState (0); | |||||
setVisible (false); | |||||
} | |||||
} | } | ||||
bool CallOutBox::keyPressed (const KeyPress& key) | bool CallOutBox::keyPressed (const KeyPress& key) | ||||
@@ -82541,9 +82594,8 @@ private: | |||||
void setStartOfLine (float x, float y, const int numPixels) throw() | void setStartOfLine (float x, float y, const int numPixels) throw() | ||||
{ | { | ||||
float x1 = x, y1 = y; | float x1 = x, y1 = y; | ||||
inverseTransform.transformPoint (x1, y1); | |||||
x += numPixels; | x += numPixels; | ||||
inverseTransform.transformPoint (x, y); | |||||
inverseTransform.transformPoints (x1, y1, x, y); | |||||
xBresenham.set ((int) (x1 * 256.0f), (int) (x * 256.0f), numPixels); | xBresenham.set ((int) (x1 * 256.0f), (int) (x * 256.0f), numPixels); | ||||
yBresenham.set ((int) (y1 * 256.0f), (int) (y * 256.0f), numPixels); | yBresenham.set ((int) (y1 * 256.0f), (int) (y * 256.0f), numPixels); | ||||
@@ -85261,7 +85313,7 @@ BEGIN_JUCE_NAMESPACE | |||||
DrawablePath::DrawablePath() | DrawablePath::DrawablePath() | ||||
: mainFill (Colours::black), | : mainFill (Colours::black), | ||||
strokeFill (Colours::transparentBlack), | |||||
strokeFill (Colours::black), | |||||
strokeType (0.0f), | strokeType (0.0f), | ||||
pathNeedsUpdating (true), | pathNeedsUpdating (true), | ||||
strokeNeedsUpdating (true) | strokeNeedsUpdating (true) | ||||
@@ -86659,9 +86711,8 @@ private: | |||||
capStyle = PathStrokeType::square; | capStyle = PathStrokeType::square; | ||||
float ox = 0.0f, oy = 0.0f; | float ox = 0.0f, oy = 0.0f; | ||||
transform.transformPoint (ox, oy); | |||||
float x = getCoordLength (strokeWidth, viewBoxW), y = 0.0f; | float x = getCoordLength (strokeWidth, viewBoxW), y = 0.0f; | ||||
transform.transformPoint (x, y); | |||||
transform.transformPoints (ox, oy, x, y); | |||||
return PathStrokeType (strokeWidth.isNotEmpty() ? juce_hypotf (x - ox, y - oy) : 1.0f, | return PathStrokeType (strokeWidth.isNotEmpty() ? juce_hypotf (x - ox, y - oy) : 1.0f, | ||||
joinStyle, capStyle); | joinStyle, capStyle); | ||||
@@ -89412,22 +89463,6 @@ bool AffineTransform::isOnlyTranslation() const throw() | |||||
&& (mat11 == 1.0f); | && (mat11 == 1.0f); | ||||
} | } | ||||
void AffineTransform::transformPoint (float& x, | |||||
float& y) const throw() | |||||
{ | |||||
const float oldX = x; | |||||
x = mat00 * oldX + mat01 * y + mat02; | |||||
y = mat10 * oldX + mat11 * y + mat12; | |||||
} | |||||
void AffineTransform::transformPoint (double& x, | |||||
double& y) const throw() | |||||
{ | |||||
const double oldX = x; | |||||
x = mat00 * oldX + mat01 * y + mat02; | |||||
y = mat10 * oldX + mat11 * y + mat12; | |||||
} | |||||
END_JUCE_NAMESPACE | END_JUCE_NAMESPACE | ||||
/*** End of inlined file: juce_AffineTransform.cpp ***/ | /*** End of inlined file: juce_AffineTransform.cpp ***/ | ||||
@@ -90333,8 +90368,7 @@ void Path::addPath (const Path& other, | |||||
float y2 = other.data.elements [i++]; | float y2 = other.data.elements [i++]; | ||||
float x3 = other.data.elements [i++]; | float x3 = other.data.elements [i++]; | ||||
float y3 = other.data.elements [i++]; | float y3 = other.data.elements [i++]; | ||||
transformToApply.transformPoint (x2, y2); | |||||
transformToApply.transformPoint (x3, y3); | |||||
transformToApply.transformPoints (x2, y2, x3, y3); | |||||
cubicTo (x, y, x2, y2, x3, y3); | cubicTo (x, y, x2, y2, x3, y3); | ||||
} | } | ||||
@@ -90360,8 +90394,7 @@ void Path::applyTransform (const AffineTransform& transform) throw() | |||||
if (type == moveMarker) | if (type == moveMarker) | ||||
{ | { | ||||
transform.transformPoint (data.elements [i], | |||||
data.elements [i + 1]); | |||||
transform.transformPoint (data.elements [i], data.elements [i + 1]); | |||||
if (setMaxMin) | if (setMaxMin) | ||||
{ | { | ||||
@@ -90381,8 +90414,7 @@ void Path::applyTransform (const AffineTransform& transform) throw() | |||||
} | } | ||||
else if (type == lineMarker) | else if (type == lineMarker) | ||||
{ | { | ||||
transform.transformPoint (data.elements [i], | |||||
data.elements [i + 1]); | |||||
transform.transformPoint (data.elements [i], data.elements [i + 1]); | |||||
pathXMin = jmin (pathXMin, data.elements [i]); | pathXMin = jmin (pathXMin, data.elements [i]); | ||||
pathXMax = jmax (pathXMax, data.elements [i]); | pathXMax = jmax (pathXMax, data.elements [i]); | ||||
@@ -90393,11 +90425,8 @@ void Path::applyTransform (const AffineTransform& transform) throw() | |||||
} | } | ||||
else if (type == quadMarker) | else if (type == quadMarker) | ||||
{ | { | ||||
transform.transformPoint (data.elements [i], | |||||
data.elements [i + 1]); | |||||
transform.transformPoint (data.elements [i + 2], | |||||
data.elements [i + 3]); | |||||
transform.transformPoints (data.elements [i], data.elements [i + 1], | |||||
data.elements [i + 2], data.elements [i + 3]); | |||||
pathXMin = jmin (pathXMin, data.elements [i], data.elements [i + 2]); | pathXMin = jmin (pathXMin, data.elements [i], data.elements [i + 2]); | ||||
pathXMax = jmax (pathXMax, data.elements [i], data.elements [i + 2]); | pathXMax = jmax (pathXMax, data.elements [i], data.elements [i + 2]); | ||||
@@ -90408,14 +90437,9 @@ void Path::applyTransform (const AffineTransform& transform) throw() | |||||
} | } | ||||
else if (type == cubicMarker) | else if (type == cubicMarker) | ||||
{ | { | ||||
transform.transformPoint (data.elements [i], | |||||
data.elements [i + 1]); | |||||
transform.transformPoint (data.elements [i + 2], | |||||
data.elements [i + 3]); | |||||
transform.transformPoint (data.elements [i + 4], | |||||
data.elements [i + 5]); | |||||
transform.transformPoints (data.elements [i], data.elements [i + 1], | |||||
data.elements [i + 2], data.elements [i + 3], | |||||
data.elements [i + 4], data.elements [i + 5]); | |||||
pathXMin = jmin (pathXMin, data.elements [i], data.elements [i + 2], data.elements [i + 4]); | pathXMin = jmin (pathXMin, data.elements [i], data.elements [i + 2], data.elements [i + 4]); | ||||
pathXMax = jmax (pathXMax, data.elements [i], data.elements [i + 2], data.elements [i + 4]); | pathXMax = jmax (pathXMax, data.elements [i], data.elements [i + 2], data.elements [i + 4]); | ||||
@@ -91115,16 +91139,13 @@ bool PathFlatteningIterator::next() | |||||
x2 = points [index++]; | x2 = points [index++]; | ||||
y2 = points [index++]; | y2 = points [index++]; | ||||
if (! isIdentityTransform) | |||||
transform.transformPoint (x2, y2); | |||||
if (type == Path::quadMarker) | if (type == Path::quadMarker) | ||||
{ | { | ||||
x3 = points [index++]; | x3 = points [index++]; | ||||
y3 = points [index++]; | y3 = points [index++]; | ||||
if (! isIdentityTransform) | if (! isIdentityTransform) | ||||
transform.transformPoint (x3, y3); | |||||
transform.transformPoints (x2, y2, x3, y3); | |||||
} | } | ||||
else if (type == Path::cubicMarker) | else if (type == Path::cubicMarker) | ||||
{ | { | ||||
@@ -91134,10 +91155,12 @@ bool PathFlatteningIterator::next() | |||||
y4 = points [index++]; | y4 = points [index++]; | ||||
if (! isIdentityTransform) | if (! isIdentityTransform) | ||||
{ | |||||
transform.transformPoint (x3, y3); | |||||
transform.transformPoint (x4, y4); | |||||
} | |||||
transform.transformPoints (x2, y2, x3, y3, x4, y4); | |||||
} | |||||
else | |||||
{ | |||||
if (! isIdentityTransform) | |||||
transform.transformPoint (x2, y2); | |||||
} | } | ||||
} | } | ||||
} | } | ||||
@@ -241238,7 +241261,7 @@ void* MouseCursor::createStandardMouseCursor (const MouseCursor::StandardCursorT | |||||
{ | { | ||||
static const unsigned char dragHandData[] = | static const unsigned char dragHandData[] = | ||||
{ 71,73,70,56,57,97,16,0,16,0,145,2,0,0,0,0,255,255,255,0,0,0,0,0,0,33,249,4,1,0,0,2,0,44,0,0,0,0,16,0, | { 71,73,70,56,57,97,16,0,16,0,145,2,0,0,0,0,255,255,255,0,0,0,0,0,0,33,249,4,1,0,0,2,0,44,0,0,0,0,16,0, | ||||
16,0,0,2,52,148,47,0,200,185,16,130,90,12,74,139,107,84,123,39, 132,117,151,116,132,146,248,60,209,138, | |||||
16,0,0,2,52,148,47,0,200,185,16,130,90,12,74,139,107,84,123,39,132,117,151,116,132,146,248,60,209,138, | |||||
98,22,203,114,34,236,37,52,77,217,247,154,191,119,110,240,193,128,193,95,163,56,60,234,98,135,2,0,59 }; | 98,22,203,114,34,236,37,52,77,217,247,154,191,119,110,240,193,128,193,95,163,56,60,234,98,135,2,0,59 }; | ||||
dragHandCursor = createMouseCursorFromImage (ImageFileFormat::loadFrom (dragHandData, sizeof (dragHandData)), 8, 7); | dragHandCursor = createMouseCursorFromImage (ImageFileFormat::loadFrom (dragHandData, sizeof (dragHandData)), 8, 7); | ||||
@@ -241372,13 +241395,6 @@ private: | |||||
class JuceDataObject : public ComBaseClassHelper <IDataObject> | class JuceDataObject : public ComBaseClassHelper <IDataObject> | ||||
{ | { | ||||
JuceDropSource* const dropSource; | |||||
const FORMATETC* const format; | |||||
const STGMEDIUM* const medium; | |||||
JuceDataObject (const JuceDataObject&); | |||||
JuceDataObject& operator= (const JuceDataObject&); | |||||
public: | public: | ||||
JuceDataObject (JuceDropSource* const dropSource_, | JuceDataObject (JuceDropSource* const dropSource_, | ||||
const FORMATETC* const format_, | const FORMATETC* const format_, | ||||
@@ -241460,6 +241476,14 @@ public: | |||||
HRESULT __stdcall DAdvise (FORMATETC __RPC_FAR*, DWORD, IAdviseSink __RPC_FAR*, DWORD __RPC_FAR*) { return OLE_E_ADVISENOTSUPPORTED; } | HRESULT __stdcall DAdvise (FORMATETC __RPC_FAR*, DWORD, IAdviseSink __RPC_FAR*, DWORD __RPC_FAR*) { return OLE_E_ADVISENOTSUPPORTED; } | ||||
HRESULT __stdcall DUnadvise (DWORD) { return E_NOTIMPL; } | HRESULT __stdcall DUnadvise (DWORD) { return E_NOTIMPL; } | ||||
HRESULT __stdcall EnumDAdvise (IEnumSTATDATA __RPC_FAR *__RPC_FAR *) { return OLE_E_ADVISENOTSUPPORTED; } | HRESULT __stdcall EnumDAdvise (IEnumSTATDATA __RPC_FAR *__RPC_FAR *) { return OLE_E_ADVISENOTSUPPORTED; } | ||||
private: | |||||
JuceDropSource* const dropSource; | |||||
const FORMATETC* const format; | |||||
const STGMEDIUM* const medium; | |||||
JuceDataObject (const JuceDataObject&); | |||||
JuceDataObject& operator= (const JuceDataObject&); | |||||
}; | }; | ||||
static HDROP createHDrop (const StringArray& fileNames) throw() | static HDROP createHDrop (const StringArray& fileNames) throw() | ||||
@@ -249004,60 +249028,24 @@ static const String getDSErrorMessage (HRESULT hr) | |||||
switch (hr) | switch (hr) | ||||
{ | { | ||||
case MAKE_HRESULT(1, 0x878, 10): | |||||
result = "Device already allocated"; | |||||
break; | |||||
case MAKE_HRESULT(1, 0x878, 30): | |||||
result = "Control unavailable"; | |||||
break; | |||||
case E_INVALIDARG: | |||||
result = "Invalid parameter"; | |||||
break; | |||||
case MAKE_HRESULT(1, 0x878, 50): | |||||
result = "Invalid call"; | |||||
break; | |||||
case E_FAIL: | |||||
result = "Generic error"; | |||||
break; | |||||
case MAKE_HRESULT(1, 0x878, 70): | |||||
result = "Priority level error"; | |||||
break; | |||||
case E_OUTOFMEMORY: | |||||
result = "Out of memory"; | |||||
break; | |||||
case MAKE_HRESULT(1, 0x878, 100): | |||||
result = "Bad format"; | |||||
break; | |||||
case E_NOTIMPL: | |||||
result = "Unsupported function"; | |||||
break; | |||||
case MAKE_HRESULT(1, 0x878, 120): | |||||
result = "No driver"; | |||||
break; | |||||
case MAKE_HRESULT(1, 0x878, 130): | |||||
result = "Already initialised"; | |||||
break; | |||||
case CLASS_E_NOAGGREGATION: | |||||
result = "No aggregation"; | |||||
break; | |||||
case MAKE_HRESULT(1, 0x878, 150): | |||||
result = "Buffer lost"; | |||||
break; | |||||
case MAKE_HRESULT(1, 0x878, 160): | |||||
result = "Another app has priority"; | |||||
break; | |||||
case MAKE_HRESULT(1, 0x878, 170): | |||||
result = "Uninitialised"; | |||||
break; | |||||
case E_NOINTERFACE: | |||||
result = "No interface"; | |||||
break; | |||||
case S_OK: | |||||
result = "No error"; | |||||
break; | |||||
default: | |||||
return "Unknown error: " + String ((int) hr); | |||||
case MAKE_HRESULT(1, 0x878, 10): result = "Device already allocated"; break; | |||||
case MAKE_HRESULT(1, 0x878, 30): result = "Control unavailable"; break; | |||||
case E_INVALIDARG: result = "Invalid parameter"; break; | |||||
case MAKE_HRESULT(1, 0x878, 50): result = "Invalid call"; break; | |||||
case E_FAIL: result = "Generic error"; break; | |||||
case MAKE_HRESULT(1, 0x878, 70): result = "Priority level error"; break; | |||||
case E_OUTOFMEMORY: result = "Out of memory"; break; | |||||
case MAKE_HRESULT(1, 0x878, 100): result = "Bad format"; break; | |||||
case E_NOTIMPL: result = "Unsupported function"; break; | |||||
case MAKE_HRESULT(1, 0x878, 120): result = "No driver"; break; | |||||
case MAKE_HRESULT(1, 0x878, 130): result = "Already initialised"; break; | |||||
case CLASS_E_NOAGGREGATION: result = "No aggregation"; break; | |||||
case MAKE_HRESULT(1, 0x878, 150): result = "Buffer lost"; break; | |||||
case MAKE_HRESULT(1, 0x878, 160): result = "Another app has priority"; break; | |||||
case MAKE_HRESULT(1, 0x878, 170): result = "Uninitialised"; break; | |||||
case E_NOINTERFACE: result = "No interface"; break; | |||||
case S_OK: result = "No error"; break; | |||||
default: return "Unknown error: " + String ((int) hr); | |||||
} | } | ||||
return result; | return result; | ||||
@@ -258647,7 +258635,8 @@ public: | |||||
GLXContext sharedContext) | GLXContext sharedContext) | ||||
: renderContext (0), | : renderContext (0), | ||||
embeddedWindow (0), | embeddedWindow (0), | ||||
pixelFormat (pixelFormat_) | |||||
pixelFormat (pixelFormat_), | |||||
swapInterval (0) | |||||
{ | { | ||||
jassert (component != 0); | jassert (component != 0); | ||||
LinuxComponentPeer* const peer = dynamic_cast <LinuxComponentPeer*> (component->getTopLevelComponent()->getPeer()); | LinuxComponentPeer* const peer = dynamic_cast <LinuxComponentPeer*> (component->getTopLevelComponent()->getPeer()); | ||||
@@ -258775,14 +258764,21 @@ public: | |||||
bool setSwapInterval (const int numFramesPerSwap) | bool setSwapInterval (const int numFramesPerSwap) | ||||
{ | { | ||||
// xxx needs doing.. | |||||
static PFNGLXSWAPINTERVALSGIPROC GLXSwapIntervalSGI = (PFNGLXSWAPINTERVALSGIPROC) glXGetProcAddress ((const GLubyte*) "glXSwapIntervalSGI"); | |||||
if (GLXSwapIntervalSGI != 0) | |||||
{ | |||||
swapInterval = numFramesPerSwap; | |||||
GLXSwapIntervalSGI (numFramesPerSwap); | |||||
return true; | |||||
} | |||||
return false; | return false; | ||||
} | } | ||||
int getSwapInterval() const | int getSwapInterval() const | ||||
{ | { | ||||
// xxx needs doing.. | |||||
return 0; | |||||
return swapInterval; | |||||
} | } | ||||
void repaint() | void repaint() | ||||
@@ -258796,6 +258792,7 @@ public: | |||||
private: | private: | ||||
Window embeddedWindow; | Window embeddedWindow; | ||||
OpenGLPixelFormat pixelFormat; | OpenGLPixelFormat pixelFormat; | ||||
int swapInterval; | |||||
WindowedGLContext (const WindowedGLContext&); | WindowedGLContext (const WindowedGLContext&); | ||||
WindowedGLContext& operator= (const WindowedGLContext&); | WindowedGLContext& operator= (const WindowedGLContext&); | ||||
@@ -264943,14 +264940,11 @@ private: | |||||
CGContextAddLineToPoint (context, i.x1, flipHeight - i.y1); | CGContextAddLineToPoint (context, i.x1, flipHeight - i.y1); | ||||
break; | break; | ||||
case Path::Iterator::quadraticTo: | case Path::Iterator::quadraticTo: | ||||
transform.transformPoint (i.x1, i.y1); | |||||
transform.transformPoint (i.x2, i.y2); | |||||
transform.transformPoints (i.x1, i.y1, i.x2, i.y2); | |||||
CGContextAddQuadCurveToPoint (context, i.x1, flipHeight - i.y1, i.x2, flipHeight - i.y2); | CGContextAddQuadCurveToPoint (context, i.x1, flipHeight - i.y1, i.x2, flipHeight - i.y2); | ||||
break; | break; | ||||
case Path::Iterator::cubicTo: | case Path::Iterator::cubicTo: | ||||
transform.transformPoint (i.x1, i.y1); | |||||
transform.transformPoint (i.x2, i.y2); | |||||
transform.transformPoint (i.x3, i.y3); | |||||
transform.transformPoints (i.x1, i.y1, i.x2, i.y2, i.x3, i.y3); | |||||
CGContextAddCurveToPoint (context, i.x1, flipHeight - i.y1, i.x2, flipHeight - i.y2, i.x3, flipHeight - i.y3); | CGContextAddCurveToPoint (context, i.x1, flipHeight - i.y1, i.x2, flipHeight - i.y2, i.x3, flipHeight - i.y3); | ||||
break; | break; | ||||
case Path::Iterator::closePath: | case Path::Iterator::closePath: | ||||
@@ -269590,14 +269584,11 @@ private: | |||||
CGContextAddLineToPoint (context, i.x1, flipHeight - i.y1); | CGContextAddLineToPoint (context, i.x1, flipHeight - i.y1); | ||||
break; | break; | ||||
case Path::Iterator::quadraticTo: | case Path::Iterator::quadraticTo: | ||||
transform.transformPoint (i.x1, i.y1); | |||||
transform.transformPoint (i.x2, i.y2); | |||||
transform.transformPoints (i.x1, i.y1, i.x2, i.y2); | |||||
CGContextAddQuadCurveToPoint (context, i.x1, flipHeight - i.y1, i.x2, flipHeight - i.y2); | CGContextAddQuadCurveToPoint (context, i.x1, flipHeight - i.y1, i.x2, flipHeight - i.y2); | ||||
break; | break; | ||||
case Path::Iterator::cubicTo: | case Path::Iterator::cubicTo: | ||||
transform.transformPoint (i.x1, i.y1); | |||||
transform.transformPoint (i.x2, i.y2); | |||||
transform.transformPoint (i.x3, i.y3); | |||||
transform.transformPoints (i.x1, i.y1, i.x2, i.y2, i.x3, i.y3); | |||||
CGContextAddCurveToPoint (context, i.x1, flipHeight - i.y1, i.x2, flipHeight - i.y2, i.x3, flipHeight - i.y3); | CGContextAddCurveToPoint (context, i.x1, flipHeight - i.y1, i.x2, flipHeight - i.y2, i.x3, flipHeight - i.y3); | ||||
break; | break; | ||||
case Path::Iterator::closePath: | case Path::Iterator::closePath: | ||||
@@ -269649,6 +269640,11 @@ class NSViewComponentPeer; | |||||
END_JUCE_NAMESPACE | END_JUCE_NAMESPACE | ||||
@interface NSEvent (JuceDeviceDelta) | |||||
- (float) deviceDeltaX; | |||||
- (float) deviceDeltaY; | |||||
@end | |||||
#define JuceNSView MakeObjCClassName(JuceNSView) | #define JuceNSView MakeObjCClassName(JuceNSView) | ||||
@interface JuceNSView : NSView<NSTextInput> | @interface JuceNSView : NSView<NSTextInput> | ||||
@@ -271019,8 +271015,20 @@ void NSViewComponentPeer::redirectMouseWheel (NSEvent* ev) | |||||
{ | { | ||||
updateModifiers (ev); | updateModifiers (ev); | ||||
handleMouseWheel (0, getMousePos (ev, view), getMouseTime (ev), | |||||
[ev deltaX] * 10.0f, [ev deltaY] * 10.0f); | |||||
float x = 0, y = 0; | |||||
@try | |||||
{ | |||||
x = [ev deviceDeltaX] * 0.5f; | |||||
y = [ev deviceDeltaY] * 0.5f; | |||||
} | |||||
@catch (...) | |||||
{ | |||||
x = [ev deltaX] * 10.0f; | |||||
y = [ev deltaY] * 10.0f; | |||||
} | |||||
handleMouseWheel (0, getMousePos (ev, view), getMouseTime (ev), x, y); | |||||
} | } | ||||
void NSViewComponentPeer::showArrowCursorIfNeeded() | void NSViewComponentPeer::showArrowCursorIfNeeded() | ||||
@@ -64,7 +64,7 @@ | |||||
*/ | */ | ||||
#define JUCE_MAJOR_VERSION 1 | #define JUCE_MAJOR_VERSION 1 | ||||
#define JUCE_MINOR_VERSION 52 | #define JUCE_MINOR_VERSION 52 | ||||
#define JUCE_BUILDNUMBER 21 | |||||
#define JUCE_BUILDNUMBER 22 | |||||
/** Current Juce version number. | /** Current Juce version number. | ||||
@@ -18900,12 +18900,48 @@ public: | |||||
static const AffineTransform identity; | static const AffineTransform identity; | ||||
/** Transforms a 2D co-ordinate using this matrix. */ | /** Transforms a 2D co-ordinate using this matrix. */ | ||||
void transformPoint (float& x, | |||||
float& y) const throw(); | |||||
template <typename ValueType> | |||||
void transformPoint (ValueType& x, ValueType& y) const throw() | |||||
{ | |||||
const ValueType oldX = x; | |||||
x = static_cast <ValueType> (mat00 * oldX + mat01 * y + mat02); | |||||
y = static_cast <ValueType> (mat10 * oldX + mat11 * y + mat12); | |||||
} | |||||
/** Transforms a 2D co-ordinate using this matrix. */ | |||||
void transformPoint (double& x, | |||||
double& y) const throw(); | |||||
/** Transforms two 2D co-ordinates using this matrix. | |||||
This is just a shortcut for calling transformPoint() on each of these pairs of | |||||
coordinates in turn. (And putting all the calculations into one function hopefully | |||||
also gives the compiler a bit more scope for pipelining it). | |||||
*/ | |||||
template <typename ValueType> | |||||
void transformPoints (ValueType& x1, ValueType& y1, | |||||
ValueType& x2, ValueType& y2) const throw() | |||||
{ | |||||
const ValueType oldX1 = x1, oldX2 = x2; | |||||
x1 = static_cast <ValueType> (mat00 * oldX1 + mat01 * y1 + mat02); | |||||
y1 = static_cast <ValueType> (mat10 * oldX1 + mat11 * y1 + mat12); | |||||
x2 = static_cast <ValueType> (mat00 * oldX2 + mat01 * y2 + mat02); | |||||
y2 = static_cast <ValueType> (mat10 * oldX2 + mat11 * y2 + mat12); | |||||
} | |||||
/** Transforms three 2D co-ordinates using this matrix. | |||||
This is just a shortcut for calling transformPoint() on each of these pairs of | |||||
coordinates in turn. (And putting all the calculations into one function hopefully | |||||
also gives the compiler a bit more scope for pipelining it). | |||||
*/ | |||||
template <typename ValueType> | |||||
void transformPoints (ValueType& x1, ValueType& y1, | |||||
ValueType& x2, ValueType& y2, | |||||
ValueType& x3, ValueType& y3) const throw() | |||||
{ | |||||
const ValueType oldX1 = x1, oldX2 = x2, oldX3 = x3; | |||||
x1 = static_cast <ValueType> (mat00 * oldX1 + mat01 * y1 + mat02); | |||||
y1 = static_cast <ValueType> (mat10 * oldX1 + mat11 * y1 + mat12); | |||||
x2 = static_cast <ValueType> (mat00 * oldX2 + mat01 * y2 + mat02); | |||||
y2 = static_cast <ValueType> (mat10 * oldX2 + mat11 * y2 + mat12); | |||||
x3 = static_cast <ValueType> (mat00 * oldX3 + mat01 * y3 + mat02); | |||||
y3 = static_cast <ValueType> (mat10 * oldX3 + mat11 * y3 + mat12); | |||||
} | |||||
/** Returns a new transform which is the same as this one followed by a translation. */ | /** Returns a new transform which is the same as this one followed by a translation. */ | ||||
const AffineTransform translated (float deltaX, | const AffineTransform translated (float deltaX, | ||||
@@ -19145,7 +19181,8 @@ public: | |||||
void applyTransform (const AffineTransform& transform) throw() { transform.transformPoint (x, y); } | void applyTransform (const AffineTransform& transform) throw() { transform.transformPoint (x, y); } | ||||
/** Returns the position of this point, if it is transformed by a given AffineTransform. */ | /** Returns the position of this point, if it is transformed by a given AffineTransform. */ | ||||
const Point transformedBy (const AffineTransform& transform) const throw() { ValueType x2 (x), y2 (y); transform.transformPoint (x2, y2); return Point (x2, y2); } | |||||
const Point transformedBy (const AffineTransform& transform) const throw() { return Point (transform.mat00 * x + transform.mat01 * y + transform.mat02, | |||||
transform.mat10 * x + transform.mat11 * y + transform.mat12); } | |||||
/** Casts this point to a Point<float> object. */ | /** Casts this point to a Point<float> object. */ | ||||
const Point<float> toFloat() const throw() { return Point<float> (static_cast <float> (x), static_cast<float> (y)); } | const Point<float> toFloat() const throw() { return Point<float> (static_cast <float> (x), static_cast<float> (y)); } | ||||
@@ -20720,10 +20757,8 @@ public: | |||||
float x3 = x, y3 = y + h; | float x3 = x, y3 = y + h; | ||||
float x4 = x2, y4 = y3; | float x4 = x2, y4 = y3; | ||||
transform.transformPoint (x1, y1); | |||||
transform.transformPoint (x2, y2); | |||||
transform.transformPoint (x3, y3); | |||||
transform.transformPoint (x4, y4); | |||||
transform.transformPoints (x1, y1, x2, y2); | |||||
transform.transformPoints (x3, y3, x4, y4); | |||||
const float rx = jmin (x1, x2, x3, x4); | const float rx = jmin (x1, x2, x3, x4); | ||||
const float ry = jmin (y1, y2, y3, y4); | const float ry = jmin (y1, y2, y3, y4); | ||||
@@ -57394,6 +57429,8 @@ public: | |||||
void inputAttemptWhenModal(); | void inputAttemptWhenModal(); | ||||
/** @internal */ | /** @internal */ | ||||
bool keyPressed (const KeyPress& key); | bool keyPressed (const KeyPress& key); | ||||
/** @internal */ | |||||
void handleCommandMessage (int commandId); | |||||
juce_UseDebuggingNewOperator | juce_UseDebuggingNewOperator | ||||
@@ -33,7 +33,7 @@ | |||||
*/ | */ | ||||
#define JUCE_MAJOR_VERSION 1 | #define JUCE_MAJOR_VERSION 1 | ||||
#define JUCE_MINOR_VERSION 52 | #define JUCE_MINOR_VERSION 52 | ||||
#define JUCE_BUILDNUMBER 21 | |||||
#define JUCE_BUILDNUMBER 22 | |||||
/** Current Juce version number. | /** Current Juce version number. | ||||
@@ -223,6 +223,7 @@ void Viewport::updateVisibleArea() | |||||
horizontalScrollBar.setRangeLimits (0.0, contentBounds.getWidth()); | horizontalScrollBar.setRangeLimits (0.0, contentBounds.getWidth()); | ||||
horizontalScrollBar.setCurrentRange (visibleOrigin.getX(), contentArea.getWidth()); | horizontalScrollBar.setCurrentRange (visibleOrigin.getX(), contentArea.getWidth()); | ||||
horizontalScrollBar.setSingleStepSize (singleStepX); | horizontalScrollBar.setSingleStepSize (singleStepX); | ||||
horizontalScrollBar.cancelPendingUpdate(); | |||||
} | } | ||||
if (vBarVisible) | if (vBarVisible) | ||||
@@ -231,6 +232,7 @@ void Viewport::updateVisibleArea() | |||||
verticalScrollBar.setRangeLimits (0.0, contentBounds.getHeight()); | verticalScrollBar.setRangeLimits (0.0, contentBounds.getHeight()); | ||||
verticalScrollBar.setCurrentRange (visibleOrigin.getY(), contentArea.getHeight()); | verticalScrollBar.setCurrentRange (visibleOrigin.getY(), contentArea.getHeight()); | ||||
verticalScrollBar.setSingleStepSize (singleStepY); | verticalScrollBar.setSingleStepSize (singleStepY); | ||||
verticalScrollBar.cancelPendingUpdate(); | |||||
} | } | ||||
// Force the visibility *after* setting the ranges to avoid flicker caused by edge conditions in the numbers. | // Force the visibility *after* setting the ranges to avoid flicker caused by edge conditions in the numbers. | ||||
@@ -322,20 +324,46 @@ bool Viewport::useMouseWheelMoveIfNeeded (const MouseEvent& e, float wheelIncrem | |||||
const bool hasVertBar = verticalScrollBar.isVisible(); | const bool hasVertBar = verticalScrollBar.isVisible(); | ||||
const bool hasHorzBar = horizontalScrollBar.isVisible(); | const bool hasHorzBar = horizontalScrollBar.isVisible(); | ||||
if (hasHorzBar && (wheelIncrementX != 0 || e.mods.isShiftDown() || ! hasVertBar)) | |||||
if (hasHorzBar || hasVertBar) | |||||
{ | { | ||||
if (wheelIncrementX == 0 && ! hasVertBar) | |||||
wheelIncrementX = wheelIncrementY; | |||||
horizontalScrollBar.mouseWheelMove (e.getEventRelativeTo (&horizontalScrollBar), | |||||
wheelIncrementX, wheelIncrementY); | |||||
return true; | |||||
} | |||||
else if (hasVertBar && wheelIncrementY != 0) | |||||
{ | |||||
verticalScrollBar.mouseWheelMove (e.getEventRelativeTo (&verticalScrollBar), | |||||
wheelIncrementX, wheelIncrementY); | |||||
return true; | |||||
if (wheelIncrementX != 0) | |||||
{ | |||||
wheelIncrementX *= 14.0f * singleStepX; | |||||
wheelIncrementX = (wheelIncrementX < 0) ? jmin (wheelIncrementX, -1.0f) | |||||
: jmax (wheelIncrementX, 1.0f); | |||||
} | |||||
if (wheelIncrementY != 0) | |||||
{ | |||||
wheelIncrementY *= 14.0f * singleStepY; | |||||
wheelIncrementY = (wheelIncrementY < 0) ? jmin (wheelIncrementY, -1.0f) | |||||
: jmax (wheelIncrementY, 1.0f); | |||||
} | |||||
Point<int> pos (getViewPosition()); | |||||
if (wheelIncrementX != 0 && wheelIncrementY != 0 && hasHorzBar && hasVertBar) | |||||
{ | |||||
pos.setX (pos.getX() - roundToInt (wheelIncrementX)); | |||||
pos.setY (pos.getY() - roundToInt (wheelIncrementY)); | |||||
} | |||||
else if (hasHorzBar && (wheelIncrementX != 0 || e.mods.isShiftDown() || ! hasVertBar)) | |||||
{ | |||||
if (wheelIncrementX == 0 && ! hasVertBar) | |||||
wheelIncrementX = wheelIncrementY; | |||||
pos.setX (pos.getX() - roundToInt (wheelIncrementX)); | |||||
} | |||||
else if (hasVertBar && wheelIncrementY != 0) | |||||
{ | |||||
pos.setY (pos.getY() - roundToInt (wheelIncrementY)); | |||||
} | |||||
if (pos != getViewPosition()) | |||||
{ | |||||
setViewPosition (pos); | |||||
return true; | |||||
} | |||||
} | } | ||||
} | } | ||||
@@ -1533,7 +1533,7 @@ int PopupMenu::showMenu (const Rectangle<int>& target, | |||||
callback->component = Window::create (*this, ModifierKeys::getCurrentModifiers().isAnyMouseButtonDown(), | callback->component = Window::create (*this, ModifierKeys::getCurrentModifiers().isAnyMouseButtonDown(), | ||||
0, target, minimumWidth, maximumNumColumns > 0 ? maximumNumColumns : 7, | 0, target, minimumWidth, maximumNumColumns > 0 ? maximumNumColumns : 7, | ||||
standardItemHeight, alignToRectangle, 0, | |||||
standardItemHeight, alignToRectangle, itemIdThatMustBeVisible, | |||||
&callback->managerOfChosenCommand, componentAttachedTo); | &callback->managerOfChosenCommand, componentAttachedTo); | ||||
if (callback->component == 0) | if (callback->component == 0) | ||||
@@ -103,10 +103,35 @@ bool CallOutBox::hitTest (int x, int y) | |||||
return outline.contains ((float) x, (float) y); | return outline.contains ((float) x, (float) y); | ||||
} | } | ||||
enum { callOutBoxDismissCommandId = 0x4f83a04b }; | |||||
void CallOutBox::inputAttemptWhenModal() | void CallOutBox::inputAttemptWhenModal() | ||||
{ | { | ||||
exitModalState (0); | |||||
setVisible (false); | |||||
const Point<int> mousePos (getMouseXYRelative() + getBounds().getPosition()); | |||||
if (targetArea.contains (mousePos)) | |||||
{ | |||||
// if you click on the area that originally popped-up the callout, you expect it | |||||
// to get rid of the box, but deleting the box here allows the click to pass through and | |||||
// probably re-trigger it, so we need to dismiss the box asynchronously to consume the click.. | |||||
postCommandMessage (callOutBoxDismissCommandId); | |||||
} | |||||
else | |||||
{ | |||||
exitModalState (0); | |||||
setVisible (false); | |||||
} | |||||
} | |||||
void CallOutBox::handleCommandMessage (int commandId) | |||||
{ | |||||
Component::handleCommandMessage (commandId); | |||||
if (commandId == callOutBoxDismissCommandId) | |||||
{ | |||||
exitModalState (0); | |||||
setVisible (false); | |||||
} | |||||
} | } | ||||
bool CallOutBox::keyPressed (const KeyPress& key) | bool CallOutBox::keyPressed (const KeyPress& key) | ||||
@@ -105,6 +105,8 @@ public: | |||||
void inputAttemptWhenModal(); | void inputAttemptWhenModal(); | ||||
/** @internal */ | /** @internal */ | ||||
bool keyPressed (const KeyPress& key); | bool keyPressed (const KeyPress& key); | ||||
/** @internal */ | |||||
void handleCommandMessage (int commandId); | |||||
juce_UseDebuggingNewOperator | juce_UseDebuggingNewOperator | ||||
@@ -889,9 +889,8 @@ private: | |||||
void setStartOfLine (float x, float y, const int numPixels) throw() | void setStartOfLine (float x, float y, const int numPixels) throw() | ||||
{ | { | ||||
float x1 = x, y1 = y; | float x1 = x, y1 = y; | ||||
inverseTransform.transformPoint (x1, y1); | |||||
x += numPixels; | x += numPixels; | ||||
inverseTransform.transformPoint (x, y); | |||||
inverseTransform.transformPoints (x1, y1, x, y); | |||||
xBresenham.set ((int) (x1 * 256.0f), (int) (x * 256.0f), numPixels); | xBresenham.set ((int) (x1 * 256.0f), (int) (x * 256.0f), numPixels); | ||||
yBresenham.set ((int) (y1 * 256.0f), (int) (y * 256.0f), numPixels); | yBresenham.set ((int) (y1 * 256.0f), (int) (y * 256.0f), numPixels); | ||||
@@ -35,7 +35,7 @@ BEGIN_JUCE_NAMESPACE | |||||
//============================================================================== | //============================================================================== | ||||
DrawablePath::DrawablePath() | DrawablePath::DrawablePath() | ||||
: mainFill (Colours::black), | : mainFill (Colours::black), | ||||
strokeFill (Colours::transparentBlack), | |||||
strokeFill (Colours::black), | |||||
strokeType (0.0f), | strokeType (0.0f), | ||||
pathNeedsUpdating (true), | pathNeedsUpdating (true), | ||||
strokeNeedsUpdating (true) | strokeNeedsUpdating (true) | ||||
@@ -801,9 +801,8 @@ private: | |||||
capStyle = PathStrokeType::square; | capStyle = PathStrokeType::square; | ||||
float ox = 0.0f, oy = 0.0f; | float ox = 0.0f, oy = 0.0f; | ||||
transform.transformPoint (ox, oy); | |||||
float x = getCoordLength (strokeWidth, viewBoxW), y = 0.0f; | float x = getCoordLength (strokeWidth, viewBoxW), y = 0.0f; | ||||
transform.transformPoint (x, y); | |||||
transform.transformPoints (ox, oy, x, y); | |||||
return PathStrokeType (strokeWidth.isNotEmpty() ? juce_hypotf (x - ox, y - oy) : 1.0f, | return PathStrokeType (strokeWidth.isNotEmpty() ? juce_hypotf (x - ox, y - oy) : 1.0f, | ||||
joinStyle, capStyle); | joinStyle, capStyle); | ||||
@@ -257,22 +257,5 @@ bool AffineTransform::isOnlyTranslation() const throw() | |||||
&& (mat11 == 1.0f); | && (mat11 == 1.0f); | ||||
} | } | ||||
//============================================================================== | |||||
void AffineTransform::transformPoint (float& x, | |||||
float& y) const throw() | |||||
{ | |||||
const float oldX = x; | |||||
x = mat00 * oldX + mat01 * y + mat02; | |||||
y = mat10 * oldX + mat11 * y + mat12; | |||||
} | |||||
void AffineTransform::transformPoint (double& x, | |||||
double& y) const throw() | |||||
{ | |||||
const double oldX = x; | |||||
x = mat00 * oldX + mat01 * y + mat02; | |||||
y = mat10 * oldX + mat11 * y + mat12; | |||||
} | |||||
END_JUCE_NAMESPACE | END_JUCE_NAMESPACE |
@@ -81,12 +81,48 @@ public: | |||||
//============================================================================== | //============================================================================== | ||||
/** Transforms a 2D co-ordinate using this matrix. */ | /** Transforms a 2D co-ordinate using this matrix. */ | ||||
void transformPoint (float& x, | |||||
float& y) const throw(); | |||||
/** Transforms a 2D co-ordinate using this matrix. */ | |||||
void transformPoint (double& x, | |||||
double& y) const throw(); | |||||
template <typename ValueType> | |||||
void transformPoint (ValueType& x, ValueType& y) const throw() | |||||
{ | |||||
const ValueType oldX = x; | |||||
x = static_cast <ValueType> (mat00 * oldX + mat01 * y + mat02); | |||||
y = static_cast <ValueType> (mat10 * oldX + mat11 * y + mat12); | |||||
} | |||||
/** Transforms two 2D co-ordinates using this matrix. | |||||
This is just a shortcut for calling transformPoint() on each of these pairs of | |||||
coordinates in turn. (And putting all the calculations into one function hopefully | |||||
also gives the compiler a bit more scope for pipelining it). | |||||
*/ | |||||
template <typename ValueType> | |||||
void transformPoints (ValueType& x1, ValueType& y1, | |||||
ValueType& x2, ValueType& y2) const throw() | |||||
{ | |||||
const ValueType oldX1 = x1, oldX2 = x2; | |||||
x1 = static_cast <ValueType> (mat00 * oldX1 + mat01 * y1 + mat02); | |||||
y1 = static_cast <ValueType> (mat10 * oldX1 + mat11 * y1 + mat12); | |||||
x2 = static_cast <ValueType> (mat00 * oldX2 + mat01 * y2 + mat02); | |||||
y2 = static_cast <ValueType> (mat10 * oldX2 + mat11 * y2 + mat12); | |||||
} | |||||
/** Transforms three 2D co-ordinates using this matrix. | |||||
This is just a shortcut for calling transformPoint() on each of these pairs of | |||||
coordinates in turn. (And putting all the calculations into one function hopefully | |||||
also gives the compiler a bit more scope for pipelining it). | |||||
*/ | |||||
template <typename ValueType> | |||||
void transformPoints (ValueType& x1, ValueType& y1, | |||||
ValueType& x2, ValueType& y2, | |||||
ValueType& x3, ValueType& y3) const throw() | |||||
{ | |||||
const ValueType oldX1 = x1, oldX2 = x2, oldX3 = x3; | |||||
x1 = static_cast <ValueType> (mat00 * oldX1 + mat01 * y1 + mat02); | |||||
y1 = static_cast <ValueType> (mat10 * oldX1 + mat11 * y1 + mat12); | |||||
x2 = static_cast <ValueType> (mat00 * oldX2 + mat01 * y2 + mat02); | |||||
y2 = static_cast <ValueType> (mat10 * oldX2 + mat11 * y2 + mat12); | |||||
x3 = static_cast <ValueType> (mat00 * oldX3 + mat01 * y3 + mat02); | |||||
y3 = static_cast <ValueType> (mat10 * oldX3 + mat11 * y3 + mat12); | |||||
} | |||||
//============================================================================== | //============================================================================== | ||||
/** Returns a new transform which is the same as this one followed by a translation. */ | /** Returns a new transform which is the same as this one followed by a translation. */ | ||||
@@ -829,8 +829,7 @@ void Path::addPath (const Path& other, | |||||
float y2 = other.data.elements [i++]; | float y2 = other.data.elements [i++]; | ||||
float x3 = other.data.elements [i++]; | float x3 = other.data.elements [i++]; | ||||
float y3 = other.data.elements [i++]; | float y3 = other.data.elements [i++]; | ||||
transformToApply.transformPoint (x2, y2); | |||||
transformToApply.transformPoint (x3, y3); | |||||
transformToApply.transformPoints (x2, y2, x3, y3); | |||||
cubicTo (x, y, x2, y2, x3, y3); | cubicTo (x, y, x2, y2, x3, y3); | ||||
} | } | ||||
@@ -857,8 +856,7 @@ void Path::applyTransform (const AffineTransform& transform) throw() | |||||
if (type == moveMarker) | if (type == moveMarker) | ||||
{ | { | ||||
transform.transformPoint (data.elements [i], | |||||
data.elements [i + 1]); | |||||
transform.transformPoint (data.elements [i], data.elements [i + 1]); | |||||
if (setMaxMin) | if (setMaxMin) | ||||
{ | { | ||||
@@ -878,8 +876,7 @@ void Path::applyTransform (const AffineTransform& transform) throw() | |||||
} | } | ||||
else if (type == lineMarker) | else if (type == lineMarker) | ||||
{ | { | ||||
transform.transformPoint (data.elements [i], | |||||
data.elements [i + 1]); | |||||
transform.transformPoint (data.elements [i], data.elements [i + 1]); | |||||
pathXMin = jmin (pathXMin, data.elements [i]); | pathXMin = jmin (pathXMin, data.elements [i]); | ||||
pathXMax = jmax (pathXMax, data.elements [i]); | pathXMax = jmax (pathXMax, data.elements [i]); | ||||
@@ -890,11 +887,8 @@ void Path::applyTransform (const AffineTransform& transform) throw() | |||||
} | } | ||||
else if (type == quadMarker) | else if (type == quadMarker) | ||||
{ | { | ||||
transform.transformPoint (data.elements [i], | |||||
data.elements [i + 1]); | |||||
transform.transformPoint (data.elements [i + 2], | |||||
data.elements [i + 3]); | |||||
transform.transformPoints (data.elements [i], data.elements [i + 1], | |||||
data.elements [i + 2], data.elements [i + 3]); | |||||
pathXMin = jmin (pathXMin, data.elements [i], data.elements [i + 2]); | pathXMin = jmin (pathXMin, data.elements [i], data.elements [i + 2]); | ||||
pathXMax = jmax (pathXMax, data.elements [i], data.elements [i + 2]); | pathXMax = jmax (pathXMax, data.elements [i], data.elements [i + 2]); | ||||
@@ -905,14 +899,9 @@ void Path::applyTransform (const AffineTransform& transform) throw() | |||||
} | } | ||||
else if (type == cubicMarker) | else if (type == cubicMarker) | ||||
{ | { | ||||
transform.transformPoint (data.elements [i], | |||||
data.elements [i + 1]); | |||||
transform.transformPoint (data.elements [i + 2], | |||||
data.elements [i + 3]); | |||||
transform.transformPoint (data.elements [i + 4], | |||||
data.elements [i + 5]); | |||||
transform.transformPoints (data.elements [i], data.elements [i + 1], | |||||
data.elements [i + 2], data.elements [i + 3], | |||||
data.elements [i + 4], data.elements [i + 5]); | |||||
pathXMin = jmin (pathXMin, data.elements [i], data.elements [i + 2], data.elements [i + 4]); | pathXMin = jmin (pathXMin, data.elements [i], data.elements [i + 2], data.elements [i + 4]); | ||||
pathXMax = jmax (pathXMax, data.elements [i], data.elements [i + 2], data.elements [i + 4]); | pathXMax = jmax (pathXMax, data.elements [i], data.elements [i + 2], data.elements [i + 4]); | ||||
@@ -87,16 +87,13 @@ bool PathFlatteningIterator::next() | |||||
x2 = points [index++]; | x2 = points [index++]; | ||||
y2 = points [index++]; | y2 = points [index++]; | ||||
if (! isIdentityTransform) | |||||
transform.transformPoint (x2, y2); | |||||
if (type == Path::quadMarker) | if (type == Path::quadMarker) | ||||
{ | { | ||||
x3 = points [index++]; | x3 = points [index++]; | ||||
y3 = points [index++]; | y3 = points [index++]; | ||||
if (! isIdentityTransform) | if (! isIdentityTransform) | ||||
transform.transformPoint (x3, y3); | |||||
transform.transformPoints (x2, y2, x3, y3); | |||||
} | } | ||||
else if (type == Path::cubicMarker) | else if (type == Path::cubicMarker) | ||||
{ | { | ||||
@@ -106,10 +103,12 @@ bool PathFlatteningIterator::next() | |||||
y4 = points [index++]; | y4 = points [index++]; | ||||
if (! isIdentityTransform) | if (! isIdentityTransform) | ||||
{ | |||||
transform.transformPoint (x3, y3); | |||||
transform.transformPoint (x4, y4); | |||||
} | |||||
transform.transformPoints (x2, y2, x3, y3, x4, y4); | |||||
} | |||||
else | |||||
{ | |||||
if (! isIdentityTransform) | |||||
transform.transformPoint (x2, y2); | |||||
} | } | ||||
} | } | ||||
} | } | ||||
@@ -153,7 +153,8 @@ public: | |||||
void applyTransform (const AffineTransform& transform) throw() { transform.transformPoint (x, y); } | void applyTransform (const AffineTransform& transform) throw() { transform.transformPoint (x, y); } | ||||
/** Returns the position of this point, if it is transformed by a given AffineTransform. */ | /** Returns the position of this point, if it is transformed by a given AffineTransform. */ | ||||
const Point transformedBy (const AffineTransform& transform) const throw() { ValueType x2 (x), y2 (y); transform.transformPoint (x2, y2); return Point (x2, y2); } | |||||
const Point transformedBy (const AffineTransform& transform) const throw() { return Point (transform.mat00 * x + transform.mat01 * y + transform.mat02, | |||||
transform.mat10 * x + transform.mat11 * y + transform.mat12); } | |||||
/** Casts this point to a Point<float> object. */ | /** Casts this point to a Point<float> object. */ | ||||
const Point<float> toFloat() const throw() { return Point<float> (static_cast <float> (x), static_cast<float> (y)); } | const Point<float> toFloat() const throw() { return Point<float> (static_cast <float> (x), static_cast<float> (y)); } | ||||
@@ -494,10 +494,8 @@ public: | |||||
float x3 = x, y3 = y + h; | float x3 = x, y3 = y + h; | ||||
float x4 = x2, y4 = y3; | float x4 = x2, y4 = y3; | ||||
transform.transformPoint (x1, y1); | |||||
transform.transformPoint (x2, y2); | |||||
transform.transformPoint (x3, y3); | |||||
transform.transformPoint (x4, y4); | |||||
transform.transformPoints (x1, y1, x2, y2); | |||||
transform.transformPoints (x3, y3, x4, y4); | |||||
const float rx = jmin (x1, x2, x3, x4); | const float rx = jmin (x1, x2, x3, x4); | ||||
const float ry = jmin (y1, y2, y3, y4); | const float ry = jmin (y1, y2, y3, y4); | ||||
@@ -3160,7 +3160,8 @@ public: | |||||
GLXContext sharedContext) | GLXContext sharedContext) | ||||
: renderContext (0), | : renderContext (0), | ||||
embeddedWindow (0), | embeddedWindow (0), | ||||
pixelFormat (pixelFormat_) | |||||
pixelFormat (pixelFormat_), | |||||
swapInterval (0) | |||||
{ | { | ||||
jassert (component != 0); | jassert (component != 0); | ||||
LinuxComponentPeer* const peer = dynamic_cast <LinuxComponentPeer*> (component->getTopLevelComponent()->getPeer()); | LinuxComponentPeer* const peer = dynamic_cast <LinuxComponentPeer*> (component->getTopLevelComponent()->getPeer()); | ||||
@@ -3288,14 +3289,21 @@ public: | |||||
bool setSwapInterval (const int numFramesPerSwap) | bool setSwapInterval (const int numFramesPerSwap) | ||||
{ | { | ||||
// xxx needs doing.. | |||||
static PFNGLXSWAPINTERVALSGIPROC GLXSwapIntervalSGI = (PFNGLXSWAPINTERVALSGIPROC) glXGetProcAddress ((const GLubyte*) "glXSwapIntervalSGI"); | |||||
if (GLXSwapIntervalSGI != 0) | |||||
{ | |||||
swapInterval = numFramesPerSwap; | |||||
GLXSwapIntervalSGI (numFramesPerSwap); | |||||
return true; | |||||
} | |||||
return false; | return false; | ||||
} | } | ||||
int getSwapInterval() const | int getSwapInterval() const | ||||
{ | { | ||||
// xxx needs doing.. | |||||
return 0; | |||||
return swapInterval; | |||||
} | } | ||||
void repaint() | void repaint() | ||||
@@ -3310,6 +3318,7 @@ public: | |||||
private: | private: | ||||
Window embeddedWindow; | Window embeddedWindow; | ||||
OpenGLPixelFormat pixelFormat; | OpenGLPixelFormat pixelFormat; | ||||
int swapInterval; | |||||
//============================================================================== | //============================================================================== | ||||
WindowedGLContext (const WindowedGLContext&); | WindowedGLContext (const WindowedGLContext&); | ||||
@@ -717,14 +717,11 @@ private: | |||||
CGContextAddLineToPoint (context, i.x1, flipHeight - i.y1); | CGContextAddLineToPoint (context, i.x1, flipHeight - i.y1); | ||||
break; | break; | ||||
case Path::Iterator::quadraticTo: | case Path::Iterator::quadraticTo: | ||||
transform.transformPoint (i.x1, i.y1); | |||||
transform.transformPoint (i.x2, i.y2); | |||||
transform.transformPoints (i.x1, i.y1, i.x2, i.y2); | |||||
CGContextAddQuadCurveToPoint (context, i.x1, flipHeight - i.y1, i.x2, flipHeight - i.y2); | CGContextAddQuadCurveToPoint (context, i.x1, flipHeight - i.y1, i.x2, flipHeight - i.y2); | ||||
break; | break; | ||||
case Path::Iterator::cubicTo: | case Path::Iterator::cubicTo: | ||||
transform.transformPoint (i.x1, i.y1); | |||||
transform.transformPoint (i.x2, i.y2); | |||||
transform.transformPoint (i.x3, i.y3); | |||||
transform.transformPoints (i.x1, i.y1, i.x2, i.y2, i.x3, i.y3); | |||||
CGContextAddCurveToPoint (context, i.x1, flipHeight - i.y1, i.x2, flipHeight - i.y2, i.x3, flipHeight - i.y3); | CGContextAddCurveToPoint (context, i.x1, flipHeight - i.y1, i.x2, flipHeight - i.y2, i.x3, flipHeight - i.y3); | ||||
break; | break; | ||||
case Path::Iterator::closePath: | case Path::Iterator::closePath: | ||||
@@ -32,6 +32,11 @@ class NSViewComponentPeer; | |||||
//============================================================================== | //============================================================================== | ||||
END_JUCE_NAMESPACE | END_JUCE_NAMESPACE | ||||
@interface NSEvent (JuceDeviceDelta) | |||||
- (float) deviceDeltaX; | |||||
- (float) deviceDeltaY; | |||||
@end | |||||
#define JuceNSView MakeObjCClassName(JuceNSView) | #define JuceNSView MakeObjCClassName(JuceNSView) | ||||
@interface JuceNSView : NSView<NSTextInput> | @interface JuceNSView : NSView<NSTextInput> | ||||
@@ -1424,8 +1429,20 @@ void NSViewComponentPeer::redirectMouseWheel (NSEvent* ev) | |||||
{ | { | ||||
updateModifiers (ev); | updateModifiers (ev); | ||||
handleMouseWheel (0, getMousePos (ev, view), getMouseTime (ev), | |||||
[ev deltaX] * 10.0f, [ev deltaY] * 10.0f); | |||||
float x = 0, y = 0; | |||||
@try | |||||
{ | |||||
x = [ev deviceDeltaX] * 0.5f; | |||||
y = [ev deviceDeltaY] * 0.5f; | |||||
} | |||||
@catch (...) | |||||
{ | |||||
x = [ev deltaX] * 10.0f; | |||||
y = [ev deltaY] * 10.0f; | |||||
} | |||||
handleMouseWheel (0, getMousePos (ev, view), getMouseTime (ev), x, y); | |||||
} | } | ||||
void NSViewComponentPeer::showArrowCursorIfNeeded() | void NSViewComponentPeer::showArrowCursorIfNeeded() | ||||
@@ -143,60 +143,24 @@ static const String getDSErrorMessage (HRESULT hr) | |||||
switch (hr) | switch (hr) | ||||
{ | { | ||||
case MAKE_HRESULT(1, 0x878, 10): | |||||
result = "Device already allocated"; | |||||
break; | |||||
case MAKE_HRESULT(1, 0x878, 30): | |||||
result = "Control unavailable"; | |||||
break; | |||||
case E_INVALIDARG: | |||||
result = "Invalid parameter"; | |||||
break; | |||||
case MAKE_HRESULT(1, 0x878, 50): | |||||
result = "Invalid call"; | |||||
break; | |||||
case E_FAIL: | |||||
result = "Generic error"; | |||||
break; | |||||
case MAKE_HRESULT(1, 0x878, 70): | |||||
result = "Priority level error"; | |||||
break; | |||||
case E_OUTOFMEMORY: | |||||
result = "Out of memory"; | |||||
break; | |||||
case MAKE_HRESULT(1, 0x878, 100): | |||||
result = "Bad format"; | |||||
break; | |||||
case E_NOTIMPL: | |||||
result = "Unsupported function"; | |||||
break; | |||||
case MAKE_HRESULT(1, 0x878, 120): | |||||
result = "No driver"; | |||||
break; | |||||
case MAKE_HRESULT(1, 0x878, 130): | |||||
result = "Already initialised"; | |||||
break; | |||||
case CLASS_E_NOAGGREGATION: | |||||
result = "No aggregation"; | |||||
break; | |||||
case MAKE_HRESULT(1, 0x878, 150): | |||||
result = "Buffer lost"; | |||||
break; | |||||
case MAKE_HRESULT(1, 0x878, 160): | |||||
result = "Another app has priority"; | |||||
break; | |||||
case MAKE_HRESULT(1, 0x878, 170): | |||||
result = "Uninitialised"; | |||||
break; | |||||
case E_NOINTERFACE: | |||||
result = "No interface"; | |||||
break; | |||||
case S_OK: | |||||
result = "No error"; | |||||
break; | |||||
default: | |||||
return "Unknown error: " + String ((int) hr); | |||||
case MAKE_HRESULT(1, 0x878, 10): result = "Device already allocated"; break; | |||||
case MAKE_HRESULT(1, 0x878, 30): result = "Control unavailable"; break; | |||||
case E_INVALIDARG: result = "Invalid parameter"; break; | |||||
case MAKE_HRESULT(1, 0x878, 50): result = "Invalid call"; break; | |||||
case E_FAIL: result = "Generic error"; break; | |||||
case MAKE_HRESULT(1, 0x878, 70): result = "Priority level error"; break; | |||||
case E_OUTOFMEMORY: result = "Out of memory"; break; | |||||
case MAKE_HRESULT(1, 0x878, 100): result = "Bad format"; break; | |||||
case E_NOTIMPL: result = "Unsupported function"; break; | |||||
case MAKE_HRESULT(1, 0x878, 120): result = "No driver"; break; | |||||
case MAKE_HRESULT(1, 0x878, 130): result = "Already initialised"; break; | |||||
case CLASS_E_NOAGGREGATION: result = "No aggregation"; break; | |||||
case MAKE_HRESULT(1, 0x878, 150): result = "Buffer lost"; break; | |||||
case MAKE_HRESULT(1, 0x878, 160): result = "Another app has priority"; break; | |||||
case MAKE_HRESULT(1, 0x878, 170): result = "Uninitialised"; break; | |||||
case E_NOINTERFACE: result = "No interface"; break; | |||||
case S_OK: result = "No error"; break; | |||||
default: return "Unknown error: " + String ((int) hr); | |||||
} | } | ||||
return result; | return result; | ||||
@@ -2513,7 +2513,7 @@ void* MouseCursor::createStandardMouseCursor (const MouseCursor::StandardCursorT | |||||
{ | { | ||||
static const unsigned char dragHandData[] = | static const unsigned char dragHandData[] = | ||||
{ 71,73,70,56,57,97,16,0,16,0,145,2,0,0,0,0,255,255,255,0,0,0,0,0,0,33,249,4,1,0,0,2,0,44,0,0,0,0,16,0, | { 71,73,70,56,57,97,16,0,16,0,145,2,0,0,0,0,255,255,255,0,0,0,0,0,0,33,249,4,1,0,0,2,0,44,0,0,0,0,16,0, | ||||
16,0,0,2,52,148,47,0,200,185,16,130,90,12,74,139,107,84,123,39, 132,117,151,116,132,146,248,60,209,138, | |||||
16,0,0,2,52,148,47,0,200,185,16,130,90,12,74,139,107,84,123,39,132,117,151,116,132,146,248,60,209,138, | |||||
98,22,203,114,34,236,37,52,77,217,247,154,191,119,110,240,193,128,193,95,163,56,60,234,98,135,2,0,59 }; | 98,22,203,114,34,236,37,52,77,217,247,154,191,119,110,240,193,128,193,95,163,56,60,234,98,135,2,0,59 }; | ||||
dragHandCursor = createMouseCursorFromImage (ImageFileFormat::loadFrom (dragHandData, sizeof (dragHandData)), 8, 7); | dragHandCursor = createMouseCursorFromImage (ImageFileFormat::loadFrom (dragHandData, sizeof (dragHandData)), 8, 7); | ||||
@@ -2651,13 +2651,6 @@ private: | |||||
class JuceDataObject : public ComBaseClassHelper <IDataObject> | class JuceDataObject : public ComBaseClassHelper <IDataObject> | ||||
{ | { | ||||
JuceDropSource* const dropSource; | |||||
const FORMATETC* const format; | |||||
const STGMEDIUM* const medium; | |||||
JuceDataObject (const JuceDataObject&); | |||||
JuceDataObject& operator= (const JuceDataObject&); | |||||
public: | public: | ||||
JuceDataObject (JuceDropSource* const dropSource_, | JuceDataObject (JuceDropSource* const dropSource_, | ||||
const FORMATETC* const format_, | const FORMATETC* const format_, | ||||
@@ -2739,6 +2732,14 @@ public: | |||||
HRESULT __stdcall DAdvise (FORMATETC __RPC_FAR*, DWORD, IAdviseSink __RPC_FAR*, DWORD __RPC_FAR*) { return OLE_E_ADVISENOTSUPPORTED; } | HRESULT __stdcall DAdvise (FORMATETC __RPC_FAR*, DWORD, IAdviseSink __RPC_FAR*, DWORD __RPC_FAR*) { return OLE_E_ADVISENOTSUPPORTED; } | ||||
HRESULT __stdcall DUnadvise (DWORD) { return E_NOTIMPL; } | HRESULT __stdcall DUnadvise (DWORD) { return E_NOTIMPL; } | ||||
HRESULT __stdcall EnumDAdvise (IEnumSTATDATA __RPC_FAR *__RPC_FAR *) { return OLE_E_ADVISENOTSUPPORTED; } | HRESULT __stdcall EnumDAdvise (IEnumSTATDATA __RPC_FAR *__RPC_FAR *) { return OLE_E_ADVISENOTSUPPORTED; } | ||||
private: | |||||
JuceDropSource* const dropSource; | |||||
const FORMATETC* const format; | |||||
const STGMEDIUM* const medium; | |||||
JuceDataObject (const JuceDataObject&); | |||||
JuceDataObject& operator= (const JuceDataObject&); | |||||
}; | }; | ||||
static HDROP createHDrop (const StringArray& fileNames) throw() | static HDROP createHDrop (const StringArray& fileNames) throw() | ||||