Browse Source

More internal changes to drawables. Linux URL header retrieval. Small fix for AudioProcessorPlayer. Jucer development.

tags/2021-05-28
Julian Storer 15 years ago
parent
commit
8e1b74a8fc
21 changed files with 1217 additions and 705 deletions
  1. +2
    -0
      extras/Jucer (experimental)/Source/jucer_Main.cpp
  2. +7
    -0
      extras/Jucer (experimental)/Source/model/Drawable/jucer_DrawableTypeHandler.h
  3. +4
    -0
      extras/Jucer (experimental)/Source/ui/Component Editor/jucer_ComponentEditorCanvas.h
  4. +71
    -0
      extras/Jucer (experimental)/Source/ui/Drawable Editor/jucer_DrawableEditorCanvas.h
  5. +40
    -34
      extras/Jucer (experimental)/Source/ui/Editor Base/jucer_EditorCanvas.cpp
  6. +12
    -6
      extras/Jucer (experimental)/Source/ui/Editor Base/jucer_EditorCanvas.h
  7. +5
    -0
      extras/Jucer (experimental)/Source/ui/Editor Base/jucer_EditorDragOperation.h
  8. +298
    -11
      extras/Jucer (experimental)/Source/utility/jucer_FillTypePropertyComponent.h
  9. +8
    -0
      extras/Jucer (experimental)/Source/utility/jucer_StoredSettings.cpp
  10. +5
    -1
      extras/Jucer (experimental)/Source/utility/jucer_StoredSettings.h
  11. +119
    -81
      juce_amalgamated.cpp
  12. +34
    -16
      juce_amalgamated.h
  13. +6
    -1
      src/audio/processors/juce_AudioProcessorPlayer.cpp
  14. +1
    -1
      src/core/juce_StandardHeader.h
  15. +29
    -22
      src/gui/graphics/colour/juce_ColourGradient.cpp
  16. +15
    -7
      src/gui/graphics/colour/juce_ColourGradient.h
  17. +27
    -22
      src/gui/graphics/drawables/juce_Drawable.cpp
  18. +10
    -4
      src/gui/graphics/drawables/juce_Drawable.h
  19. +34
    -12
      src/gui/graphics/drawables/juce_DrawablePath.cpp
  20. +9
    -5
      src/gui/graphics/drawables/juce_DrawablePath.h
  21. +481
    -482
      src/native/linux/juce_linux_Network.cpp

+ 2
- 0
extras/Jucer (experimental)/Source/jucer_Main.cpp View File

@@ -68,6 +68,8 @@ public:
anotherInstanceStarted (commandLine); anotherInstanceStarted (commandLine);
theMainWindow->reloadLastProject(); theMainWindow->reloadLastProject();
theMainWindow->getLookAndFeel().setColour (ColourSelector::backgroundColourId, Colours::transparentBlack);
} }
void shutdown() void shutdown()


+ 7
- 0
extras/Jucer (experimental)/Source/model/Drawable/jucer_DrawableTypeHandler.h View File

@@ -146,6 +146,13 @@ public:
void createPropertyEditors (DrawableTypeInstance& item, Array <PropertyComponent*>& props) void createPropertyEditors (DrawableTypeInstance& item, Array <PropertyComponent*>& props)
{ {
DrawablePath::ValueTreeWrapper wrapper (item.getState());
props.add (new FillTypePropertyComponent (item.getDocument().getUndoManager(),
"Fill", wrapper.getMainFillState()));
props.add (new FillTypePropertyComponent (item.getDocument().getUndoManager(),
"Stroke", wrapper.getStrokeFillState()));
} }
void itemDoubleClicked (const MouseEvent& e, DrawableTypeInstance& item) void itemDoubleClicked (const MouseEvent& e, DrawableTypeInstance& item)


+ 4
- 0
extras/Jucer (experimental)/Source/ui/Component Editor/jucer_ComponentEditorCanvas.h View File

@@ -146,6 +146,10 @@ public:
return getDocument().getCoordsFor (state); return getDocument().getCoordsFor (state);
} }
void updateExtraComponentsForObject (const ValueTree& state, Component* parent, OwnedArray<OverlayItemComponent>& existingComps)
{
}
SelectedItems& getSelection() SelectedItems& getSelection()
{ {
return editor.getSelection(); return editor.getSelection();


+ 71
- 0
extras/Jucer (experimental)/Source/ui/Drawable Editor/jucer_DrawableEditorCanvas.h View File

@@ -207,6 +207,77 @@ public:
return RelativeRectangle(); return RelativeRectangle();
} }
class ControlPointComponent : public OverlayItemComponent
{
public:
ControlPointComponent (DrawableEditorCanvas* canvas)
: OverlayItemComponent (canvas)
{
}
~ControlPointComponent()
{
}
void paint (Graphics& g)
{
g.fillAll (Colours::pink);
}
void mouseDown (const MouseEvent& e)
{
}
void mouseDrag (const MouseEvent& e)
{
}
void mouseUp (const MouseEvent& e)
{
}
void updatePosition (const RelativePoint& point, RelativeCoordinate::NamedCoordinateFinder* nameFinder)
{
const Point<float> p (point.resolve (nameFinder));
setBoundsInTargetSpace (Rectangle<int> (roundToInt (p.getX()) - 2, roundToInt (p.getY()) - 2, 5, 5));
}
};
void updateExtraComponentsForObject (const ValueTree& state, Component* parent, OwnedArray<OverlayItemComponent>& comps)
{
if (drawable == 0)
{
comps.clear();
return;
}
DrawableTypeInstance item (getDocument(), state);
Array<RelativePoint> points;
item.getAllControlPoints (points);
Drawable* d = drawable->getDrawableWithName (Drawable::ValueTreeWrapperBase (state).getID());
DrawableComposite* parentDrawable = d->getParent();
comps.removeRange (points.size(), comps.size());
BigInteger requiredIndexes;
requiredIndexes.setRange (0, points.size(), true);
for (int i = 0; i < points.size(); ++i)
{
ControlPointComponent* c = dynamic_cast <ControlPointComponent*> (comps[i]);
if (c == 0)
{
c = new ControlPointComponent (this);
comps.set (i, c);
parent->addAndMakeVisible (c);
}
c->updatePosition (points.getReference(i), parentDrawable);
}
}
SelectedItems& getSelection() SelectedItems& getSelection()
{ {
return editor.getSelection(); return editor.getSelection();


+ 40
- 34
extras/Jucer (experimental)/Source/ui/Editor Base/jucer_EditorCanvas.cpp View File

@@ -114,12 +114,14 @@ public:
const Rectangle<int> bounds (canvas->getObjectPosition (objectState)); const Rectangle<int> bounds (canvas->getObjectPosition (objectState));
setBoundsInTargetSpace (bounds.expanded (borderThickness, borderThickness)); setBoundsInTargetSpace (bounds.expanded (borderThickness, borderThickness));
for (int i = sizeGuides.size(); --i >= 0;)
int i;
for (i = sizeGuides.size(); --i >= 0;)
{ {
sizeGuides.getUnchecked(i)->setVisible (isVisible()); sizeGuides.getUnchecked(i)->setVisible (isVisible());
sizeGuides.getUnchecked(i)->updatePosition (bounds); sizeGuides.getUnchecked(i)->updatePosition (bounds);
} }
canvas->updateExtraComponentsForObject (objectState, getParentComponent(), extraEditorComps);
return true; return true;
} }
@@ -200,6 +202,7 @@ private:
const int borderThickness; const int borderThickness;
OwnedArray <SizeGuideComponent> sizeGuides; OwnedArray <SizeGuideComponent> sizeGuides;
bool isDragging; bool isDragging;
OwnedArray <OverlayItemComponent> extraEditorComps;
const Rectangle<int> getCentreArea() const const Rectangle<int> getCentreArea() const
{ {
@@ -399,6 +402,8 @@ public:
getSelection().removeChangeListener (this); getSelection().removeChangeListener (this);
lasso = 0; lasso = 0;
resizers.clear(); resizers.clear();
markersX.clear();
markersY.clear();
deleteAllChildren(); deleteAllChildren();
} }
@@ -563,6 +568,21 @@ public:
} }
} }
void update()
{
updateResizeFrames();
updateMarkers();
}
private:
//==============================================================================
EditorCanvasBase* canvas;
ScopedPointer <LassoComponent <SelectedItems::ItemType> > lasso;
bool mouseDownResult, isDraggingClickedComp;
SelectedItems::ItemType mouseDownCompUID;
OwnedArray <ResizeFrame> resizers;
OwnedArray <MarkerComponent> markersX, markersY;
void updateResizeFrames() void updateResizeFrames()
{ {
SelectedItems& selection = getSelection(); SelectedItems& selection = getSelection();
@@ -610,49 +630,34 @@ public:
} }
} }
void update()
void updateMarkers (OwnedArray <MarkerComponent>& markers, const bool isX)
{ {
updateResizeFrames();
updateMarkers();
}
private:
//==============================================================================
EditorCanvasBase* canvas;
ScopedPointer <LassoComponent <SelectedItems::ItemType> > lasso;
bool mouseDownResult, isDraggingClickedComp;
SelectedItems::ItemType mouseDownCompUID;
OwnedArray <ResizeFrame> resizers;
MarkerListBase& markerList = canvas->getMarkerList (isX);
const int num = markerList.size();
void updateMarkers (bool isX)
{
Array<ValueTree> requiredMarkers; Array<ValueTree> requiredMarkers;
requiredMarkers.ensureStorageAllocated (num);
MarkerListBase& markerList = canvas->getMarkerList (isX);
const int num = markerList.size();
int i; int i;
for (i = 0; i < num; ++i) for (i = 0; i < num; ++i)
requiredMarkers.add (markerList.getMarker (i)); requiredMarkers.add (markerList.getMarker (i));
for (i = getNumChildComponents(); --i >= 0;)
for (i = markers.size(); --i >= 0;)
{ {
MarkerComponent* marker = dynamic_cast <MarkerComponent*> (getChildComponent(i));
MarkerComponent* marker = markers.getUnchecked (i);
const int index = requiredMarkers.indexOf (marker->marker);
if (marker != 0 && marker->isX == isX)
if (index >= 0)
{ {
if (requiredMarkers.contains (marker->marker))
{
marker->setVisible (true);
marker->updatePosition();
requiredMarkers.removeValue (marker->marker);
}
marker->updatePosition();
requiredMarkers.removeValue (marker->marker);
}
else
{
if (marker->isMouseButtonDown())
marker->setBounds (-1, -1, 1, 1);
else else
{
if (marker->isMouseButtonDown())
marker->setBounds (-1, -1, 1, 1);
else
delete marker;
}
markers.remove (i);
} }
} }
@@ -661,6 +666,7 @@ private:
MarkerComponent* marker = new MarkerComponent (canvas, requiredMarkers.getReference(i), MarkerComponent* marker = new MarkerComponent (canvas, requiredMarkers.getReference(i),
isX, isX ? canvas->border.getTop() isX, isX ? canvas->border.getTop()
: canvas->border.getLeft()); : canvas->border.getLeft());
markers.add (marker);
addAndMakeVisible (marker); addAndMakeVisible (marker);
marker->updatePosition(); marker->updatePosition();
} }
@@ -668,8 +674,8 @@ private:
void updateMarkers() void updateMarkers()
{ {
updateMarkers (true);
updateMarkers (false);
updateMarkers (markersX, true);
updateMarkers (markersY, false);
} }
}; };


+ 12
- 6
extras/Jucer (experimental)/Source/ui/Editor Base/jucer_EditorCanvas.h View File

@@ -64,27 +64,29 @@ public:
void hideSizeGuides(); void hideSizeGuides();
//============================================================================== //==============================================================================
virtual UndoManager& getUndoManager() = 0;
virtual void documentChanged() = 0; virtual void documentChanged() = 0;
virtual Component* createComponentHolder() = 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;
virtual MarkerListBase& getMarkerList (bool isX) = 0;
virtual double limitMarkerPosition (double pos) = 0;
virtual const SelectedItems::ItemType findObjectIdAt (const Point<int>& position) = 0; virtual const SelectedItems::ItemType findObjectIdAt (const Point<int>& position) = 0;
virtual void showPopupMenu (bool isClickOnSelectedObject) = 0; virtual void showPopupMenu (bool isClickOnSelectedObject) = 0;
virtual void objectDoubleClicked (const MouseEvent& e, const ValueTree& state) = 0; virtual void objectDoubleClicked (const MouseEvent& e, const ValueTree& state) = 0;
virtual const ValueTree getObjectState (const String& objectId) = 0; virtual const ValueTree getObjectState (const String& objectId) = 0;
virtual RelativeRectangle getObjectCoords (const ValueTree& state) = 0;
virtual const Rectangle<int> getObjectPosition (const ValueTree& state) = 0; virtual const Rectangle<int> getObjectPosition (const ValueTree& state) = 0;
virtual bool hasSizeGuides() const = 0; virtual bool hasSizeGuides() const = 0;
virtual RelativeRectangle getObjectCoords (const ValueTree& state) = 0;
virtual MarkerListBase& getMarkerList (bool isX) = 0;
virtual double limitMarkerPosition (double pos) = 0;
virtual SelectedItems& getSelection() = 0; virtual SelectedItems& getSelection() = 0;
virtual UndoManager& getUndoManager() = 0;
virtual void deselectNonDraggableObjects() = 0; virtual void deselectNonDraggableObjects() = 0;
virtual void findLassoItemsInArea (Array <SelectedItems::ItemType>& itemsFound, const Rectangle<int>& area) = 0; virtual void findLassoItemsInArea (Array <SelectedItems::ItemType>& itemsFound, const Rectangle<int>& area) = 0;
virtual Component* createComponentHolder() = 0;
class DragOperation class DragOperation
{ {
@@ -126,6 +128,10 @@ public:
EditorCanvasBase* canvas; EditorCanvasBase* canvas;
}; };
//==============================================================================
virtual void updateExtraComponentsForObject (const ValueTree& state, Component* parent,
OwnedArray<OverlayItemComponent>& existingComps) = 0;
protected: protected:
//============================================================================== //==============================================================================
const BorderSize border; const BorderSize border;


+ 5
- 0
extras/Jucer (experimental)/Source/ui/Editor Base/jucer_EditorDragOperation.h View File

@@ -172,6 +172,11 @@ public:
roundToInt (line.end - line.start) + extraEndLength * 2, 1)); roundToInt (line.end - line.start) + extraEndLength * 2, 1));
} }
bool updatePosition()
{
return true;
}
void paint (Graphics& g) void paint (Graphics& g)
{ {
g.fillAll (alignmentMarkerColour); g.fillAll (alignmentMarkerColour);


+ 298
- 11
extras/Jucer (experimental)/Source/utility/jucer_FillTypePropertyComponent.h View File

@@ -37,15 +37,43 @@ public:
: fillState (fillState_), : fillState (fillState_),
undoManager (undoManager_) undoManager (undoManager_)
{ {
addAndMakeVisible (&colourPicker);
colourButton.setButtonText ("Colour");
colourButton.setConnectedEdges (TextButton::ConnectedOnRight);
gradientButton.setButtonText ("Gradient");
gradientButton.setConnectedEdges (TextButton::ConnectedOnRight | TextButton::ConnectedOnLeft);
imageButton.setButtonText ("Image");
imageButton.setConnectedEdges (TextButton::ConnectedOnLeft);
addAndMakeVisible (&colourButton);
addAndMakeVisible (&gradientButton);
addAndMakeVisible (&imageButton);
addChildComponent (&colourPicker);
colourPicker.setCurrentColour (Colours::green);
colourPicker.setName ("Colour"); colourPicker.setName ("Colour");
colourPicker.addChangeListener (this); colourPicker.addChangeListener (this);
addChildComponent (&gradientPicker);
gradientPicker.addChangeListener (this);
fillState.addListener (this); fillState.addListener (this);
colourButton.setRadioGroupId (123);
gradientButton.setRadioGroupId (123);
imageButton.setRadioGroupId (123);
colourButton.addButtonListener (this);
gradientButton.addButtonListener (this);
imageButton.addButtonListener (this);
refresh();
} }
~PopupFillSelector() ~PopupFillSelector()
{ {
colourButton.removeButtonListener (this);
gradientButton.removeButtonListener (this);
imageButton.removeButtonListener (this);
} }
static void showAt (Component* comp, const ValueTree& fill, UndoManager* undoManager) static void showAt (Component* comp, const ValueTree& fill, UndoManager* undoManager)
@@ -59,32 +87,84 @@ public:
void resized() void resized()
{ {
colourPicker.setBounds (0, 0, getWidth(), getHeight());
const int y = 2, w = 80, h = 22;
gradientButton.setBounds (getWidth() / 2 - w / 2, y, w, h);
colourButton.setBounds (gradientButton.getX() - w, y, w, h);
imageButton.setBounds (gradientButton.getRight(), y, w, h);
const Rectangle<int> content (2, y + h + 4, getWidth() - 4, getHeight() - (y + h + 6));
colourPicker.setBounds (content);
gradientPicker.setBounds (content);
} }
void buttonClicked (Button*)
void buttonClicked (Button* b)
{ {
if (b == &colourButton)
{
setFillType (colourPicker.getCurrentColour());
}
else if (b == &gradientButton)
{
setFillType (gradientPicker.getGradient());
}
else if (b == &imageButton)
{
setFillType (FillType (*StoredSettings::getInstance()->getFallbackImage(),
AffineTransform::identity));
}
} }
void changeListenerCallback (void* source)
const FillType readFillType (RelativePoint* gp1, RelativePoint* gp2) const
{ {
const FillType currentFill (Drawable::ValueTreeWrapperBase::readFillType (fillState));
return Drawable::ValueTreeWrapperBase::readFillType (fillState, gp1, gp2, 0);
}
if (currentFill.isColour())
void setFillType (const FillType& newFill)
{
RelativePoint gp1, gp2;
const FillType currentFill (readFillType (&gp1, &gp2));
if (currentFill != newFill)
{ {
const FillType newFill (colourPicker.getCurrentColour());
if (undoManager != 0)
undoManager->undoCurrentTransactionOnly();
if (currentFill != newFill)
Drawable::ValueTreeWrapperBase::writeFillType (fillState, newFill, undoManager);
Drawable::ValueTreeWrapperBase::writeFillType (fillState, newFill, &gp1, &gp2, undoManager);
refresh();
} }
} }
void changeListenerCallback (void*)
{
const FillType currentFill (readFillType (0, 0));
if (currentFill.isColour())
setFillType (colourPicker.getCurrentColour());
else if (currentFill.isGradient())
setFillType (gradientPicker.getGradient());
}
void refresh() void refresh()
{ {
const FillType newFill (Drawable::ValueTreeWrapperBase::readFillType (fillState));
const FillType newFill (readFillType (0, 0));
colourPicker.setVisible (newFill.isColour());
gradientPicker.setVisible (newFill.isGradient());
if (newFill.isColour()) if (newFill.isColour())
{
colourButton.setToggleState (true, false);
colourPicker.setCurrentColour (newFill.colour); colourPicker.setCurrentColour (newFill.colour);
}
else if (newFill.isGradient())
{
gradientButton.setToggleState (true, false);
gradientPicker.setGradient (*newFill.gradient);
}
else
{
imageButton.setToggleState (true, false);
}
} }
void valueTreePropertyChanged (ValueTree& treeWhosePropertyHasChanged, const Identifier& property) { refresh(); } void valueTreePropertyChanged (ValueTree& treeWhosePropertyHasChanged, const Identifier& property) { refresh(); }
@@ -92,9 +172,215 @@ public:
void valueTreeParentChanged (ValueTree& treeWhoseParentHasChanged) {} void valueTreeParentChanged (ValueTree& treeWhoseParentHasChanged) {}
private: private:
//==============================================================================
class GradientDesigner : public Component,
public ChangeBroadcaster,
private ChangeListener
{
public:
GradientDesigner()
: gradient (Colours::red, 0.0f, 0.0f, Colours::blue, 200.0f, 200.0f, false),
selectedPoint (-1),
dragging (false),
draggingNewPoint (false),
draggingPos (0)
{
addChildComponent (&colourPicker);
colourPicker.addChangeListener (this);
}
~GradientDesigner()
{
}
void paint (Graphics& g)
{
g.fillAll (getLookAndFeel().findColour (ColourSelector::backgroundColourId));
g.fillCheckerBoard (previewArea.getX(), previewArea.getY(),
previewArea.getWidth(), previewArea.getHeight(), 10, 10,
Colour (0xffdddddd), Colour (0xffffffff));
FillType f (gradient);
f.gradient->point1.setXY ((float) previewArea.getX(), (float) previewArea.getCentreY());
f.gradient->point2.setXY ((float) previewArea.getRight(), (float) previewArea.getCentreY());
g.setFillType (f);
g.fillRect (previewArea);
Path marker;
const float headSize = 4.5f;
marker.addLineSegment (0.0f, -2.0f, 0.0f, previewArea.getHeight() + 2.0f, 1.5f);
marker.addTriangle (0.0f, 1.0f, -headSize, -headSize, headSize, -headSize);
for (int i = 0; i < gradient.getNumColours(); ++i)
{
const double pos = gradient.getColourPosition (i);
const Colour col (gradient.getColour (i));
const AffineTransform t (AffineTransform::translation (previewArea.getX() + 0.5f + (float) (previewArea.getWidth() * pos),
(float) previewArea.getY()));
g.setColour (Colours::black.withAlpha (0.8f));
g.strokePath (marker, PathStrokeType (i == selectedPoint ? 2.0f : 1.5f), t);
g.setColour (i == selectedPoint ? Colours::lightblue : Colours::white);
g.fillPath (marker, t);
}
}
void resized()
{
previewArea.setBounds (7, 8, getWidth() - 14, 24);
colourPicker.setBounds (0, previewArea.getBottom() + 8,
getWidth(), getHeight() - previewArea.getBottom() - 8);
}
void mouseDown (const MouseEvent& e)
{
dragging = false;
draggingNewPoint = false;
int point = getPointAt (e.x);
if (point >= 0)
setSelectedPoint (point);
}
void mouseDrag (const MouseEvent& e)
{
if ((! dragging) && ! e.mouseWasClicked())
{
preDragGradient = gradient;
const int mouseDownPoint = getPointAt (e.getMouseDownX());
if (mouseDownPoint >= 0)
{
if (mouseDownPoint > 0 && mouseDownPoint < gradient.getNumColours() - 1)
{
dragging = true;
draggingNewPoint = false;
draggingColour = gradient.getColour (mouseDownPoint);
preDragGradient.removeColour (mouseDownPoint);
selectedPoint = -1;
}
}
else
{
dragging = true;
draggingNewPoint = true;
selectedPoint = -1;
}
}
if (dragging)
{
draggingPos = jlimit (0.001, 0.999, (e.x - previewArea.getX()) / (double) previewArea.getWidth());
gradient = preDragGradient;
if (previewArea.expanded (6, 6).contains (e.x, e.y))
{
if (draggingNewPoint)
draggingColour = preDragGradient.getColourAtPosition (draggingPos);
selectedPoint = gradient.addColour (draggingPos, draggingColour);
updatePicker();
}
else
{
selectedPoint = -1;
}
sendChangeMessage (this);
repaint (previewArea.expanded (30, 30));
}
}
void mouseUp (const MouseEvent& e)
{
dragging = false;
}
const ColourGradient& getGradient() const throw() { return gradient; }
void setGradient (const ColourGradient& newGradient)
{
if (newGradient != gradient)
{
gradient = newGradient;
if (selectedPoint < 0)
selectedPoint = 0;
updatePicker();
sendChangeMessage (this);
repaint();
}
}
void setSelectedPoint (int newIndex)
{
if (selectedPoint != newIndex)
{
selectedPoint = newIndex;
updatePicker();
repaint();
}
}
void changeListenerCallback (void*)
{
if (selectedPoint >= 0 && (! dragging) && gradient.getColour (selectedPoint) != colourPicker.getCurrentColour())
{
gradient.setColour (selectedPoint, colourPicker.getCurrentColour());
repaint (previewArea);
sendChangeMessage (this);
}
}
private:
StoredSettings::ColourSelectorWithSwatches colourPicker;
ColourGradient gradient;
int selectedPoint;
bool dragging, draggingNewPoint;
double draggingPos;
Colour draggingColour;
ColourGradient preDragGradient;
Rectangle<int> previewArea;
void updatePicker()
{
colourPicker.setVisible (selectedPoint >= 0);
if (selectedPoint >= 0)
colourPicker.setCurrentColour (gradient.getColour (selectedPoint));
}
int getPointAt (const int x) const
{
int best = -1;
double bestDiff = 6;
for (int i = gradient.getNumColours(); --i >= 0;)
{
const double pos = previewArea.getX() + previewArea.getWidth() * gradient.getColourPosition (i);
const double diff = std::abs (pos - x);
if (diff < bestDiff)
{
bestDiff = diff;
best = i;
}
}
return best;
}
};
//==============================================================================
StoredSettings::ColourSelectorWithSwatches colourPicker; StoredSettings::ColourSelectorWithSwatches colourPicker;
GradientDesigner gradientPicker;
ValueTree fillState; ValueTree fillState;
UndoManager* undoManager; UndoManager* undoManager;
TextButton colourButton, gradientButton, imageButton;
}; };
@@ -149,7 +435,7 @@ public:
void refresh() void refresh()
{ {
const FillType newFill (Drawable::ValueTreeWrapperBase::readFillType (fillState));
const FillType newFill (Drawable::ValueTreeWrapperBase::readFillType (fillState, 0, 0, 0));
if (newFill != fillType) if (newFill != fillType)
{ {
@@ -185,6 +471,7 @@ public:
: PropertyComponent (name), : PropertyComponent (name),
editor (fill, undoManager) editor (fill, undoManager)
{ {
jassert (fill.isValid());
addAndMakeVisible (&editor); addAndMakeVisible (&editor);
} }


+ 8
- 0
extras/Jucer (experimental)/Source/utility/jucer_StoredSettings.cpp View File

@@ -134,3 +134,11 @@ const StringArray& StoredSettings::getFontNames()
return fontNames; return fontNames;
} }
Image* StoredSettings::getFallbackImage()
{
if (fallbackImage == 0)
fallbackImage = ImageFileFormat::loadFrom (BinaryData::juce_icon_png, BinaryData::juce_icon_pngSize);
return fallbackImage;
}

+ 5
- 1
extras/Jucer (experimental)/Source/utility/jucer_StoredSettings.h View File

@@ -53,7 +53,6 @@ public:
const File getLastKnownJuceFolder() const; const File getLastKnownJuceFolder() const;
void setLastKnownJuceFolder (const File& file); void setLastKnownJuceFolder (const File& file);
const StringArray& getFontNames(); const StringArray& getFontNames();
//============================================================================== //==============================================================================
@@ -69,12 +68,17 @@ public:
void setSwatchColour (int index, const Colour& newColour) const { StoredSettings::getInstance()->swatchColours.set (index, newColour); } void setSwatchColour (int index, const Colour& newColour) const { StoredSettings::getInstance()->swatchColours.set (index, newColour); }
}; };
Image* getFallbackImage();
//============================================================================== //==============================================================================
juce_UseDebuggingNewOperator juce_UseDebuggingNewOperator
private: private:
ScopedPointer<PropertiesFile> props; ScopedPointer<PropertiesFile> props;
StringArray fontNames; StringArray fontNames;
ScopedPointer<Image> fallbackImage;
}; };


+ 119
- 81
juce_amalgamated.cpp View File

@@ -36166,7 +36166,12 @@ void AudioProcessorPlayer::audioDeviceIOCallback (const float** inputChannelData
const ScopedLock sl (lock); const ScopedLock sl (lock);


if (processor != 0) if (processor != 0)
processor->processBlock (buffer, incomingMidi);
{
const ScopedLock sl (processor->getCallbackLock());

if (! processor->isSuspended())
processor->processBlock (buffer, incomingMidi);
}
} }


void AudioProcessorPlayer::audioDeviceAboutToStart (AudioIODevice* device) void AudioProcessorPlayer::audioDeviceAboutToStart (AudioIODevice* device)
@@ -78867,19 +78872,15 @@ ColourGradient::ColourGradient() throw()
#endif #endif
} }


ColourGradient::ColourGradient (const Colour& colour1,
const float x1_,
const float y1_,
const Colour& colour2,
const float x2_,
const float y2_,
ColourGradient::ColourGradient (const Colour& colour1, const float x1_, const float y1_,
const Colour& colour2, const float x2_, const float y2_,
const bool isRadial_) const bool isRadial_)
: point1 (x1_, y1_), : point1 (x1_, y1_),
point2 (x2_, y2_), point2 (x2_, y2_),
isRadial (isRadial_) isRadial (isRadial_)
{ {
colours.add (ColourPoint (0, colour1));
colours.add (ColourPoint (1 << 16, colour2));
colours.add (ColourPoint (0.0, colour1));
colours.add (ColourPoint (1.0, colour2));
} }


ColourGradient::~ColourGradient() ColourGradient::~ColourGradient()
@@ -78903,13 +78904,12 @@ void ColourGradient::clearColours()
colours.clear(); colours.clear();
} }


void ColourGradient::addColour (const double proportionAlongGradient,
const Colour& colour)
int ColourGradient::addColour (const double proportionAlongGradient, const Colour& colour)
{ {
// must be within the two end-points // must be within the two end-points
jassert (proportionAlongGradient >= 0 && proportionAlongGradient <= 1.0); jassert (proportionAlongGradient >= 0 && proportionAlongGradient <= 1.0);


const uint32 pos = jlimit (0, 65535, roundToInt (proportionAlongGradient * 65536.0));
const double pos = jlimit (0.0, 1.0, proportionAlongGradient);


int i; int i;
for (i = 0; i < colours.size(); ++i) for (i = 0; i < colours.size(); ++i)
@@ -78917,6 +78917,13 @@ void ColourGradient::addColour (const double proportionAlongGradient,
break; break;


colours.insert (i, ColourPoint (pos, colour)); colours.insert (i, ColourPoint (pos, colour));
return i;
}

void ColourGradient::removeColour (int index)
{
jassert (index > 0 && index < colours.size() - 1);
colours.remove (index);
} }


void ColourGradient::multiplyOpacity (const float multiplier) throw() void ColourGradient::multiplyOpacity (const float multiplier) throw()
@@ -78936,7 +78943,7 @@ int ColourGradient::getNumColours() const throw()
double ColourGradient::getColourPosition (const int index) const throw() double ColourGradient::getColourPosition (const int index) const throw()
{ {
if (((unsigned int) index) < (unsigned int) colours.size()) if (((unsigned int) index) < (unsigned int) colours.size())
return jlimit (0.0, 1.0, colours.getReference (index).position / 65535.0);
return colours.getReference (index).position;


return 0; return 0;
} }
@@ -78949,26 +78956,31 @@ const Colour ColourGradient::getColour (const int index) const throw()
return Colour(); return Colour();
} }


const Colour ColourGradient::getColourAtPosition (const float position) const throw()
void ColourGradient::setColour (int index, const Colour& newColour) throw()
{ {
jassert (colours.getReference(0).position == 0); // the first colour specified has to go at position 0
if (((unsigned int) index) < (unsigned int) colours.size())
colours.getReference (index).colour = newColour;
}


const int integerPos = jlimit (0, 65535, roundToInt (position * 65536.0f));
const Colour ColourGradient::getColourAtPosition (const double position) const throw()
{
jassert (colours.getReference(0).position == 0); // the first colour specified has to go at position 0


if (integerPos <= 0 || colours.size() <= 1)
return getColour (0);
if (position <= 0 || colours.size() <= 1)
return colours.getReference(0).colour;


int i = colours.size() - 1; int i = colours.size() - 1;
while (integerPos < (int) colours.getReference(i).position)
while (position < colours.getReference(i).position)
--i; --i;


const ColourPoint& p1 = colours.getReference (i);

if (i >= colours.size() - 1) if (i >= colours.size() - 1)
return colours.getReference(i).colour;
return p1.colour;


const ColourPoint& p1 = colours.getReference (i);
const ColourPoint& p2 = colours.getReference (i + 1); const ColourPoint& p2 = colours.getReference (i + 1);


return p1.colour.interpolatedWith (p2.colour, (integerPos - p1.position) / (float) (p2.position - p1.position));
return p1.colour.interpolatedWith (p2.colour, (float) ((position - p1.position) / (p2.position - p1.position)));
} }


int ColourGradient::createLookupTable (const AffineTransform& transform, HeapBlock <PixelARGB>& lookupTable) const int ColourGradient::createLookupTable (const AffineTransform& transform, HeapBlock <PixelARGB>& lookupTable) const
@@ -78994,7 +79006,7 @@ int ColourGradient::createLookupTable (const AffineTransform& transform, HeapBlo
for (int j = 1; j < colours.size(); ++j) for (int j = 1; j < colours.size(); ++j)
{ {
const ColourPoint& p = colours.getReference (j); const ColourPoint& p = colours.getReference (j);
const int numToDo = ((p.position * (numEntries - 1)) >> 16) - index;
const int numToDo = roundToInt (p.position * (numEntries - 1)) - index;
const PixelARGB pix2 (p.colour.getPixelARGB()); const PixelARGB pix2 (p.colour.getPixelARGB());


for (int i = 0; i < numToDo; ++i) for (int i = 0; i < numToDo; ++i)
@@ -83854,10 +83866,8 @@ Drawable* Drawable::createFromValueTree (const ValueTree& tree, ImageProvider* i


const Identifier Drawable::ValueTreeWrapperBase::idProperty ("id"); const Identifier Drawable::ValueTreeWrapperBase::idProperty ("id");
const Identifier Drawable::ValueTreeWrapperBase::type ("type"); const Identifier Drawable::ValueTreeWrapperBase::type ("type");
const Identifier Drawable::ValueTreeWrapperBase::x1 ("x1");
const Identifier Drawable::ValueTreeWrapperBase::x2 ("x2");
const Identifier Drawable::ValueTreeWrapperBase::y1 ("y1");
const Identifier Drawable::ValueTreeWrapperBase::y2 ("y2");
const Identifier Drawable::ValueTreeWrapperBase::gradientPoint1 ("point1");
const Identifier Drawable::ValueTreeWrapperBase::gradientPoint2 ("point2");
const Identifier Drawable::ValueTreeWrapperBase::colour ("colour"); const Identifier Drawable::ValueTreeWrapperBase::colour ("colour");
const Identifier Drawable::ValueTreeWrapperBase::radial ("radial"); const Identifier Drawable::ValueTreeWrapperBase::radial ("radial");
const Identifier Drawable::ValueTreeWrapperBase::colours ("colours"); const Identifier Drawable::ValueTreeWrapperBase::colours ("colours");
@@ -83884,7 +83894,8 @@ void Drawable::ValueTreeWrapperBase::setID (const String& newID, UndoManager* un
state.setProperty (idProperty, newID, undoManager); state.setProperty (idProperty, newID, undoManager);
} }


const FillType Drawable::ValueTreeWrapperBase::readFillType (const ValueTree& v)
const FillType Drawable::ValueTreeWrapperBase::readFillType (const ValueTree& v, RelativePoint* gp1, RelativePoint* gp2,
RelativeCoordinate::NamedCoordinateFinder* nameFinder)
{ {
const String newType (v[type].toString()); const String newType (v[type].toString());


@@ -83896,9 +83907,17 @@ const FillType Drawable::ValueTreeWrapperBase::readFillType (const ValueTree& v)
} }
else if (newType == "gradient") else if (newType == "gradient")
{ {
RelativePoint p1 (v [gradientPoint1]), p2 (v [gradientPoint2]);

ColourGradient g; ColourGradient g;
g.point1.setXY (v[x1], v[y1]);
g.point2.setXY (v[x2], v[y2]);

if (gp1 != 0)
*gp1 = p1;
if (gp2 != 0)
*gp2 = p2;

g.point1 = p1.resolve (nameFinder);
g.point2 = p2.resolve (nameFinder);
g.isRadial = v[radial]; g.isRadial = v[radial];


StringArray colourSteps; StringArray colourSteps;
@@ -83919,26 +83938,24 @@ const FillType Drawable::ValueTreeWrapperBase::readFillType (const ValueTree& v)
return FillType(); return FillType();
} }


void Drawable::ValueTreeWrapperBase::writeFillType (ValueTree& v, const FillType& fillType, UndoManager* const undoManager)
void Drawable::ValueTreeWrapperBase::writeFillType (ValueTree& v, const FillType& fillType,
const RelativePoint* gp1, const RelativePoint* gp2,
UndoManager* const undoManager)
{ {
if (fillType.isColour()) if (fillType.isColour())
{ {
v.setProperty (type, "solid", undoManager); v.setProperty (type, "solid", undoManager);
v.setProperty (colour, String::toHexString ((int) fillType.colour.getARGB()), undoManager); v.setProperty (colour, String::toHexString ((int) fillType.colour.getARGB()), undoManager);
v.removeProperty (x1, undoManager);
v.removeProperty (x2, undoManager);
v.removeProperty (y1, undoManager);
v.removeProperty (y2, undoManager);
v.removeProperty (gradientPoint1, undoManager);
v.removeProperty (gradientPoint2, undoManager);
v.removeProperty (radial, undoManager); v.removeProperty (radial, undoManager);
v.removeProperty (colours, undoManager); v.removeProperty (colours, undoManager);
} }
else if (fillType.isGradient()) else if (fillType.isGradient())
{ {
v.setProperty (type, "gradient", undoManager); v.setProperty (type, "gradient", undoManager);
v.setProperty (x1, fillType.gradient->point1.getX(), undoManager);
v.setProperty (y1, fillType.gradient->point1.getY(), undoManager);
v.setProperty (x2, fillType.gradient->point2.getX(), undoManager);
v.setProperty (y2, fillType.gradient->point2.getY(), undoManager);
v.setProperty (gradientPoint1, gp1 != 0 ? gp1->toString() : fillType.gradient->point1.toString(), undoManager);
v.setProperty (gradientPoint2, gp2 != 0 ? gp2->toString() : fillType.gradient->point2.toString(), undoManager);
v.setProperty (radial, fillType.gradient->isRadial, undoManager); v.setProperty (radial, fillType.gradient->isRadial, undoManager);


String s; String s;
@@ -83955,10 +83972,8 @@ void Drawable::ValueTreeWrapperBase::writeFillType (ValueTree& v, const FillType


jassertfalse; //xxx todo jassertfalse; //xxx todo


v.removeProperty (x1, undoManager);
v.removeProperty (x2, undoManager);
v.removeProperty (y1, undoManager);
v.removeProperty (y2, undoManager);
v.removeProperty (gradientPoint1, undoManager);
v.removeProperty (gradientPoint2, undoManager);
v.removeProperty (radial, undoManager); v.removeProperty (radial, undoManager);
v.removeProperty (colours, undoManager); v.removeProperty (colours, undoManager);
v.removeProperty (colour, undoManager); v.removeProperty (colour, undoManager);
@@ -83969,7 +83984,9 @@ void Drawable::ValueTreeWrapperBase::writeFillType (ValueTree& v, const FillType
} }
} }


void Drawable::ValueTreeWrapperBase::replaceFillType (const Identifier& tag, const FillType& fillType, UndoManager* const undoManager)
void Drawable::ValueTreeWrapperBase::replaceFillType (const Identifier& tag, const FillType& fillType,
const RelativePoint* gp1, const RelativePoint* gp2,
UndoManager* const undoManager)
{ {
ValueTree v (state.getChildWithName (tag)); ValueTree v (state.getChildWithName (tag));


@@ -83979,7 +83996,7 @@ void Drawable::ValueTreeWrapperBase::replaceFillType (const Identifier& tag, con
v = state.getChildWithName (tag); v = state.getChildWithName (tag);
} }


writeFillType (v, fillType, undoManager);
writeFillType (v, fillType, gp1, gp2, undoManager);
} }


END_JUCE_NAMESPACE END_JUCE_NAMESPACE
@@ -85114,24 +85131,46 @@ DrawablePath::ValueTreeWrapper::ValueTreeWrapper (const ValueTree& state_)
jassert (state.hasType (valueTreeType)); jassert (state.hasType (valueTreeType));
} }


const FillType DrawablePath::ValueTreeWrapper::getMainFill() const
ValueTree DrawablePath::ValueTreeWrapper::getMainFillState()
{
ValueTree v (state.getChildWithName (fill));
if (v.isValid())
return v;

setMainFill (Colours::black, 0, 0, 0);
return getMainFillState();
}

ValueTree DrawablePath::ValueTreeWrapper::getStrokeFillState()
{
ValueTree v (state.getChildWithName (stroke));
if (v.isValid())
return v;

setStrokeFill (Colours::black, 0, 0, 0);
return getStrokeFillState();
}

const FillType DrawablePath::ValueTreeWrapper::getMainFill (RelativeCoordinate::NamedCoordinateFinder* nameFinder) const
{ {
return readFillType (state.getChildWithName (fill));
return readFillType (state.getChildWithName (fill), 0, 0, nameFinder);
} }


void DrawablePath::ValueTreeWrapper::setMainFill (const FillType& newFill, UndoManager* undoManager)
void DrawablePath::ValueTreeWrapper::setMainFill (const FillType& newFill, const RelativePoint* gp1,
const RelativePoint* gp2, UndoManager* undoManager)
{ {
replaceFillType (fill, newFill, undoManager);
replaceFillType (fill, newFill, gp1, gp2, undoManager);
} }


const FillType DrawablePath::ValueTreeWrapper::getStrokeFill() const
const FillType DrawablePath::ValueTreeWrapper::getStrokeFill (RelativeCoordinate::NamedCoordinateFinder* nameFinder) const
{ {
return readFillType (state.getChildWithName (stroke));
return readFillType (state.getChildWithName (stroke), 0, 0, nameFinder);
} }


void DrawablePath::ValueTreeWrapper::setStrokeFill (const FillType& newFill, UndoManager* undoManager)
void DrawablePath::ValueTreeWrapper::setStrokeFill (const FillType& newFill, const RelativePoint* gp1,
const RelativePoint* gp2, UndoManager* undoManager)
{ {
replaceFillType (stroke, newFill, undoManager);
replaceFillType (stroke, newFill, gp1, gp2, undoManager);
} }


const PathStrokeType DrawablePath::ValueTreeWrapper::getStrokeType() const const PathStrokeType DrawablePath::ValueTreeWrapper::getStrokeType() const
@@ -85175,7 +85214,7 @@ const Rectangle<float> DrawablePath::refreshFromValueTree (const ValueTree& tree
setName (v.getID()); setName (v.getID());


bool needsRedraw = false; bool needsRedraw = false;
const FillType newFill (v.getMainFill());
const FillType newFill (v.getMainFill (parent));


if (mainFill != newFill) if (mainFill != newFill)
{ {
@@ -85183,7 +85222,7 @@ const Rectangle<float> DrawablePath::refreshFromValueTree (const ValueTree& tree
mainFill = newFill; mainFill = newFill;
} }


const FillType newStrokeFill (v.getStrokeFill());
const FillType newStrokeFill (v.getStrokeFill (parent));


if (strokeFill != newStrokeFill) if (strokeFill != newStrokeFill)
{ {
@@ -85224,8 +85263,8 @@ const ValueTree DrawablePath::createValueTree (ImageProvider*) const
ValueTreeWrapper v (tree); ValueTreeWrapper v (tree);


v.setID (getName(), 0); v.setID (getName(), 0);
v.setMainFill (mainFill, 0);
v.setStrokeFill (strokeFill, 0);
v.setMainFill (mainFill, 0, 0, 0);
v.setStrokeFill (strokeFill, 0, 0, 0);
v.setStrokeType (strokeType, 0); v.setStrokeType (strokeType, 0);


if (relativePath != 0) if (relativePath != 0)
@@ -253051,8 +253090,8 @@ public:
{ {
//DBG (responseHeader); //DBG (responseHeader);


StringArray lines;
lines.addLines (responseHeader);
headerLines.clear();
headerLines.addLines (responseHeader);


const int statusCode = responseHeader.fromFirstOccurrenceOf (" ", false, false) const int statusCode = responseHeader.fromFirstOccurrenceOf (" ", false, false)
.substring (0, 3).getIntValue(); .substring (0, 3).getIntValue();
@@ -253060,7 +253099,7 @@ public:
//int contentLength = findHeaderItem (lines, "Content-Length:").getIntValue(); //int contentLength = findHeaderItem (lines, "Content-Length:").getIntValue();
//bool isChunked = findHeaderItem (lines, "Transfer-Encoding:").equalsIgnoreCase ("chunked"); //bool isChunked = findHeaderItem (lines, "Transfer-Encoding:").equalsIgnoreCase ("chunked");


String location (findHeaderItem (lines, "Location:"));
String location (findHeaderItem (headerLines, "Location:"));


if (statusCode >= 300 && statusCode < 400 if (statusCode >= 300 && statusCode < 400
&& location.isNotEmpty()) && location.isNotEmpty())
@@ -253101,6 +253140,7 @@ public:
} }


int readPosition; int readPosition;
StringArray headerLines;


juce_UseDebuggingNewOperator juce_UseDebuggingNewOperator


@@ -253250,13 +253290,11 @@ void* juce_openInternetFile (const String& url,
void* callbackContext, void* callbackContext,
int timeOutMs) int timeOutMs)
{ {
JUCE_HTTPSocketStream* const s = new JUCE_HTTPSocketStream();
ScopedPointer<JUCE_HTTPSocketStream> s (new JUCE_HTTPSocketStream());


if (s->open (url, headers, postData, isPost,
callback, callbackContext, timeOutMs))
return s;
if (s->open (url, headers, postData, isPost, callback, callbackContext, timeOutMs))
return s.release();


delete s;
return 0; return 0;
} }


@@ -253267,46 +253305,46 @@ void juce_closeInternetFile (void* handle)


int juce_readFromInternetFile (void* handle, void* buffer, int bytesToRead) int juce_readFromInternetFile (void* handle, void* buffer, int bytesToRead)
{ {
JUCE_HTTPSocketStream* const s = (JUCE_HTTPSocketStream*) handle;

if (s != 0)
return s->read (buffer, bytesToRead);
JUCE_HTTPSocketStream* const s = static_cast <JUCE_HTTPSocketStream*> (handle);


return 0;
return s != 0 ? s->read (buffer, bytesToRead) : 0;
} }


int64 juce_getInternetFileContentLength (void* handle) int64 juce_getInternetFileContentLength (void* handle)
{ {
JUCE_HTTPSocketStream* const s = (JUCE_HTTPSocketStream*) handle;
JUCE_HTTPSocketStream* const s = static_cast <JUCE_HTTPSocketStream*> (handle);


if (s != 0) if (s != 0)
{ {
//xxx todo //xxx todo
jassertfalse;
jassertfalse
} }


return -1; return -1;
} }


void juce_getInternetFileHeaders (void* handle, StringPairArray& headers)
bool juce_getInternetFileHeaders (void* handle, StringPairArray& headers)
{ {
JUCE_HTTPSocketStream* const s = (JUCE_HTTPSocketStream*) handle;
JUCE_HTTPSocketStream* const s = static_cast <JUCE_HTTPSocketStream*> (handle);


if (s != 0) if (s != 0)
{ {
// xxx todo
jassertfalse;
for (int i = 0; i < s->headerLines.size(); ++i)
{
const String& headersEntry = s->headerLines[i];
const String key (headersEntry.upToFirstOccurrenceOf (": ", false, false));
const String value (headersEntry.fromFirstOccurrenceOf (": ", false, false));
const String previousValue (headers [key]);
headers.set (key, previousValue.isEmpty() ? value : (previousValue + ";" + value));
}
} }
} }


int juce_seekInInternetFile (void* handle, int newPosition) int juce_seekInInternetFile (void* handle, int newPosition)
{ {
JUCE_HTTPSocketStream* const s = (JUCE_HTTPSocketStream*) handle;
JUCE_HTTPSocketStream* const s = static_cast <JUCE_HTTPSocketStream*> (handle);


if (s != 0)
return s->readPosition;

return 0;
return s != 0 ? s->readPosition : 0;
} }


#endif #endif


+ 34
- 16
juce_amalgamated.h View File

@@ -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 6
#define JUCE_BUILDNUMBER 7


/** Current Juce version number. /** Current Juce version number.


@@ -23179,9 +23179,13 @@ public:
of the distance along the line between the two points of the distance along the line between the two points
at which the colour should occur. at which the colour should occur.
@param colour the colour that should be used at this point @param colour the colour that should be used at this point
@returns the index at which the new point was added
*/ */
void addColour (double proportionAlongGradient,
const Colour& colour);
int addColour (double proportionAlongGradient,
const Colour& colour);

/** Removes one of the colours from the gradient. */
void removeColour (int index);


/** Multiplies the alpha value of all the colours by the given scale factor */ /** Multiplies the alpha value of all the colours by the given scale factor */
void multiplyOpacity (float multiplier) throw(); void multiplyOpacity (float multiplier) throw();
@@ -23196,15 +23200,19 @@ public:
double getColourPosition (int index) const throw(); double getColourPosition (int index) const throw();


/** Returns the colour that was added with a given index. /** Returns the colour that was added with a given index.

The index is from 0 to getNumColours() - 1. The return value will be between 0.0 and 1.0
The index is from 0 to getNumColours() - 1.
*/ */
const Colour getColour (int index) const throw(); const Colour getColour (int index) const throw();


/** Changes the colour at a given index.
The index is from 0 to getNumColours() - 1.
*/
void setColour (int index, const Colour& newColour) throw();

/** Returns the an interpolated colour at any position along the gradient. /** Returns the an interpolated colour at any position along the gradient.
@param position the position along the gradient, between 0 and 1 @param position the position along the gradient, between 0 and 1
*/ */
const Colour getColourAtPosition (float position) const throw();
const Colour getColourAtPosition (double position) const throw();


/** Creates a set of interpolated premultiplied ARGB values. /** Creates a set of interpolated premultiplied ARGB values.
This will resize the HeapBlock, fill it with the colours, and will return the number of This will resize the HeapBlock, fill it with the colours, and will return the number of
@@ -23237,14 +23245,14 @@ private:
{ {
ColourPoint() throw() {} ColourPoint() throw() {}


ColourPoint (uint32 position_, const Colour& colour_) throw()
ColourPoint (const double position_, const Colour& colour_) throw()
: position (position_), colour (colour_) : position (position_), colour (colour_)
{} {}


bool operator== (const ColourPoint& other) const throw() { return position == other.position && colour == other.colour; } bool operator== (const ColourPoint& other) const throw() { return position == other.position && colour == other.colour; }
bool operator!= (const ColourPoint& other) const throw() { return position != other.position || colour != other.colour; } bool operator!= (const ColourPoint& other) const throw() { return position != other.position || colour != other.colour; }


uint32 position;
double position;
Colour colour; Colour colour;
}; };


@@ -42586,14 +42594,20 @@ public:
void setID (const String& newID, UndoManager* undoManager); void setID (const String& newID, UndoManager* undoManager);
static const Identifier idProperty; static const Identifier idProperty;


static const FillType readFillType (const ValueTree& v);
static void writeFillType (ValueTree& v, const FillType& fillType, UndoManager* undoManager);
static const FillType readFillType (const ValueTree& v, RelativePoint* gradientPoint1, RelativePoint* gradientPoint2,
RelativeCoordinate::NamedCoordinateFinder* nameFinder);

static void writeFillType (ValueTree& v, const FillType& fillType,
const RelativePoint* gradientPoint1, const RelativePoint* gradientPoint2,
UndoManager* undoManager);


protected: protected:
ValueTree state; ValueTree state;
static const Identifier type, x1, x2, y1, y2, colour, radial, colours;
static const Identifier type, gradientPoint1, gradientPoint2, colour, radial, colours;


void replaceFillType (const Identifier& tag, const FillType& fillType, UndoManager* undoManager);
void replaceFillType (const Identifier& tag, const FillType& fillType,
const RelativePoint* gradientPoint1, const RelativePoint* gradientPoint2,
UndoManager* undoManager);
}; };


juce_UseDebuggingNewOperator juce_UseDebuggingNewOperator
@@ -58593,11 +58607,15 @@ public:
public: public:
ValueTreeWrapper (const ValueTree& state); ValueTreeWrapper (const ValueTree& state);


const FillType getMainFill() const;
void setMainFill (const FillType& newFill, UndoManager* undoManager);
const FillType getMainFill (RelativeCoordinate::NamedCoordinateFinder* nameFinder) const;
ValueTree getMainFillState();
void setMainFill (const FillType& newFill, const RelativePoint* gradientPoint1,
const RelativePoint* gradientPoint2, UndoManager* undoManager);


const FillType getStrokeFill() const;
void setStrokeFill (const FillType& newFill, UndoManager* undoManager);
const FillType getStrokeFill (RelativeCoordinate::NamedCoordinateFinder* nameFinder) const;
ValueTree getStrokeFillState();
void setStrokeFill (const FillType& newFill, const RelativePoint* gradientPoint1,
const RelativePoint* gradientPoint2, UndoManager* undoManager);


const PathStrokeType getStrokeType() const; const PathStrokeType getStrokeType() const;
void setStrokeType (const PathStrokeType& newStrokeType, UndoManager* undoManager); void setStrokeType (const PathStrokeType& newStrokeType, UndoManager* undoManager);


+ 6
- 1
src/audio/processors/juce_AudioProcessorPlayer.cpp View File

@@ -133,7 +133,12 @@ void AudioProcessorPlayer::audioDeviceIOCallback (const float** inputChannelData
const ScopedLock sl (lock); const ScopedLock sl (lock);
if (processor != 0) if (processor != 0)
processor->processBlock (buffer, incomingMidi);
{
const ScopedLock sl (processor->getCallbackLock());
if (! processor->isSuspended())
processor->processBlock (buffer, incomingMidi);
}
} }
void AudioProcessorPlayer::audioDeviceAboutToStart (AudioIODevice* device) void AudioProcessorPlayer::audioDeviceAboutToStart (AudioIODevice* device)


+ 1
- 1
src/core/juce_StandardHeader.h View File

@@ -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 6
#define JUCE_BUILDNUMBER 7
/** Current Juce version number. /** Current Juce version number.


+ 29
- 22
src/gui/graphics/colour/juce_ColourGradient.cpp View File

@@ -38,19 +38,15 @@ ColourGradient::ColourGradient() throw()
#endif #endif
} }
ColourGradient::ColourGradient (const Colour& colour1,
const float x1_,
const float y1_,
const Colour& colour2,
const float x2_,
const float y2_,
ColourGradient::ColourGradient (const Colour& colour1, const float x1_, const float y1_,
const Colour& colour2, const float x2_, const float y2_,
const bool isRadial_) const bool isRadial_)
: point1 (x1_, y1_), : point1 (x1_, y1_),
point2 (x2_, y2_), point2 (x2_, y2_),
isRadial (isRadial_) isRadial (isRadial_)
{ {
colours.add (ColourPoint (0, colour1));
colours.add (ColourPoint (1 << 16, colour2));
colours.add (ColourPoint (0.0, colour1));
colours.add (ColourPoint (1.0, colour2));
} }
ColourGradient::~ColourGradient() ColourGradient::~ColourGradient()
@@ -75,13 +71,12 @@ void ColourGradient::clearColours()
colours.clear(); colours.clear();
} }
void ColourGradient::addColour (const double proportionAlongGradient,
const Colour& colour)
int ColourGradient::addColour (const double proportionAlongGradient, const Colour& colour)
{ {
// must be within the two end-points // must be within the two end-points
jassert (proportionAlongGradient >= 0 && proportionAlongGradient <= 1.0); jassert (proportionAlongGradient >= 0 && proportionAlongGradient <= 1.0);
const uint32 pos = jlimit (0, 65535, roundToInt (proportionAlongGradient * 65536.0));
const double pos = jlimit (0.0, 1.0, proportionAlongGradient);
int i; int i;
for (i = 0; i < colours.size(); ++i) for (i = 0; i < colours.size(); ++i)
@@ -89,6 +84,13 @@ void ColourGradient::addColour (const double proportionAlongGradient,
break; break;
colours.insert (i, ColourPoint (pos, colour)); colours.insert (i, ColourPoint (pos, colour));
return i;
}
void ColourGradient::removeColour (int index)
{
jassert (index > 0 && index < colours.size() - 1);
colours.remove (index);
} }
void ColourGradient::multiplyOpacity (const float multiplier) throw() void ColourGradient::multiplyOpacity (const float multiplier) throw()
@@ -109,7 +111,7 @@ int ColourGradient::getNumColours() const throw()
double ColourGradient::getColourPosition (const int index) const throw() double ColourGradient::getColourPosition (const int index) const throw()
{ {
if (((unsigned int) index) < (unsigned int) colours.size()) if (((unsigned int) index) < (unsigned int) colours.size())
return jlimit (0.0, 1.0, colours.getReference (index).position / 65535.0);
return colours.getReference (index).position;
return 0; return 0;
} }
@@ -122,26 +124,31 @@ const Colour ColourGradient::getColour (const int index) const throw()
return Colour(); return Colour();
} }
const Colour ColourGradient::getColourAtPosition (const float position) const throw()
void ColourGradient::setColour (int index, const Colour& newColour) throw()
{ {
jassert (colours.getReference(0).position == 0); // the first colour specified has to go at position 0
if (((unsigned int) index) < (unsigned int) colours.size())
colours.getReference (index).colour = newColour;
}
const int integerPos = jlimit (0, 65535, roundToInt (position * 65536.0f));
const Colour ColourGradient::getColourAtPosition (const double position) const throw()
{
jassert (colours.getReference(0).position == 0); // the first colour specified has to go at position 0
if (integerPos <= 0 || colours.size() <= 1)
return getColour (0);
if (position <= 0 || colours.size() <= 1)
return colours.getReference(0).colour;
int i = colours.size() - 1; int i = colours.size() - 1;
while (integerPos < (int) colours.getReference(i).position)
while (position < colours.getReference(i).position)
--i; --i;
const ColourPoint& p1 = colours.getReference (i);
if (i >= colours.size() - 1) if (i >= colours.size() - 1)
return colours.getReference(i).colour;
return p1.colour;
const ColourPoint& p1 = colours.getReference (i);
const ColourPoint& p2 = colours.getReference (i + 1); const ColourPoint& p2 = colours.getReference (i + 1);
return p1.colour.interpolatedWith (p2.colour, (integerPos - p1.position) / (float) (p2.position - p1.position));
return p1.colour.interpolatedWith (p2.colour, (float) ((position - p1.position) / (p2.position - p1.position)));
} }
//============================================================================== //==============================================================================
@@ -168,7 +175,7 @@ int ColourGradient::createLookupTable (const AffineTransform& transform, HeapBlo
for (int j = 1; j < colours.size(); ++j) for (int j = 1; j < colours.size(); ++j)
{ {
const ColourPoint& p = colours.getReference (j); const ColourPoint& p = colours.getReference (j);
const int numToDo = ((p.position * (numEntries - 1)) >> 16) - index;
const int numToDo = roundToInt (p.position * (numEntries - 1)) - index;
const PixelARGB pix2 (p.colour.getPixelARGB()); const PixelARGB pix2 (p.colour.getPixelARGB());
for (int i = 0; i < numToDo; ++i) for (int i = 0; i < numToDo; ++i)


+ 15
- 7
src/gui/graphics/colour/juce_ColourGradient.h View File

@@ -90,9 +90,13 @@ public:
of the distance along the line between the two points of the distance along the line between the two points
at which the colour should occur. at which the colour should occur.
@param colour the colour that should be used at this point @param colour the colour that should be used at this point
@returns the index at which the new point was added
*/ */
void addColour (double proportionAlongGradient,
const Colour& colour);
int addColour (double proportionAlongGradient,
const Colour& colour);
/** Removes one of the colours from the gradient. */
void removeColour (int index);
/** Multiplies the alpha value of all the colours by the given scale factor */ /** Multiplies the alpha value of all the colours by the given scale factor */
void multiplyOpacity (float multiplier) throw(); void multiplyOpacity (float multiplier) throw();
@@ -108,15 +112,19 @@ public:
double getColourPosition (int index) const throw(); double getColourPosition (int index) const throw();
/** Returns the colour that was added with a given index. /** Returns the colour that was added with a given index.
The index is from 0 to getNumColours() - 1. The return value will be between 0.0 and 1.0
The index is from 0 to getNumColours() - 1.
*/ */
const Colour getColour (int index) const throw(); const Colour getColour (int index) const throw();
/** Changes the colour at a given index.
The index is from 0 to getNumColours() - 1.
*/
void setColour (int index, const Colour& newColour) throw();
/** Returns the an interpolated colour at any position along the gradient. /** Returns the an interpolated colour at any position along the gradient.
@param position the position along the gradient, between 0 and 1 @param position the position along the gradient, between 0 and 1
*/ */
const Colour getColourAtPosition (float position) const throw();
const Colour getColourAtPosition (double position) const throw();
//============================================================================== //==============================================================================
/** Creates a set of interpolated premultiplied ARGB values. /** Creates a set of interpolated premultiplied ARGB values.
@@ -152,14 +160,14 @@ private:
{ {
ColourPoint() throw() {} ColourPoint() throw() {}
ColourPoint (uint32 position_, const Colour& colour_) throw()
ColourPoint (const double position_, const Colour& colour_) throw()
: position (position_), colour (colour_) : position (position_), colour (colour_)
{} {}
bool operator== (const ColourPoint& other) const throw() { return position == other.position && colour == other.colour; } bool operator== (const ColourPoint& other) const throw() { return position == other.position && colour == other.colour; }
bool operator!= (const ColourPoint& other) const throw() { return position != other.position || colour != other.colour; } bool operator!= (const ColourPoint& other) const throw() { return position != other.position || colour != other.colour; }
uint32 position;
double position;
Colour colour; Colour colour;
}; };


+ 27
- 22
src/gui/graphics/drawables/juce_Drawable.cpp View File

@@ -158,10 +158,8 @@ Drawable* Drawable::createFromValueTree (const ValueTree& tree, ImageProvider* i
//============================================================================== //==============================================================================
const Identifier Drawable::ValueTreeWrapperBase::idProperty ("id"); const Identifier Drawable::ValueTreeWrapperBase::idProperty ("id");
const Identifier Drawable::ValueTreeWrapperBase::type ("type"); const Identifier Drawable::ValueTreeWrapperBase::type ("type");
const Identifier Drawable::ValueTreeWrapperBase::x1 ("x1");
const Identifier Drawable::ValueTreeWrapperBase::x2 ("x2");
const Identifier Drawable::ValueTreeWrapperBase::y1 ("y1");
const Identifier Drawable::ValueTreeWrapperBase::y2 ("y2");
const Identifier Drawable::ValueTreeWrapperBase::gradientPoint1 ("point1");
const Identifier Drawable::ValueTreeWrapperBase::gradientPoint2 ("point2");
const Identifier Drawable::ValueTreeWrapperBase::colour ("colour"); const Identifier Drawable::ValueTreeWrapperBase::colour ("colour");
const Identifier Drawable::ValueTreeWrapperBase::radial ("radial"); const Identifier Drawable::ValueTreeWrapperBase::radial ("radial");
const Identifier Drawable::ValueTreeWrapperBase::colours ("colours"); const Identifier Drawable::ValueTreeWrapperBase::colours ("colours");
@@ -188,7 +186,8 @@ void Drawable::ValueTreeWrapperBase::setID (const String& newID, UndoManager* un
state.setProperty (idProperty, newID, undoManager); state.setProperty (idProperty, newID, undoManager);
} }
const FillType Drawable::ValueTreeWrapperBase::readFillType (const ValueTree& v)
const FillType Drawable::ValueTreeWrapperBase::readFillType (const ValueTree& v, RelativePoint* gp1, RelativePoint* gp2,
RelativeCoordinate::NamedCoordinateFinder* nameFinder)
{ {
const String newType (v[type].toString()); const String newType (v[type].toString());
@@ -200,9 +199,17 @@ const FillType Drawable::ValueTreeWrapperBase::readFillType (const ValueTree& v)
} }
else if (newType == "gradient") else if (newType == "gradient")
{ {
RelativePoint p1 (v [gradientPoint1]), p2 (v [gradientPoint2]);
ColourGradient g; ColourGradient g;
g.point1.setXY (v[x1], v[y1]);
g.point2.setXY (v[x2], v[y2]);
if (gp1 != 0)
*gp1 = p1;
if (gp2 != 0)
*gp2 = p2;
g.point1 = p1.resolve (nameFinder);
g.point2 = p2.resolve (nameFinder);
g.isRadial = v[radial]; g.isRadial = v[radial];
StringArray colourSteps; StringArray colourSteps;
@@ -223,26 +230,24 @@ const FillType Drawable::ValueTreeWrapperBase::readFillType (const ValueTree& v)
return FillType(); return FillType();
} }
void Drawable::ValueTreeWrapperBase::writeFillType (ValueTree& v, const FillType& fillType, UndoManager* const undoManager)
void Drawable::ValueTreeWrapperBase::writeFillType (ValueTree& v, const FillType& fillType,
const RelativePoint* gp1, const RelativePoint* gp2,
UndoManager* const undoManager)
{ {
if (fillType.isColour()) if (fillType.isColour())
{ {
v.setProperty (type, "solid", undoManager); v.setProperty (type, "solid", undoManager);
v.setProperty (colour, String::toHexString ((int) fillType.colour.getARGB()), undoManager); v.setProperty (colour, String::toHexString ((int) fillType.colour.getARGB()), undoManager);
v.removeProperty (x1, undoManager);
v.removeProperty (x2, undoManager);
v.removeProperty (y1, undoManager);
v.removeProperty (y2, undoManager);
v.removeProperty (gradientPoint1, undoManager);
v.removeProperty (gradientPoint2, undoManager);
v.removeProperty (radial, undoManager); v.removeProperty (radial, undoManager);
v.removeProperty (colours, undoManager); v.removeProperty (colours, undoManager);
} }
else if (fillType.isGradient()) else if (fillType.isGradient())
{ {
v.setProperty (type, "gradient", undoManager); v.setProperty (type, "gradient", undoManager);
v.setProperty (x1, fillType.gradient->point1.getX(), undoManager);
v.setProperty (y1, fillType.gradient->point1.getY(), undoManager);
v.setProperty (x2, fillType.gradient->point2.getX(), undoManager);
v.setProperty (y2, fillType.gradient->point2.getY(), undoManager);
v.setProperty (gradientPoint1, gp1 != 0 ? gp1->toString() : fillType.gradient->point1.toString(), undoManager);
v.setProperty (gradientPoint2, gp2 != 0 ? gp2->toString() : fillType.gradient->point2.toString(), undoManager);
v.setProperty (radial, fillType.gradient->isRadial, undoManager); v.setProperty (radial, fillType.gradient->isRadial, undoManager);
String s; String s;
@@ -259,10 +264,8 @@ void Drawable::ValueTreeWrapperBase::writeFillType (ValueTree& v, const FillType
jassertfalse; //xxx todo jassertfalse; //xxx todo
v.removeProperty (x1, undoManager);
v.removeProperty (x2, undoManager);
v.removeProperty (y1, undoManager);
v.removeProperty (y2, undoManager);
v.removeProperty (gradientPoint1, undoManager);
v.removeProperty (gradientPoint2, undoManager);
v.removeProperty (radial, undoManager); v.removeProperty (radial, undoManager);
v.removeProperty (colours, undoManager); v.removeProperty (colours, undoManager);
v.removeProperty (colour, undoManager); v.removeProperty (colour, undoManager);
@@ -273,7 +276,9 @@ void Drawable::ValueTreeWrapperBase::writeFillType (ValueTree& v, const FillType
} }
} }
void Drawable::ValueTreeWrapperBase::replaceFillType (const Identifier& tag, const FillType& fillType, UndoManager* const undoManager)
void Drawable::ValueTreeWrapperBase::replaceFillType (const Identifier& tag, const FillType& fillType,
const RelativePoint* gp1, const RelativePoint* gp2,
UndoManager* const undoManager)
{ {
ValueTree v (state.getChildWithName (tag)); ValueTree v (state.getChildWithName (tag));
@@ -283,7 +288,7 @@ void Drawable::ValueTreeWrapperBase::replaceFillType (const Identifier& tag, con
v = state.getChildWithName (tag); v = state.getChildWithName (tag);
} }
writeFillType (v, fillType, undoManager);
writeFillType (v, fillType, gp1, gp2, undoManager);
} }


+ 10
- 4
src/gui/graphics/drawables/juce_Drawable.h View File

@@ -248,14 +248,20 @@ public:
void setID (const String& newID, UndoManager* undoManager); void setID (const String& newID, UndoManager* undoManager);
static const Identifier idProperty; static const Identifier idProperty;
static const FillType readFillType (const ValueTree& v);
static void writeFillType (ValueTree& v, const FillType& fillType, UndoManager* undoManager);
static const FillType readFillType (const ValueTree& v, RelativePoint* gradientPoint1, RelativePoint* gradientPoint2,
RelativeCoordinate::NamedCoordinateFinder* nameFinder);
static void writeFillType (ValueTree& v, const FillType& fillType,
const RelativePoint* gradientPoint1, const RelativePoint* gradientPoint2,
UndoManager* undoManager);
protected: protected:
ValueTree state; ValueTree state;
static const Identifier type, x1, x2, y1, y2, colour, radial, colours;
static const Identifier type, gradientPoint1, gradientPoint2, colour, radial, colours;
void replaceFillType (const Identifier& tag, const FillType& fillType, UndoManager* undoManager);
void replaceFillType (const Identifier& tag, const FillType& fillType,
const RelativePoint* gradientPoint1, const RelativePoint* gradientPoint2,
UndoManager* undoManager);
}; };
//============================================================================== //==============================================================================


+ 34
- 12
src/gui/graphics/drawables/juce_DrawablePath.cpp View File

@@ -197,24 +197,46 @@ DrawablePath::ValueTreeWrapper::ValueTreeWrapper (const ValueTree& state_)
jassert (state.hasType (valueTreeType)); jassert (state.hasType (valueTreeType));
} }
const FillType DrawablePath::ValueTreeWrapper::getMainFill() const
ValueTree DrawablePath::ValueTreeWrapper::getMainFillState()
{ {
return readFillType (state.getChildWithName (fill));
ValueTree v (state.getChildWithName (fill));
if (v.isValid())
return v;
setMainFill (Colours::black, 0, 0, 0);
return getMainFillState();
}
ValueTree DrawablePath::ValueTreeWrapper::getStrokeFillState()
{
ValueTree v (state.getChildWithName (stroke));
if (v.isValid())
return v;
setStrokeFill (Colours::black, 0, 0, 0);
return getStrokeFillState();
}
const FillType DrawablePath::ValueTreeWrapper::getMainFill (RelativeCoordinate::NamedCoordinateFinder* nameFinder) const
{
return readFillType (state.getChildWithName (fill), 0, 0, nameFinder);
} }
void DrawablePath::ValueTreeWrapper::setMainFill (const FillType& newFill, UndoManager* undoManager)
void DrawablePath::ValueTreeWrapper::setMainFill (const FillType& newFill, const RelativePoint* gp1,
const RelativePoint* gp2, UndoManager* undoManager)
{ {
replaceFillType (fill, newFill, undoManager);
replaceFillType (fill, newFill, gp1, gp2, undoManager);
} }
const FillType DrawablePath::ValueTreeWrapper::getStrokeFill() const
const FillType DrawablePath::ValueTreeWrapper::getStrokeFill (RelativeCoordinate::NamedCoordinateFinder* nameFinder) const
{ {
return readFillType (state.getChildWithName (stroke));
return readFillType (state.getChildWithName (stroke), 0, 0, nameFinder);
} }
void DrawablePath::ValueTreeWrapper::setStrokeFill (const FillType& newFill, UndoManager* undoManager)
void DrawablePath::ValueTreeWrapper::setStrokeFill (const FillType& newFill, const RelativePoint* gp1,
const RelativePoint* gp2, UndoManager* undoManager)
{ {
replaceFillType (stroke, newFill, undoManager);
replaceFillType (stroke, newFill, gp1, gp2, undoManager);
} }
const PathStrokeType DrawablePath::ValueTreeWrapper::getStrokeType() const const PathStrokeType DrawablePath::ValueTreeWrapper::getStrokeType() const
@@ -258,7 +280,7 @@ const Rectangle<float> DrawablePath::refreshFromValueTree (const ValueTree& tree
setName (v.getID()); setName (v.getID());
bool needsRedraw = false; bool needsRedraw = false;
const FillType newFill (v.getMainFill());
const FillType newFill (v.getMainFill (parent));
if (mainFill != newFill) if (mainFill != newFill)
{ {
@@ -266,7 +288,7 @@ const Rectangle<float> DrawablePath::refreshFromValueTree (const ValueTree& tree
mainFill = newFill; mainFill = newFill;
} }
const FillType newStrokeFill (v.getStrokeFill());
const FillType newStrokeFill (v.getStrokeFill (parent));
if (strokeFill != newStrokeFill) if (strokeFill != newStrokeFill)
{ {
@@ -307,8 +329,8 @@ const ValueTree DrawablePath::createValueTree (ImageProvider*) const
ValueTreeWrapper v (tree); ValueTreeWrapper v (tree);
v.setID (getName(), 0); v.setID (getName(), 0);
v.setMainFill (mainFill, 0);
v.setStrokeFill (strokeFill, 0);
v.setMainFill (mainFill, 0, 0, 0);
v.setStrokeFill (strokeFill, 0, 0, 0);
v.setStrokeType (strokeType, 0); v.setStrokeType (strokeType, 0);
if (relativePath != 0) if (relativePath != 0)


+ 9
- 5
src/gui/graphics/drawables/juce_DrawablePath.h View File

@@ -128,11 +128,15 @@ public:
public: public:
ValueTreeWrapper (const ValueTree& state); ValueTreeWrapper (const ValueTree& state);
const FillType getMainFill() const;
void setMainFill (const FillType& newFill, UndoManager* undoManager);
const FillType getStrokeFill() const;
void setStrokeFill (const FillType& newFill, UndoManager* undoManager);
const FillType getMainFill (RelativeCoordinate::NamedCoordinateFinder* nameFinder) const;
ValueTree getMainFillState();
void setMainFill (const FillType& newFill, const RelativePoint* gradientPoint1,
const RelativePoint* gradientPoint2, UndoManager* undoManager);
const FillType getStrokeFill (RelativeCoordinate::NamedCoordinateFinder* nameFinder) const;
ValueTree getStrokeFillState();
void setStrokeFill (const FillType& newFill, const RelativePoint* gradientPoint1,
const RelativePoint* gradientPoint2, UndoManager* undoManager);
const PathStrokeType getStrokeType() const; const PathStrokeType getStrokeType() const;
void setStrokeType (const PathStrokeType& newStrokeType, UndoManager* undoManager); void setStrokeType (const PathStrokeType& newStrokeType, UndoManager* undoManager);


+ 481
- 482
src/native/linux/juce_linux_Network.cpp View File

@@ -1,482 +1,481 @@
/*
==============================================================================
This file is part of the JUCE library - "Jules' Utility Class Extensions"
Copyright 2004-10 by Raw Material Software Ltd.
------------------------------------------------------------------------------
JUCE can be redistributed and/or modified under the terms of the GNU General
Public License (Version 2), as published by the Free Software Foundation.
A copy of the license is included in the JUCE distribution, or can be found
online at www.gnu.org/licenses.
JUCE is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
------------------------------------------------------------------------------
To release a closed-source product which uses JUCE, commercial licenses are
available: visit www.rawmaterialsoftware.com/juce for more information.
==============================================================================
*/
// (This file gets included by juce_linux_NativeCode.cpp, rather than being
// compiled on its own).
#if JUCE_INCLUDED_FILE
//==============================================================================
int SystemStats::getMACAddresses (int64* addresses, int maxNum, const bool littleEndian)
{
int numResults = 0;
const int s = socket (AF_INET, SOCK_DGRAM, 0);
if (s != -1)
{
char buf [1024];
struct ifconf ifc;
ifc.ifc_len = sizeof (buf);
ifc.ifc_buf = buf;
ioctl (s, SIOCGIFCONF, &ifc);
for (unsigned int i = 0; i < ifc.ifc_len / sizeof (struct ifreq); ++i)
{
struct ifreq ifr;
strcpy (ifr.ifr_name, ifc.ifc_req[i].ifr_name);
if (ioctl (s, SIOCGIFFLAGS, &ifr) == 0
&& (ifr.ifr_flags & IFF_LOOPBACK) == 0
&& ioctl (s, SIOCGIFHWADDR, &ifr) == 0
&& numResults < maxNum)
{
int64 a = 0;
for (int j = 6; --j >= 0;)
a = (a << 8) | (uint8) ifr.ifr_hwaddr.sa_data [littleEndian ? j : (5 - j)];
*addresses++ = a;
++numResults;
}
}
close (s);
}
return numResults;
}
bool PlatformUtilities::launchEmailWithAttachments (const String& targetEmailAddress,
const String& emailSubject,
const String& bodyText,
const StringArray& filesToAttach)
{
jassertfalse; // xxx todo
return false;
}
//==============================================================================
/** A HTTP input stream that uses sockets.
*/
class JUCE_HTTPSocketStream
{
public:
//==============================================================================
JUCE_HTTPSocketStream()
: readPosition (0),
socketHandle (-1),
levelsOfRedirection (0),
timeoutSeconds (15)
{
}
~JUCE_HTTPSocketStream()
{
closeSocket();
}
//==============================================================================
bool open (const String& url,
const String& headers,
const MemoryBlock& postData,
const bool isPost,
URL::OpenStreamProgressCallback* callback,
void* callbackContext,
int timeOutMs)
{
closeSocket();
uint32 timeOutTime = Time::getMillisecondCounter();
if (timeOutMs == 0)
timeOutTime += 60000;
else if (timeOutMs < 0)
timeOutTime = 0xffffffff;
else
timeOutTime += timeOutMs;
String hostName, hostPath;
int hostPort;
if (! decomposeURL (url, hostName, hostPath, hostPort))
return false;
const struct hostent* host = 0;
int port = 0;
String proxyName, proxyPath;
int proxyPort = 0;
String proxyURL (getenv ("http_proxy"));
if (proxyURL.startsWithIgnoreCase ("http://"))
{
if (! decomposeURL (proxyURL, proxyName, proxyPath, proxyPort))
return false;
host = gethostbyname (proxyName.toUTF8());
port = proxyPort;
}
else
{
host = gethostbyname (hostName.toUTF8());
port = hostPort;
}
if (host == 0)
return false;
struct sockaddr_in address;
zerostruct (address);
memcpy (&address.sin_addr, host->h_addr, host->h_length);
address.sin_family = host->h_addrtype;
address.sin_port = htons (port);
socketHandle = socket (host->h_addrtype, SOCK_STREAM, 0);
if (socketHandle == -1)
return false;
int receiveBufferSize = 16384;
setsockopt (socketHandle, SOL_SOCKET, SO_RCVBUF, (char*) &receiveBufferSize, sizeof (receiveBufferSize));
setsockopt (socketHandle, SOL_SOCKET, SO_KEEPALIVE, 0, 0);
#if JUCE_MAC
setsockopt (socketHandle, SOL_SOCKET, SO_NOSIGPIPE, 0, 0);
#endif
if (connect (socketHandle, (struct sockaddr*) &address, sizeof (address)) == -1)
{
closeSocket();
return false;
}
const MemoryBlock requestHeader (createRequestHeader (hostName, hostPort,
proxyName, proxyPort,
hostPath, url,
headers, postData,
isPost));
size_t totalHeaderSent = 0;
while (totalHeaderSent < requestHeader.getSize())
{
if (Time::getMillisecondCounter() > timeOutTime)
{
closeSocket();
return false;
}
const int numToSend = jmin (1024, (int) (requestHeader.getSize() - totalHeaderSent));
if (send (socketHandle,
((const char*) requestHeader.getData()) + totalHeaderSent,
numToSend, 0)
!= numToSend)
{
closeSocket();
return false;
}
totalHeaderSent += numToSend;
if (callback != 0 && ! callback (callbackContext, totalHeaderSent, requestHeader.getSize()))
{
closeSocket();
return false;
}
}
const String responseHeader (readResponse (timeOutTime));
if (responseHeader.isNotEmpty())
{
//DBG (responseHeader);
StringArray lines;
lines.addLines (responseHeader);
const int statusCode = responseHeader.fromFirstOccurrenceOf (" ", false, false)
.substring (0, 3).getIntValue();
//int contentLength = findHeaderItem (lines, "Content-Length:").getIntValue();
//bool isChunked = findHeaderItem (lines, "Transfer-Encoding:").equalsIgnoreCase ("chunked");
String location (findHeaderItem (lines, "Location:"));
if (statusCode >= 300 && statusCode < 400
&& location.isNotEmpty())
{
if (! location.startsWithIgnoreCase ("http://"))
location = "http://" + location;
if (levelsOfRedirection++ < 3)
return open (location, headers, postData, isPost, callback, callbackContext, timeOutMs);
}
else
{
levelsOfRedirection = 0;
return true;
}
}
closeSocket();
return false;
}
//==============================================================================
int read (void* buffer, int bytesToRead)
{
fd_set readbits;
FD_ZERO (&readbits);
FD_SET (socketHandle, &readbits);
struct timeval tv;
tv.tv_sec = timeoutSeconds;
tv.tv_usec = 0;
if (select (socketHandle + 1, &readbits, 0, 0, &tv) <= 0)
return 0; // (timeout)
const int bytesRead = jmax (0, (int) recv (socketHandle, buffer, bytesToRead, MSG_WAITALL));
readPosition += bytesRead;
return bytesRead;
}
//==============================================================================
int readPosition;
//==============================================================================
juce_UseDebuggingNewOperator
private:
int socketHandle, levelsOfRedirection;
const int timeoutSeconds;
//==============================================================================
void closeSocket()
{
if (socketHandle >= 0)
close (socketHandle);
socketHandle = -1;
}
const MemoryBlock createRequestHeader (const String& hostName,
const int hostPort,
const String& proxyName,
const int proxyPort,
const String& hostPath,
const String& originalURL,
const String& headers,
const MemoryBlock& postData,
const bool isPost)
{
String header (isPost ? "POST " : "GET ");
if (proxyName.isEmpty())
{
header << hostPath << " HTTP/1.0\r\nHost: "
<< hostName << ':' << hostPort;
}
else
{
header << originalURL << " HTTP/1.0\r\nHost: "
<< proxyName << ':' << proxyPort;
}
header << "\r\nUser-Agent: JUCE/"
<< JUCE_MAJOR_VERSION << '.' << JUCE_MINOR_VERSION
<< "\r\nConnection: Close\r\nContent-Length: "
<< postData.getSize() << "\r\n"
<< headers << "\r\n";
MemoryBlock mb;
mb.append (header.toUTF8(), (int) strlen (header.toUTF8()));
mb.append (postData.getData(), postData.getSize());
return mb;
}
const String readResponse (const uint32 timeOutTime)
{
int bytesRead = 0, numConsecutiveLFs = 0;
MemoryBlock buffer (1024, true);
while (numConsecutiveLFs < 2 && bytesRead < 32768
&& Time::getMillisecondCounter() <= timeOutTime)
{
fd_set readbits;
FD_ZERO (&readbits);
FD_SET (socketHandle, &readbits);
struct timeval tv;
tv.tv_sec = timeoutSeconds;
tv.tv_usec = 0;
if (select (socketHandle + 1, &readbits, 0, 0, &tv) <= 0)
return String::empty; // (timeout)
buffer.ensureSize (bytesRead + 8, true);
char* const dest = (char*) buffer.getData() + bytesRead;
if (recv (socketHandle, dest, 1, 0) == -1)
return String::empty;
const char lastByte = *dest;
++bytesRead;
if (lastByte == '\n')
++numConsecutiveLFs;
else if (lastByte != '\r')
numConsecutiveLFs = 0;
}
const String header (String::fromUTF8 ((const char*) buffer.getData()));
if (header.startsWithIgnoreCase ("HTTP/"))
return header.trimEnd();
return String::empty;
}
//==============================================================================
static bool decomposeURL (const String& url,
String& host, String& path, int& port)
{
if (! url.startsWithIgnoreCase ("http://"))
return false;
const int nextSlash = url.indexOfChar (7, '/');
int nextColon = url.indexOfChar (7, ':');
if (nextColon > nextSlash && nextSlash > 0)
nextColon = -1;
if (nextColon >= 0)
{
host = url.substring (7, nextColon);
if (nextSlash >= 0)
port = url.substring (nextColon + 1, nextSlash).getIntValue();
else
port = url.substring (nextColon + 1).getIntValue();
}
else
{
port = 80;
if (nextSlash >= 0)
host = url.substring (7, nextSlash);
else
host = url.substring (7);
}
if (nextSlash >= 0)
path = url.substring (nextSlash);
else
path = "/";
return true;
}
//==============================================================================
static const String findHeaderItem (const StringArray& lines, const String& itemName)
{
for (int i = 0; i < lines.size(); ++i)
if (lines[i].startsWithIgnoreCase (itemName))
return lines[i].substring (itemName.length()).trim();
return String::empty;
}
};
//==============================================================================
void* juce_openInternetFile (const String& url,
const String& headers,
const MemoryBlock& postData,
const bool isPost,
URL::OpenStreamProgressCallback* callback,
void* callbackContext,
int timeOutMs)
{
JUCE_HTTPSocketStream* const s = new JUCE_HTTPSocketStream();
if (s->open (url, headers, postData, isPost,
callback, callbackContext, timeOutMs))
return s;
delete s;
return 0;
}
void juce_closeInternetFile (void* handle)
{
delete static_cast <JUCE_HTTPSocketStream*> (handle);
}
int juce_readFromInternetFile (void* handle, void* buffer, int bytesToRead)
{
JUCE_HTTPSocketStream* const s = (JUCE_HTTPSocketStream*) handle;
if (s != 0)
return s->read (buffer, bytesToRead);
return 0;
}
int64 juce_getInternetFileContentLength (void* handle)
{
JUCE_HTTPSocketStream* const s = (JUCE_HTTPSocketStream*) handle;
if (s != 0)
{
//xxx todo
jassertfalse;
}
return -1;
}
void juce_getInternetFileHeaders (void* handle, StringPairArray& headers)
{
JUCE_HTTPSocketStream* const s = (JUCE_HTTPSocketStream*) handle;
if (s != 0)
{
// xxx todo
jassertfalse;
}
}
int juce_seekInInternetFile (void* handle, int newPosition)
{
JUCE_HTTPSocketStream* const s = (JUCE_HTTPSocketStream*) handle;
if (s != 0)
return s->readPosition;
return 0;
}
#endif
/*
==============================================================================

This file is part of the JUCE library - "Jules' Utility Class Extensions"
Copyright 2004-10 by Raw Material Software Ltd.

------------------------------------------------------------------------------

JUCE can be redistributed and/or modified under the terms of the GNU General
Public License (Version 2), as published by the Free Software Foundation.
A copy of the license is included in the JUCE distribution, or can be found
online at www.gnu.org/licenses.

JUCE is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.

------------------------------------------------------------------------------

To release a closed-source product which uses JUCE, commercial licenses are
available: visit www.rawmaterialsoftware.com/juce for more information.

==============================================================================
*/

// (This file gets included by juce_linux_NativeCode.cpp, rather than being
// compiled on its own).
#if JUCE_INCLUDED_FILE


//==============================================================================
int SystemStats::getMACAddresses (int64* addresses, int maxNum, const bool littleEndian)
{
int numResults = 0;

const int s = socket (AF_INET, SOCK_DGRAM, 0);
if (s != -1)
{
char buf [1024];
struct ifconf ifc;
ifc.ifc_len = sizeof (buf);
ifc.ifc_buf = buf;
ioctl (s, SIOCGIFCONF, &ifc);

for (unsigned int i = 0; i < ifc.ifc_len / sizeof (struct ifreq); ++i)
{
struct ifreq ifr;
strcpy (ifr.ifr_name, ifc.ifc_req[i].ifr_name);

if (ioctl (s, SIOCGIFFLAGS, &ifr) == 0
&& (ifr.ifr_flags & IFF_LOOPBACK) == 0
&& ioctl (s, SIOCGIFHWADDR, &ifr) == 0
&& numResults < maxNum)
{
int64 a = 0;
for (int j = 6; --j >= 0;)
a = (a << 8) | (uint8) ifr.ifr_hwaddr.sa_data [littleEndian ? j : (5 - j)];

*addresses++ = a;
++numResults;
}
}

close (s);
}

return numResults;
}


bool PlatformUtilities::launchEmailWithAttachments (const String& targetEmailAddress,
const String& emailSubject,
const String& bodyText,
const StringArray& filesToAttach)
{
jassertfalse; // xxx todo

return false;
}

//==============================================================================
/** A HTTP input stream that uses sockets.
*/
class JUCE_HTTPSocketStream
{
public:
//==============================================================================
JUCE_HTTPSocketStream()
: readPosition (0),
socketHandle (-1),
levelsOfRedirection (0),
timeoutSeconds (15)
{
}

~JUCE_HTTPSocketStream()
{
closeSocket();
}

//==============================================================================
bool open (const String& url,
const String& headers,
const MemoryBlock& postData,
const bool isPost,
URL::OpenStreamProgressCallback* callback,
void* callbackContext,
int timeOutMs)
{
closeSocket();

uint32 timeOutTime = Time::getMillisecondCounter();

if (timeOutMs == 0)
timeOutTime += 60000;
else if (timeOutMs < 0)
timeOutTime = 0xffffffff;
else
timeOutTime += timeOutMs;

String hostName, hostPath;
int hostPort;

if (! decomposeURL (url, hostName, hostPath, hostPort))
return false;

const struct hostent* host = 0;
int port = 0;

String proxyName, proxyPath;
int proxyPort = 0;

String proxyURL (getenv ("http_proxy"));
if (proxyURL.startsWithIgnoreCase ("http://"))
{
if (! decomposeURL (proxyURL, proxyName, proxyPath, proxyPort))
return false;

host = gethostbyname (proxyName.toUTF8());
port = proxyPort;
}
else
{
host = gethostbyname (hostName.toUTF8());
port = hostPort;
}

if (host == 0)
return false;

struct sockaddr_in address;
zerostruct (address);
memcpy (&address.sin_addr, host->h_addr, host->h_length);
address.sin_family = host->h_addrtype;
address.sin_port = htons (port);

socketHandle = socket (host->h_addrtype, SOCK_STREAM, 0);

if (socketHandle == -1)
return false;

int receiveBufferSize = 16384;
setsockopt (socketHandle, SOL_SOCKET, SO_RCVBUF, (char*) &receiveBufferSize, sizeof (receiveBufferSize));
setsockopt (socketHandle, SOL_SOCKET, SO_KEEPALIVE, 0, 0);

#if JUCE_MAC
setsockopt (socketHandle, SOL_SOCKET, SO_NOSIGPIPE, 0, 0);
#endif

if (connect (socketHandle, (struct sockaddr*) &address, sizeof (address)) == -1)
{
closeSocket();
return false;
}

const MemoryBlock requestHeader (createRequestHeader (hostName, hostPort,
proxyName, proxyPort,
hostPath, url,
headers, postData,
isPost));
size_t totalHeaderSent = 0;

while (totalHeaderSent < requestHeader.getSize())
{
if (Time::getMillisecondCounter() > timeOutTime)
{
closeSocket();
return false;
}

const int numToSend = jmin (1024, (int) (requestHeader.getSize() - totalHeaderSent));

if (send (socketHandle,
((const char*) requestHeader.getData()) + totalHeaderSent,
numToSend, 0)
!= numToSend)
{
closeSocket();
return false;
}

totalHeaderSent += numToSend;

if (callback != 0 && ! callback (callbackContext, totalHeaderSent, requestHeader.getSize()))
{
closeSocket();
return false;
}
}

const String responseHeader (readResponse (timeOutTime));

if (responseHeader.isNotEmpty())
{
//DBG (responseHeader);

headerLines.clear();
headerLines.addLines (responseHeader);

const int statusCode = responseHeader.fromFirstOccurrenceOf (" ", false, false)
.substring (0, 3).getIntValue();

//int contentLength = findHeaderItem (lines, "Content-Length:").getIntValue();
//bool isChunked = findHeaderItem (lines, "Transfer-Encoding:").equalsIgnoreCase ("chunked");

String location (findHeaderItem (headerLines, "Location:"));

if (statusCode >= 300 && statusCode < 400
&& location.isNotEmpty())
{
if (! location.startsWithIgnoreCase ("http://"))
location = "http://" + location;

if (levelsOfRedirection++ < 3)
return open (location, headers, postData, isPost, callback, callbackContext, timeOutMs);
}
else
{
levelsOfRedirection = 0;
return true;
}
}

closeSocket();
return false;
}

//==============================================================================
int read (void* buffer, int bytesToRead)
{
fd_set readbits;
FD_ZERO (&readbits);
FD_SET (socketHandle, &readbits);

struct timeval tv;
tv.tv_sec = timeoutSeconds;
tv.tv_usec = 0;

if (select (socketHandle + 1, &readbits, 0, 0, &tv) <= 0)
return 0; // (timeout)

const int bytesRead = jmax (0, (int) recv (socketHandle, buffer, bytesToRead, MSG_WAITALL));
readPosition += bytesRead;
return bytesRead;
}

//==============================================================================
int readPosition;
StringArray headerLines;

//==============================================================================
juce_UseDebuggingNewOperator

private:
int socketHandle, levelsOfRedirection;
const int timeoutSeconds;

//==============================================================================
void closeSocket()
{
if (socketHandle >= 0)
close (socketHandle);

socketHandle = -1;
}

const MemoryBlock createRequestHeader (const String& hostName,
const int hostPort,
const String& proxyName,
const int proxyPort,
const String& hostPath,
const String& originalURL,
const String& headers,
const MemoryBlock& postData,
const bool isPost)
{
String header (isPost ? "POST " : "GET ");

if (proxyName.isEmpty())
{
header << hostPath << " HTTP/1.0\r\nHost: "
<< hostName << ':' << hostPort;
}
else
{
header << originalURL << " HTTP/1.0\r\nHost: "
<< proxyName << ':' << proxyPort;
}

header << "\r\nUser-Agent: JUCE/"
<< JUCE_MAJOR_VERSION << '.' << JUCE_MINOR_VERSION
<< "\r\nConnection: Close\r\nContent-Length: "
<< postData.getSize() << "\r\n"
<< headers << "\r\n";

MemoryBlock mb;
mb.append (header.toUTF8(), (int) strlen (header.toUTF8()));
mb.append (postData.getData(), postData.getSize());

return mb;
}

const String readResponse (const uint32 timeOutTime)
{
int bytesRead = 0, numConsecutiveLFs = 0;
MemoryBlock buffer (1024, true);

while (numConsecutiveLFs < 2 && bytesRead < 32768
&& Time::getMillisecondCounter() <= timeOutTime)
{
fd_set readbits;
FD_ZERO (&readbits);
FD_SET (socketHandle, &readbits);

struct timeval tv;
tv.tv_sec = timeoutSeconds;
tv.tv_usec = 0;

if (select (socketHandle + 1, &readbits, 0, 0, &tv) <= 0)
return String::empty; // (timeout)

buffer.ensureSize (bytesRead + 8, true);
char* const dest = (char*) buffer.getData() + bytesRead;

if (recv (socketHandle, dest, 1, 0) == -1)
return String::empty;

const char lastByte = *dest;
++bytesRead;

if (lastByte == '\n')
++numConsecutiveLFs;
else if (lastByte != '\r')
numConsecutiveLFs = 0;
}

const String header (String::fromUTF8 ((const char*) buffer.getData()));

if (header.startsWithIgnoreCase ("HTTP/"))
return header.trimEnd();

return String::empty;
}

//==============================================================================
static bool decomposeURL (const String& url,
String& host, String& path, int& port)
{
if (! url.startsWithIgnoreCase ("http://"))
return false;

const int nextSlash = url.indexOfChar (7, '/');
int nextColon = url.indexOfChar (7, ':');
if (nextColon > nextSlash && nextSlash > 0)
nextColon = -1;

if (nextColon >= 0)
{
host = url.substring (7, nextColon);

if (nextSlash >= 0)
port = url.substring (nextColon + 1, nextSlash).getIntValue();
else
port = url.substring (nextColon + 1).getIntValue();
}
else
{
port = 80;

if (nextSlash >= 0)
host = url.substring (7, nextSlash);
else
host = url.substring (7);
}

if (nextSlash >= 0)
path = url.substring (nextSlash);
else
path = "/";

return true;
}

//==============================================================================
static const String findHeaderItem (const StringArray& lines, const String& itemName)
{
for (int i = 0; i < lines.size(); ++i)
if (lines[i].startsWithIgnoreCase (itemName))
return lines[i].substring (itemName.length()).trim();

return String::empty;
}
};

//==============================================================================
void* juce_openInternetFile (const String& url,
const String& headers,
const MemoryBlock& postData,
const bool isPost,
URL::OpenStreamProgressCallback* callback,
void* callbackContext,
int timeOutMs)
{
ScopedPointer<JUCE_HTTPSocketStream> s (new JUCE_HTTPSocketStream());

if (s->open (url, headers, postData, isPost, callback, callbackContext, timeOutMs))
return s.release();

return 0;
}

void juce_closeInternetFile (void* handle)
{
delete static_cast <JUCE_HTTPSocketStream*> (handle);
}

int juce_readFromInternetFile (void* handle, void* buffer, int bytesToRead)
{
JUCE_HTTPSocketStream* const s = static_cast <JUCE_HTTPSocketStream*> (handle);

return s != 0 ? s->read (buffer, bytesToRead) : 0;
}

int64 juce_getInternetFileContentLength (void* handle)
{
JUCE_HTTPSocketStream* const s = static_cast <JUCE_HTTPSocketStream*> (handle);

if (s != 0)
{
//xxx todo
jassertfalse
}

return -1;
}

bool juce_getInternetFileHeaders (void* handle, StringPairArray& headers)
{
JUCE_HTTPSocketStream* const s = static_cast <JUCE_HTTPSocketStream*> (handle);

if (s != 0)
{
for (int i = 0; i < s->headerLines.size(); ++i)
{
const String& headersEntry = s->headerLines[i];
const String key (headersEntry.upToFirstOccurrenceOf (": ", false, false));
const String value (headersEntry.fromFirstOccurrenceOf (": ", false, false));
const String previousValue (headers [key]);
headers.set (key, previousValue.isEmpty() ? value : (previousValue + ";" + value));
}
}
}

int juce_seekInInternetFile (void* handle, int newPosition)
{
JUCE_HTTPSocketStream* const s = static_cast <JUCE_HTTPSocketStream*> (handle);

return s != 0 ? s->readPosition : 0;
}

#endif

Loading…
Cancel
Save