Browse Source

String fix. Minor additional methods for FileBasedDocument and Slider. Jucer development.

tags/2021-05-28
Julian Storer 15 years ago
parent
commit
a612dfdc2f
27 changed files with 1093 additions and 786 deletions
  1. +10
    -4
      extras/Jucer (experimental)/Builds/Linux/Makefile
  2. +6
    -0
      extras/Jucer (experimental)/Builds/MacOSX/The Jucer.xcodeproj/project.pbxproj
  3. +2
    -0
      extras/Jucer (experimental)/Builds/VisualStudio2005/The Jucer.vcproj
  4. +2
    -0
      extras/Jucer (experimental)/Builds/VisualStudio2008/The Jucer.vcproj
  5. +4
    -0
      extras/Jucer (experimental)/Jucer.jucer
  6. +98
    -156
      extras/Jucer (experimental)/Source/model/jucer_ComponentDocument.cpp
  7. +4
    -4
      extras/Jucer (experimental)/Source/model/jucer_ComponentDocument.h
  8. +392
    -0
      extras/Jucer (experimental)/Source/model/jucer_Coordinate.cpp
  9. +157
    -0
      extras/Jucer (experimental)/Source/model/jucer_Coordinate.h
  10. +1
    -1
      extras/Jucer (experimental)/Source/model/jucer_ProjectExport_Make.h
  11. +257
    -113
      extras/Jucer (experimental)/Source/ui/Component Editor/jucer_ComponentEditor.cpp
  12. +0
    -360
      extras/Jucer (experimental)/Source/utility/jucer_UtilityFunctions.cpp
  13. +91
    -111
      extras/Jucer (experimental)/Source/utility/jucer_UtilityFunctions.h
  14. +4
    -4
      extras/amalgamator/Builds/Linux/Makefile
  15. +4
    -4
      extras/audio plugin host/Builds/Linux/Makefile
  16. +4
    -4
      extras/binarybuilder/Builds/Linux/Makefile
  17. +4
    -4
      extras/example projects/Builds/Linux/Makefile
  18. +4
    -4
      extras/juce demo/Builds/Linux/Makefile
  19. +16
    -6
      juce_amalgamated.cpp
  20. +5
    -1
      juce_amalgamated.h
  21. +1
    -1
      src/core/juce_Atomic.h
  22. +1
    -1
      src/core/juce_StandardHeader.h
  23. +8
    -3
      src/gui/components/controls/juce_Slider.cpp
  24. +8
    -0
      src/gui/components/controls/juce_Slider.h
  25. +2
    -1
      src/text/juce_String.cpp
  26. +2
    -2
      src/text/juce_String.h
  27. +6
    -2
      src/utilities/juce_FileBasedDocument.cpp

+ 10
- 4
extras/Jucer (experimental)/Builds/Linux/Makefile View File

@@ -19,8 +19,8 @@ ifeq ($(CONFIG),Debug)
OUTDIR := build
CPPFLAGS := $(DEPFLAGS) -D "LINUX=1" -D "DEBUG=1" -D "_DEBUG=1" -I "/usr/include" -I "/usr/include/freetype2"
CFLAGS += $(CPPFLAGS) $(TARGET_ARCH) -g -ggdb -O0
CXXFLAGS += $(CFLAGS)
LDFLAGS += -L$(BINDIR) -L$(LIBDIR) -mwindows -L"/usr/X11R6/lib/" -L"../../../../../juce/bin" -lfreetype -lpthread -lrt -lX11 -lGL -lGLU -lXinerama -lasound
CXXFLAGS += $(CFLAGS)
LDFLAGS += -L$(BINDIR) -L$(LIBDIR) -L"/usr/X11R6/lib/" -L"../../../../../juce/bin" -lfreetype -lpthread -lrt -lX11 -lGL -lGLU -lXinerama -lasound
LDDEPS :=
RESFLAGS := -D "LINUX=1" -D "DEBUG=1" -D "_DEBUG=1" -I "/usr/include" -I "/usr/include/freetype2"
TARGET := Jucer
@@ -34,8 +34,8 @@ ifeq ($(CONFIG),Release)
OUTDIR := build
CPPFLAGS := $(DEPFLAGS) -D "LINUX=1" -D "NDEBUG=1" -I "/usr/include" -I "/usr/include/freetype2"
CFLAGS += $(CPPFLAGS) $(TARGET_ARCH) -O3
CXXFLAGS += $(CFLAGS)
LDFLAGS += -L$(BINDIR) -L$(LIBDIR) -mwindows -L"/usr/X11R6/lib/" -L"../../../../../juce/bin" -lfreetype -lpthread -lrt -lX11 -lGL -lGLU -lXinerama -lasound
CXXFLAGS += $(CFLAGS)
LDFLAGS += -L$(BINDIR) -L$(LIBDIR) -L"/usr/X11R6/lib/" -L"../../../../../juce/bin" -lfreetype -lpthread -lrt -lX11 -lGL -lGLU -lXinerama -lasound
LDDEPS :=
RESFLAGS := -D "LINUX=1" -D "NDEBUG=1" -I "/usr/include" -I "/usr/include/freetype2"
TARGET := Jucer
@@ -44,6 +44,7 @@ endif
OBJECTS := \
$(OBJDIR)/jucer_ComponentDocument.o \
$(OBJDIR)/jucer_Coordinate.o \
$(OBJDIR)/jucer_DrawableDocument.o \
$(OBJDIR)/jucer_NewFileWizard.o \
$(OBJDIR)/jucer_Project.o \
@@ -92,6 +93,11 @@ $(OBJDIR)/jucer_ComponentDocument.o: ../../Source/model/jucer_ComponentDocument.
@echo $(notdir $<)
@$(CXX) $(CXXFLAGS) -o "$@" -c "$<"
$(OBJDIR)/jucer_Coordinate.o: ../../Source/model/jucer_Coordinate.cpp
-@mkdir -p $(OBJDIR)
@echo $(notdir $<)
@$(CXX) $(CXXFLAGS) -o "$@" -c "$<"
$(OBJDIR)/jucer_DrawableDocument.o: ../../Source/model/jucer_DrawableDocument.cpp
-@mkdir -p $(OBJDIR)
@echo $(notdir $<)


+ 6
- 0
extras/Jucer (experimental)/Builds/MacOSX/The Jucer.xcodeproj/project.pbxproj View File

@@ -18,6 +18,7 @@
93C9F3F27602A33DDC9C2250 = { isa = PBXBuildFile; fileRef = 2767E1D082874D301D5D5F43; };
2E6836738CE7EB452FDC7E9A = { isa = PBXBuildFile; fileRef = D9FB1A5365FEEB854A0FF7BF; };
CD4226951C3F7FE19CF8A7CE = { isa = PBXBuildFile; fileRef = 2D6D6985B452EA0B67A18914; };
1DF9688E29753A0459E6C32A = { isa = PBXBuildFile; fileRef = 45C80436FD5A8438D0E6BE17; };
1174D3512AF8207950094C56 = { isa = PBXBuildFile; fileRef = FF625CB50FB5C3536BA40604; };
087CCE9E7146F1EC4F241254 = { isa = PBXBuildFile; fileRef = DA142548FCADFAC50648ED3C; };
E9935BFB0EFA8CCCD41DC08E = { isa = PBXBuildFile; fileRef = D47A40CB3CF6AAE14B3C7796; };
@@ -62,6 +63,8 @@
E18C99BDD4EF3DFD767F3770 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = jucer_TextButton.h; path = "../../Source/model/Component Types/jucer_TextButton.h"; sourceTree = SOURCE_ROOT; };
2D6D6985B452EA0B67A18914 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = jucer_ComponentDocument.cpp; path = ../../Source/model/jucer_ComponentDocument.cpp; sourceTree = SOURCE_ROOT; };
E6CC3A04349F6B227FDAB26F = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = jucer_ComponentDocument.h; path = ../../Source/model/jucer_ComponentDocument.h; sourceTree = SOURCE_ROOT; };
45C80436FD5A8438D0E6BE17 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = jucer_Coordinate.cpp; path = ../../Source/model/jucer_Coordinate.cpp; sourceTree = SOURCE_ROOT; };
420E4189E7DE25E9D0D8E5B8 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = jucer_Coordinate.h; path = ../../Source/model/jucer_Coordinate.h; sourceTree = SOURCE_ROOT; };
FF625CB50FB5C3536BA40604 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = jucer_DrawableDocument.cpp; path = ../../Source/model/jucer_DrawableDocument.cpp; sourceTree = SOURCE_ROOT; };
A490098DA6400B3881F336D0 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = jucer_DrawableDocument.h; path = ../../Source/model/jucer_DrawableDocument.h; sourceTree = SOURCE_ROOT; };
DA142548FCADFAC50648ED3C = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = jucer_NewFileWizard.cpp; path = ../../Source/model/jucer_NewFileWizard.cpp; sourceTree = SOURCE_ROOT; };
@@ -144,6 +147,8 @@
D3D6EC2C17524688F2E803EB,
2D6D6985B452EA0B67A18914,
E6CC3A04349F6B227FDAB26F,
45C80436FD5A8438D0E6BE17,
420E4189E7DE25E9D0D8E5B8,
FF625CB50FB5C3536BA40604,
A490098DA6400B3881F336D0,
DA142548FCADFAC50648ED3C,
@@ -319,6 +324,7 @@
87CCE4CB1FAB40B6F21DEACE = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; };
5362E03ADF975A126C1F2F7B = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = (
CD4226951C3F7FE19CF8A7CE,
1DF9688E29753A0459E6C32A,
1174D3512AF8207950094C56,
087CCE9E7146F1EC4F241254,
E9935BFB0EFA8CCCD41DC08E,


+ 2
- 0
extras/Jucer (experimental)/Builds/VisualStudio2005/The Jucer.vcproj View File

@@ -139,6 +139,8 @@
</Filter>
<File RelativePath="..\..\Source\model\jucer_ComponentDocument.cpp"/>
<File RelativePath="..\..\Source\model\jucer_ComponentDocument.h"/>
<File RelativePath="..\..\Source\model\jucer_Coordinate.cpp"/>
<File RelativePath="..\..\Source\model\jucer_Coordinate.h"/>
<File RelativePath="..\..\Source\model\jucer_DrawableDocument.cpp"/>
<File RelativePath="..\..\Source\model\jucer_DrawableDocument.h"/>
<File RelativePath="..\..\Source\model\jucer_NewFileWizard.cpp"/>


+ 2
- 0
extras/Jucer (experimental)/Builds/VisualStudio2008/The Jucer.vcproj View File

@@ -139,6 +139,8 @@
</Filter>
<File RelativePath="..\..\Source\model\jucer_ComponentDocument.cpp"/>
<File RelativePath="..\..\Source\model\jucer_ComponentDocument.h"/>
<File RelativePath="..\..\Source\model\jucer_Coordinate.cpp"/>
<File RelativePath="..\..\Source\model\jucer_Coordinate.h"/>
<File RelativePath="..\..\Source\model\jucer_DrawableDocument.cpp"/>
<File RelativePath="..\..\Source\model\jucer_DrawableDocument.h"/>
<File RelativePath="..\..\Source\model\jucer_NewFileWizard.cpp"/>


+ 4
- 0
extras/Jucer (experimental)/Jucer.jucer View File

@@ -37,6 +37,10 @@
resource="0" file="Source/model/jucer_ComponentDocument.cpp"/>
<FILE id="u5n6JTb4z" name="jucer_ComponentDocument.h" compile="0" resource="0"
file="Source/model/jucer_ComponentDocument.h"/>
<FILE id="lxuyJGZcw" name="jucer_Coordinate.cpp" compile="1" resource="0"
file="Source/model/jucer_Coordinate.cpp"/>
<FILE id="CyKbwNlwe" name="jucer_Coordinate.h" compile="0" resource="0"
file="Source/model/jucer_Coordinate.h"/>
<FILE id="XxIww5OtT" name="jucer_DrawableDocument.cpp" compile="1"
resource="0" file="Source/model/jucer_DrawableDocument.cpp"/>
<FILE id="lbB698APl" name="jucer_DrawableDocument.h" compile="0" resource="0"


+ 98
- 156
extras/Jucer (experimental)/Source/model/jucer_ComponentDocument.cpp View File

@@ -27,6 +27,7 @@
#include "Component Types/jucer_TextButton.h"
#include "Component Types/jucer_ToggleButton.h"
//==============================================================================
static const char* const componentDocumentTag = "COMPONENT";
static const char* const componentGroupTag = "COMPONENTS";
@@ -42,7 +43,8 @@ static const char* const metadataTagEnd = "JUCER_" "COMPONENT_METADATA_E
//==============================================================================
class ComponentBoundsEditor : public PropertyComponent,
public ButtonListener
public ButtonListener,
public Value::Listener
{
public:
enum Type
@@ -68,15 +70,21 @@ public:
addAndMakeVisible (anchorButton1 = new TextButton (String::empty));
anchorButton1->setConnectedEdges (Button::ConnectedOnLeft | Button::ConnectedOnTop | Button::ConnectedOnRight | Button::ConnectedOnBottom);
anchorButton1->setTriggeredOnMouseDown (true);
anchorButton1->addButtonListener (this);
addAndMakeVisible (anchorButton2 = new TextButton (String::empty));
anchorButton2->setConnectedEdges (Button::ConnectedOnLeft | Button::ConnectedOnTop | Button::ConnectedOnRight | Button::ConnectedOnBottom);
anchorButton2->setTriggeredOnMouseDown (true);
anchorButton2->addButtonListener (this);
boundsValue.addListener (this);
valueChanged (boundsValue);
}
~ComponentBoundsEditor()
{
boundsValue.removeListener (this);
deleteAllChildren();
}
@@ -87,8 +95,16 @@ public:
label->setBounds (r.getX(), r.getY(), r.getWidth() / 2, r.getHeight() / 2);
proportionButton->setBounds (r.getX() + r.getWidth() / 2, r.getY(),
r.getWidth() / 2, r.getHeight() / 2);
anchorButton1->setBounds (r.getX(), r.getY() + r.getHeight() / 2, r.getWidth() / 2, r.getHeight() / 2);
anchorButton2->setBounds (r.getX() + r.getWidth() / 2, r.getY() + r.getHeight() / 2, r.getWidth() / 2, r.getHeight() / 2);
if (anchorButton2->isVisible())
{
anchorButton1->setBounds (r.getX(), r.getY() + r.getHeight() / 2, r.getWidth() / 2, r.getHeight() / 2);
anchorButton2->setBounds (r.getX() + r.getWidth() / 2, r.getY() + r.getHeight() / 2, r.getWidth() / 2, r.getHeight() / 2);
}
else
{
anchorButton1->setBounds (r.getX(), r.getY() + r.getHeight() / 2, r.getWidth(), r.getHeight() / 2);
}
}
void refresh()
@@ -97,24 +113,49 @@ public:
void buttonClicked (Button* button)
{
RectangleCoordinates r (boundsValue.toString());
Coordinate& coord = getCoord (r);
ScopedPointer<Coordinate::MarkerResolver> markers (document.createMarkerResolver (compState));
if (button == proportionButton)
{
RectangleCoordinates r (boundsValue.toString());
Coordinate& coord = getCoord (r);
ScopedPointer<Coordinate::MarkerResolver> markers (document.createMarkerResolver (compState));
coord.toggleProportionality (*markers);
boundsValue = r.toString();
}
else if (button == anchorButton1)
{
const String marker (pickMarker (anchorButton1, coord.getAnchor1()));
if (marker.isNotEmpty())
{
coord.changeAnchor1 (marker, *markers);
boundsValue = r.toString();
}
}
else if (button == anchorButton2)
{
const String marker (pickMarker (anchorButton2, coord.getAnchor2()));
if (marker.isNotEmpty())
{
coord.changeAnchor2 (marker, *markers);
boundsValue = r.toString();
}
}
}
void valueChanged (Value&)
{
RectangleCoordinates r (boundsValue.toString());
Coordinate& coord = getCoord (r);
anchorButton1->setButtonText (coord.getAnchor1());
anchorButton2->setVisible (coord.isProportional());
anchorButton2->setButtonText (coord.getAnchor2());
resized();
}
//==============================================================================
class BoundsCoordValueSource : public Value::ValueSource,
public Value::Listener
@@ -186,6 +227,22 @@ public:
return r.left;
}
const String pickMarker (Component* button, const String& currentMarker)
{
const StringArray markers (document.getComponentMarkers (type == left || type == right));
PopupMenu m;
for (int i = 0; i < markers.size(); ++i)
m.addItem (i + 1, markers[i], true, currentMarker == markers[i]);
const int r = m.showAt (button);
if (r > 0)
return markers [r - 1];
return String::empty;
}
private:
ComponentDocument& document;
Type type;
@@ -588,11 +645,44 @@ const RectangleCoordinates ComponentDocument::getCoordsFor (const ValueTree& sta
return RectangleCoordinates (state [compBoundsProperty]);
}
bool ComponentDocument::setCoordsFor (ValueTree& state, const RectangleCoordinates& pr)
{
const String newBoundsString (pr.toString());
if (state[compBoundsProperty] == newBoundsString)
return false;
state.setProperty (compBoundsProperty, newBoundsString, getUndoManager());
return true;
}
Coordinate::MarkerResolver* ComponentDocument::createMarkerResolver (const ValueTree& state)
{
return new ComponentMarkerResolver (*this, state, getCanvasWidth().getValue(), getCanvasHeight().getValue());
}
const StringArray ComponentDocument::getComponentMarkers (bool horizontal) const
{
StringArray s;
if (horizontal)
{
s.add (Coordinate::parentLeftMarkerName);
s.add (Coordinate::parentRightMarkerName);
s.add ("left");
s.add ("right");
}
else
{
s.add (Coordinate::parentTopMarkerName);
s.add (Coordinate::parentBottomMarkerName);
s.add ("top");
s.add ("bottom");
}
return s;
}
void ComponentDocument::updateComponent (Component* comp)
{
const ValueTree v (getComponentState (comp));
@@ -675,151 +765,3 @@ UndoManager* ComponentDocument::getUndoManager()
{
return &undoManager;
}
//==============================================================================
class ComponentDocument::DragHandler
{
public:
DragHandler (ComponentDocument& document_,
const Array<Component*>& items,
const MouseEvent& e,
const ResizableBorderComponent::Zone& zone_,
Component* parentForOverlays)
: document (document_),
zone (zone_)
{
for (int i = 0; i < items.size(); ++i)
{
Component* comp = items.getUnchecked(i);
jassert (comp != 0);
const ValueTree v (document.getComponentState (comp));
draggedComponents.add (v);
Rectangle<int> pos;
{
RectangleCoordinates relativePos (v [compBoundsProperty].toString());
ScopedPointer<Coordinate::MarkerResolver> markers (document.createMarkerResolver (v));
pos = relativePos.resolve (*markers);
originalPositions.add (pos);
}
const Rectangle<float> floatPos ((float) pos.getX(), (float) pos.getY(),
(float) pos.getWidth(), (float) pos.getHeight());
if (zone.isDraggingWholeObject() || zone.isDraggingLeftEdge())
verticalSnapPositions.add (floatPos.getX());
if (zone.isDraggingWholeObject() || zone.isDraggingLeftEdge() || zone.isDraggingRightEdge())
verticalSnapPositions.add (floatPos.getCentreX());
if (zone.isDraggingWholeObject() || zone.isDraggingRightEdge())
verticalSnapPositions.add (floatPos.getRight());
if (zone.isDraggingWholeObject() || zone.isDraggingTopEdge())
horizontalSnapPositions.add (floatPos.getY());
if (zone.isDraggingWholeObject() || zone.isDraggingTopEdge() || zone.isDraggingBottomEdge())
verticalSnapPositions.add (floatPos.getCentreY());
if (zone.isDraggingWholeObject() || zone.isDraggingBottomEdge())
horizontalSnapPositions.add (floatPos.getBottom());
}
document.beginNewTransaction();
}
~DragHandler()
{
document.beginNewTransaction();
}
void drag (const MouseEvent& e)
{
document.getUndoManager()->undoCurrentTransactionOnly();
for (int n = 50;;)
{
// Need to repeatedly apply the new positions until they all settle down, in case some of
// the coords are relative to each other..
bool anyUpdated = false;
for (int i = 0; i < draggedComponents.size(); ++i)
if (dragItem (draggedComponents.getReference(i), e.getOffsetFromDragStart(), originalPositions.getReference(i)))
anyUpdated = true;
if (! anyUpdated)
break;
if (--n == 0)
{
jassertfalse;
break;
}
}
}
bool dragItem (ValueTree& v, const Point<int>& distance, const Rectangle<int>& originalPos)
{
const Rectangle<int> newBounds (zone.resizeRectangleBy (originalPos, distance));
RectangleCoordinates pr (v [compBoundsProperty].toString());
ScopedPointer<Coordinate::MarkerResolver> markers (document.createMarkerResolver (v));
pr.moveToAbsolute (newBounds, *markers);
const String newBoundsString (pr.toString());
if (v[compBoundsProperty] == newBoundsString)
return false;
v.setProperty (compBoundsProperty, newBoundsString, document.getUndoManager());
return true;
}
const Array<float> getVerticalSnapPositions (const Point<int>& distance) const
{
Array<float> p (verticalSnapPositions);
for (int i = p.size(); --i >= 0;)
p.set (i, p.getUnchecked(i) + distance.getX());
return p;
}
const Array<float> getHorizontalSnapPositions (const Point<int>& distance) const
{
Array<float> p (horizontalSnapPositions);
for (int i = p.size(); --i >= 0;)
p.set (i, p.getUnchecked(i) + distance.getY());
return p;
}
private:
ComponentDocument& document;
Array <ValueTree> draggedComponents;
Array <Rectangle<int> > originalPositions;
Array <float> verticalSnapPositions, horizontalSnapPositions;
const ResizableBorderComponent::Zone zone;
};
void ComponentDocument::beginDrag (const Array<Component*>& items, const MouseEvent& e,
Component* parentForOverlays, const ResizableBorderComponent::Zone& zone)
{
dragger = new DragHandler (*this, items, e, zone, parentForOverlays);
}
void ComponentDocument::continueDrag (const MouseEvent& e)
{
if (dragger != 0)
dragger->drag (e);
}
void ComponentDocument::endDrag (const MouseEvent& e)
{
if (dragger != 0)
{
dragger->drag (e);
dragger = 0;
}
}

+ 4
- 4
extras/Jucer (experimental)/Source/model/jucer_ComponentDocument.h View File

@@ -28,6 +28,7 @@
#include "../jucer_Headers.h"
#include "jucer_Project.h"
#include "jucer_Coordinate.h"
//==============================================================================
@@ -66,7 +67,9 @@ public:
void getComponentProperties (Array <PropertyComponent*>& props, Component* comp);
bool isStateForComponent (const ValueTree& storedState, Component* comp) const;
Coordinate::MarkerResolver* createMarkerResolver (const ValueTree& state);
const RectangleCoordinates getCoordsFor (const ValueTree& state) const;
const StringArray getComponentMarkers (bool horizontal) const;
const RectangleCoordinates getCoordsFor (const ValueTree& componentState) const;
bool setCoordsFor (ValueTree& componentState, const RectangleCoordinates& newSize);
void addNewComponentMenuItems (PopupMenu& menu) const;
void performNewComponentMenuItem (int menuResultCode);
@@ -93,9 +96,6 @@ private:
UndoManager undoManager;
bool changedSinceSaved;
class DragHandler;
ScopedPointer <DragHandler> dragger;
void checkRootObject();
ValueTree getComponentGroup() const;
Value getRootValue (const var::identifier& name) { return root.getPropertyAsValue (name, getUndoManager()); }


+ 392
- 0
extras/Jucer (experimental)/Source/model/jucer_Coordinate.cpp View File

@@ -0,0 +1,392 @@
/*
==============================================================================
This file is part of the JUCE library - "Jules' Utility Class Extensions"
Copyright 2004-9 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.
==============================================================================
*/
#include "jucer_Coordinate.h"
//==============================================================================
const char* Coordinate::parentLeftMarkerName = "parent.left";
const char* Coordinate::parentRightMarkerName = "parent.right";
const char* Coordinate::parentTopMarkerName = "parent.top";
const char* Coordinate::parentBottomMarkerName = "parent.bottom";
Coordinate::Coordinate (bool isHorizontal_)
: value (0), isProportion (false), isHorizontal (isHorizontal_)
{
}
Coordinate::Coordinate (double absoluteDistanceFromOrigin, bool isHorizontal_)
: value (absoluteDistanceFromOrigin), isProportion (false), isHorizontal (isHorizontal_)
{
}
Coordinate::Coordinate (double absoluteDistance, const String& source, bool isHorizontal_)
: anchor1 (source), value (absoluteDistance), isProportion (false), isHorizontal (isHorizontal_)
{
}
Coordinate::Coordinate (double relativeProportion, const String& pos1, const String& pos2, bool isHorizontal_)
: anchor1 (pos1), anchor2 (pos2), value (relativeProportion), isProportion (true), isHorizontal (isHorizontal_)
{
}
Coordinate::~Coordinate()
{
}
const Coordinate Coordinate::getAnchorPoint1() const
{
return Coordinate (0.0, anchor1, isHorizontal);
}
const Coordinate Coordinate::getAnchorPoint2() const
{
return Coordinate (0.0, anchor2, isHorizontal);
}
bool Coordinate::isOrigin (const String& name)
{
return name.isEmpty() || name == parentLeftMarkerName || name == parentTopMarkerName;
}
const String Coordinate::getOriginMarkerName() const
{
return isHorizontal ? parentLeftMarkerName : parentTopMarkerName;
}
const String Coordinate::getExtentMarkerName() const
{
return isHorizontal ? parentRightMarkerName : parentBottomMarkerName;
}
const String Coordinate::checkName (const String& name) const
{
return name.isEmpty() ? getOriginMarkerName() : name;
}
double Coordinate::getPosition (const String& name, MarkerResolver& markerResolver, int recursionCounter) const
{
if (isOrigin (name))
return 0.0;
return markerResolver.findMarker (name, isHorizontal)
.resolve (markerResolver, recursionCounter + 1);
}
struct RecursivePositionException
{
};
double Coordinate::resolve (MarkerResolver& markerResolver, int recursionCounter) const
{
if (recursionCounter > 100)
{
jassertfalse
throw RecursivePositionException();
}
const double pos1 = getPosition (anchor1, markerResolver, recursionCounter);
return isProportion ? pos1 + (getPosition (anchor2, markerResolver, recursionCounter) - pos1) * value
: pos1 + value;
}
double Coordinate::resolve (MarkerResolver& markerResolver) const
{
try
{
return resolve (markerResolver, 0);
}
catch (RecursivePositionException&)
{}
return 0.0;
}
void Coordinate::moveToAbsolute (double newPos, MarkerResolver& markerResolver)
{
try
{
const double pos1 = getPosition (anchor1, markerResolver, 0);
if (isProportion)
{
const double size = getPosition (anchor2, markerResolver, 0) - pos1;
if (size != 0)
value = (newPos - pos1) / size;
}
else
{
value = newPos - pos1;
}
}
catch (RecursivePositionException&)
{}
}
bool Coordinate::isRecursive (MarkerResolver& markerResolver) const
{
try
{
resolve (markerResolver, 0);
}
catch (RecursivePositionException&)
{
return true;
}
return false;
}
void Coordinate::skipWhitespace (const String& s, int& i)
{
while (CharacterFunctions::isWhitespace (s[i]))
++i;
}
const String Coordinate::readMarkerName (const String& s, int& i)
{
skipWhitespace (s, i);
if (CharacterFunctions::isLetter (s[i]) || s[i] == '_')
{
int start = i;
while (CharacterFunctions::isLetterOrDigit (s[i]) || s[i] == '_' || s[i] == '.')
++i;
return s.substring (start, i);
}
return String::empty;
}
double Coordinate::readNumber (const String& s, int& i)
{
skipWhitespace (s, i);
int start = i;
if (CharacterFunctions::isDigit (s[i]) || s[i] == '.' || s[i] == '-')
++i;
while (CharacterFunctions::isDigit (s[i]) || s[i] == '.')
++i;
if ((s[i] == 'e' || s[i] == 'E')
&& (CharacterFunctions::isDigit (s[i + 1])
|| s[i + 1] == '-'
|| s[i + 1] == '+'))
{
i += 2;
while (CharacterFunctions::isDigit (s[i]))
++i;
}
const double value = s.substring (start, i).getDoubleValue();
while (CharacterFunctions::isWhitespace (s[i]) || s[i] == ',')
++i;
return value;
}
Coordinate::Coordinate (const String& s, bool isHorizontal_)
: value (0), isProportion (false), isHorizontal (isHorizontal_)
{
int i = 0;
anchor1 = readMarkerName (s, i);
if (anchor1.isNotEmpty())
{
skipWhitespace (s, i);
if (s[i] == '+')
value = readNumber (s, ++i);
else if (s[i] == '-')
value = -readNumber (s, ++i);
}
else
{
value = readNumber (s, i);
skipWhitespace (s, i);
if (s[i] == '%')
{
isProportion = true;
value /= 100.0;
skipWhitespace (s, ++i);
if (s[i] == '*')
{
anchor1 = readMarkerName (s, ++i);
skipWhitespace (s, i);
if (s[i] == '-' && s[i + 1] == '>')
{
i += 2;
anchor2 = readMarkerName (s, i);
}
else
{
anchor2 = anchor1;
anchor1 = getOriginMarkerName();
}
}
else
{
anchor1 = getOriginMarkerName();
anchor2 = getExtentMarkerName();
}
}
}
}
static const String limitedAccuracyString (const double n)
{
return String (n, 3).trimCharactersAtEnd ("0").trimCharactersAtEnd (".");
}
const String Coordinate::toString() const
{
if (isProportion)
{
const String percent (limitedAccuracyString (value * 100.0));
if (isOrigin (anchor1))
{
if (anchor2 == parentRightMarkerName || anchor2 == parentBottomMarkerName)
return percent + "%";
else
return percent + "% * " + checkName (anchor2);
}
else
return percent + "% * " + checkName (anchor1) + " -> " + checkName (anchor2);
}
else
{
if (isOrigin (anchor1))
return limitedAccuracyString (value);
else if (value > 0)
return checkName (anchor1) + " + " + limitedAccuracyString (value);
else if (value < 0)
return checkName (anchor1) + " - " + limitedAccuracyString (-value);
else
return checkName (anchor1);
}
}
const double Coordinate::getEditableValue() const
{
return isProportion ? value * 100.0 : value;
}
void Coordinate::setEditableValue (const double newValue)
{
value = isProportion ? newValue / 100.0 : newValue;
}
void Coordinate::toggleProportionality (MarkerResolver& markerResolver)
{
const double oldValue = resolve (markerResolver);
isProportion = ! isProportion;
anchor1 = getOriginMarkerName();
anchor2 = getExtentMarkerName();
moveToAbsolute (oldValue, markerResolver);
}
void Coordinate::changeAnchor1 (const String& newMarkerName, MarkerResolver& markerResolver)
{
const double oldValue = resolve (markerResolver);
anchor1 = newMarkerName;
moveToAbsolute (oldValue, markerResolver);
}
void Coordinate::changeAnchor2 (const String& newMarkerName, MarkerResolver& markerResolver)
{
const double oldValue = resolve (markerResolver);
anchor2 = newMarkerName;
moveToAbsolute (oldValue, markerResolver);
}
//==============================================================================
RectangleCoordinates::RectangleCoordinates()
: left (true), right (true), top (false), bottom (false)
{
}
RectangleCoordinates::RectangleCoordinates (const Rectangle<int>& rect)
: left (rect.getX(), true),
right (rect.getWidth(), "left", true),
top (rect.getY(), false),
bottom (rect.getHeight(), "top", false)
{
}
RectangleCoordinates::RectangleCoordinates (const String& stringVersion)
: left (true), right (true), top (false), bottom (false)
{
StringArray tokens;
tokens.addTokens (stringVersion, ",", String::empty);
left = Coordinate (tokens [0], true);
top = Coordinate (tokens [1], false);
right = Coordinate (tokens [2], true);
bottom = Coordinate (tokens [3], false);
}
bool RectangleCoordinates::isRecursive (Coordinate::MarkerResolver& markerResolver) const
{
return left.isRecursive (markerResolver) || right.isRecursive (markerResolver)
|| top.isRecursive (markerResolver) || bottom.isRecursive (markerResolver);
}
const Rectangle<int> RectangleCoordinates::resolve (Coordinate::MarkerResolver& markerResolver) const
{
const int l = roundToInt (left.resolve (markerResolver));
const int r = roundToInt (right.resolve (markerResolver));
const int t = roundToInt (top.resolve (markerResolver));
const int b = roundToInt (bottom.resolve (markerResolver));
return Rectangle<int> (l, t, r - l, b - t);
}
void RectangleCoordinates::moveToAbsolute (const Rectangle<int>& newPos, Coordinate::MarkerResolver& markerResolver)
{
left.moveToAbsolute (newPos.getX(), markerResolver);
right.moveToAbsolute (newPos.getRight(), markerResolver);
top.moveToAbsolute (newPos.getY(), markerResolver);
bottom.moveToAbsolute (newPos.getBottom(), markerResolver);
}
const String RectangleCoordinates::toString() const
{
return left.toString() + ", " + top.toString() + ", " + right.toString() + ", " + bottom.toString();
}

+ 157
- 0
extras/Jucer (experimental)/Source/model/jucer_Coordinate.h View File

@@ -0,0 +1,157 @@
/*
==============================================================================
This file is part of the JUCE library - "Jules' Utility Class Extensions"
Copyright 2004-9 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.
==============================================================================
*/
#ifndef __JUCER_COORDINATE_H_EF56ACFA__
#define __JUCER_COORDINATE_H_EF56ACFA__
#include "../jucer_Headers.h"
//==============================================================================
/**
Holds a co-ordinate along the x or y axis, expressed either as an absolute
position, or relative to other named marker positions.
*/
class Coordinate
{
public:
//==============================================================================
/** Creates a zero coordinate. */
explicit Coordinate (bool isHorizontal);
/** Recreates a coordinate from its stringified version. */
Coordinate (const String& stringVersion, bool isHorizontal);
/** Creates an absolute position from the parent origin. */
Coordinate (double absoluteDistanceFromOrigin, bool isHorizontal);
/** Creates an absolute position relative to a named marker. */
Coordinate (double absolutePosition, const String& relativeToMarker, bool isHorizontal);
/** Creates a relative position between two named markers. */
Coordinate (double relativePosition, const String& marker1, const String& marker2, bool isHorizontal);
/** Destructor. */
~Coordinate();
//==============================================================================
/**
Provides an interface for looking up the position of a named marker.
*/
class MarkerResolver
{
public:
virtual ~MarkerResolver() {}
virtual const Coordinate findMarker (const String& name, bool isHorizontal) = 0;
};
/** Calculates the absolute position of this co-ordinate. */
double resolve (MarkerResolver& markerResolver) const;
/** Returns true if this co-ordinate is expressed in terms of markers that form a recursive loop. */
bool isRecursive (MarkerResolver& markerResolver) const;
/** Changes the value of this marker to make it resolve to the specified position. */
void moveToAbsolute (double newPos, MarkerResolver& markerResolver);
const Coordinate getAnchorPoint1() const;
const Coordinate getAnchorPoint2() const;
const double getEditableValue() const;
void setEditableValue (const double newValue);
bool isProportional() const throw() { return isProportion; }
void toggleProportionality (MarkerResolver& markerResolver);
const String getAnchor1() const { return checkName (anchor1); }
void changeAnchor1 (const String& newMarkerName, MarkerResolver& markerResolver);
const String getAnchor2() const { return checkName (anchor2); }
void changeAnchor2 (const String& newMarkerName, MarkerResolver& markerResolver);
//==============================================================================
/*
Position string formats:
123 = absolute pixels from parent origin
marker
marker + 123
marker - 123
50% = percentage between parent origin and parent extent
50% * marker = percentage between parent origin and marker
50% * marker1 -> marker2 = percentage between two markers
standard marker names:
"origin" = parent origin
"size" = parent right or bottom
"top", "left", "bottom", "right" = refer to the component's own left, right, top and bottom.
*/
const String toString() const;
//==============================================================================
static const char* parentLeftMarkerName;
static const char* parentRightMarkerName;
static const char* parentTopMarkerName;
static const char* parentBottomMarkerName;
private:
//==============================================================================
String anchor1, anchor2;
double value;
bool isProportion, isHorizontal;
double resolve (MarkerResolver& markerResolver, int recursionCounter) const;
double getPosition (const String& name, MarkerResolver& markerResolver, int recursionCounter) const;
const String checkName (const String& name) const;
const String getOriginMarkerName() const;
const String getExtentMarkerName() const;
static bool isOrigin (const String& name);
static void skipWhitespace (const String& s, int& i);
static const String readMarkerName (const String& s, int& i);
static double readNumber (const String& s, int& i);
};
//==============================================================================
/**
Describes a rectangle as a set of Coordinate values.
*/
class RectangleCoordinates
{
public:
//==============================================================================
RectangleCoordinates();
explicit RectangleCoordinates (const Rectangle<int>& rect);
explicit RectangleCoordinates (const String& stringVersion);
//==============================================================================
const Rectangle<int> resolve (Coordinate::MarkerResolver& markerResolver) const;
bool isRecursive (Coordinate::MarkerResolver& markerResolver) const;
void moveToAbsolute (const Rectangle<int>& newPos, Coordinate::MarkerResolver& markerResolver);
const String toString() const;
Coordinate left, right, top, bottom;
};
#endif // __JUCER_COORDINATE_H_EF56ACFA__

+ 1
- 1
extras/Jucer (experimental)/Source/model/jucer_ProjectExport_Make.h View File

@@ -164,7 +164,7 @@ private:
void writeLinkerFlags (OutputStream& out, const Project::BuildConfiguration& config)
{
out << " LDFLAGS += -L$(BINDIR) -L$(LIBDIR) -mwindows";
out << " LDFLAGS += -L$(BINDIR) -L$(LIBDIR)";
{
Array<RelativePath> libraryPaths;


+ 257
- 113
extras/Jucer (experimental)/Source/ui/Component Editor/jucer_ComponentEditor.cpp View File

@@ -159,112 +159,6 @@ private:
Rectangle<int> textArea;
};
//==============================================================================
static const double tickSizes[] = { 1.0, 2.0, 5.0,
10.0, 20.0, 50.0,
100.0, 200.0, 500.0, 1000.0 };
class TickIterator
{
public:
TickIterator (const double startValue_, const double endValue_, const double valuePerPixel_,
int minPixelsPerTick, int minWidthForLabels)
: startValue (startValue_),
endValue (endValue_),
valuePerPixel (valuePerPixel_)
{
tickLevelIndex = findLevelIndexForValue (valuePerPixel * minPixelsPerTick);
labelLevelIndex = findLevelIndexForValue (valuePerPixel * minWidthForLabels);
tickPosition = pixelsToValue (-minWidthForLabels);
tickPosition = snapValueDown (tickPosition, tickLevelIndex);
}
bool getNextTick (float& pixelX, float& tickLength, String& label)
{
const double tickUnits = tickSizes [tickLevelIndex];
tickPosition += tickUnits;
const int totalLevels = sizeof (tickSizes) / sizeof (*tickSizes);
int highestIndex = tickLevelIndex;
while (++highestIndex < totalLevels)
{
const double ticksAtThisLevel = tickPosition / tickSizes [highestIndex];
if (fabs (ticksAtThisLevel - floor (ticksAtThisLevel + 0.5)) > 0.000001)
break;
}
--highestIndex;
if (highestIndex >= labelLevelIndex)
label = getDescriptionOfValue (tickPosition, labelLevelIndex);
else
label = String::empty;
tickLength = (highestIndex + 1 - tickLevelIndex) / (float) (totalLevels + 1 - tickLevelIndex);
pixelX = valueToPixels (tickPosition);
return tickPosition < endValue;
}
private:
double tickPosition;
int tickLevelIndex, labelLevelIndex;
const double startValue, endValue, valuePerPixel;
int findLevelIndexForValue (const double value) const
{
int i;
for (i = 0; i < sizeof (tickSizes) / sizeof (*tickSizes); ++i)
if (tickSizes [i] >= value)
break;
return i;
}
double pixelsToValue (int pixels) const
{
return startValue + pixels * valuePerPixel;
}
float valueToPixels (double value) const
{
return (float) ((value - startValue) / valuePerPixel);
}
static double snapValueToNearest (const double t, const int valueLevelIndex)
{
const double unitsPerInterval = tickSizes [valueLevelIndex];
return unitsPerInterval * floor (t / unitsPerInterval + 0.5);
}
static double snapValueDown (const double t, const int valueLevelIndex)
{
const double unitsPerInterval = tickSizes [valueLevelIndex];
return unitsPerInterval * floor (t / unitsPerInterval);
}
static inline int roundDoubleToInt (const double value)
{
union { int asInt[2]; double asDouble; } n;
n.asDouble = value + 6755399441055744.0;
#if TARGET_RT_BIG_ENDIAN
return n.asInt [1];
#else
return n.asInt [0];
#endif
}
static const String getDescriptionOfValue (const double value, const int valueLevelIndex)
{
return String (roundToInt (value));
}
};
//==============================================================================
class ComponentEditor::Canvas : public Component,
public ValueTree::Listener,
@@ -287,6 +181,7 @@ public:
~Canvas()
{
dragger = 0;
getDocument().getRoot().removeListener (this);
componentHolder->deleteAllChildren();
deleteAllChildren();
@@ -508,10 +403,260 @@ public:
void showSizeGuides() { overlay->showSizeGuides(); }
void hideSizeGuides() { overlay->hideSizeGuides(); }
//==============================================================================
class DragOperation
{
public:
DragOperation (Canvas& canvas_,
const Array<Component*>& items,
const MouseEvent& e,
const ResizableBorderComponent::Zone& zone_)
: canvas (canvas_),
zone (zone_)
{
for (int i = 0; i < items.size(); ++i)
{
Component* comp = items.getUnchecked(i);
jassert (comp != 0);
const ValueTree v (getDocument().getComponentState (comp));
draggedComponents.add (v);
Rectangle<int> pos;
{
RectangleCoordinates relativePos (getDocument().getCoordsFor (v));
ScopedPointer<Coordinate::MarkerResolver> markers (getDocument().createMarkerResolver (v));
pos = relativePos.resolve (*markers);
originalPositions.add (pos);
}
const Rectangle<float> floatPos ((float) pos.getX(), (float) pos.getY(),
(float) pos.getWidth(), (float) pos.getHeight());
if (zone.isDraggingWholeObject() || zone.isDraggingLeftEdge())
verticalSnapPositions.add (SnapLine (floatPos.getX(), floatPos.getY(), floatPos.getBottom()));
if (zone.isDraggingWholeObject() || (zone.isDraggingLeftEdge() && zone.isDraggingRightEdge()))
verticalSnapPositions.add (SnapLine (floatPos.getCentreX(), floatPos.getY(), floatPos.getBottom()));
if (zone.isDraggingWholeObject() || zone.isDraggingRightEdge())
verticalSnapPositions.add (SnapLine (floatPos.getRight(), floatPos.getY(), floatPos.getBottom()));
if (zone.isDraggingWholeObject() || zone.isDraggingTopEdge())
horizontalSnapPositions.add (SnapLine (floatPos.getY(), floatPos.getX(), floatPos.getRight()));
if (zone.isDraggingWholeObject() || (zone.isDraggingTopEdge() && zone.isDraggingBottomEdge()))
horizontalSnapPositions.add (SnapLine (floatPos.getCentreY(), floatPos.getX(), floatPos.getRight()));
if (zone.isDraggingWholeObject() || zone.isDraggingBottomEdge())
horizontalSnapPositions.add (SnapLine (floatPos.getBottom(), floatPos.getX(), floatPos.getRight()));
}
verticalSnapTargets.add (SnapLine (0, 0, 10000.0f));
verticalSnapTargets.add (SnapLine (getDocument().getCanvasWidth().getValue(), 0, 10000.0f));
if (zone.isDraggingWholeObject() || (zone.isDraggingLeftEdge() && zone.isDraggingRightEdge()))
verticalSnapTargets.add (SnapLine ((float) getDocument().getCanvasWidth().getValue() / 2.0f, 0, 10000.0f));
horizontalSnapTargets.add (SnapLine (0, 0, 10000.0f));
horizontalSnapTargets.add (SnapLine (getDocument().getCanvasHeight().getValue(), 0, 10000.0f));
if (zone.isDraggingWholeObject() || (zone.isDraggingTopEdge() && zone.isDraggingBottomEdge()))
horizontalSnapTargets.add (SnapLine ((float) getDocument().getCanvasHeight().getValue() / 2.0f, 0, 10000.0f));
getDocument().beginNewTransaction();
}
~DragOperation()
{
getDocument().beginNewTransaction();
}
struct SnapLine
{
SnapLine (float position_, float start_, float end_)
: position (position_), start (start_), end (end_)
{}
float position, start, end;
};
class SnapGuideComponent : public Component
{
public:
SnapGuideComponent (const SnapLine& line_, bool isVertical_, Component* parent)
: line (line_), isVertical (isVertical_)
{
if (isVertical)
setBounds (roundToInt (line.position), roundToInt (line.start), 1, roundToInt (line.end - line.start));
else
setBounds (roundToInt (line.start), roundToInt (line.position), roundToInt (line.end - line.start), 1);
parent->addAndMakeVisible (this);
}
void paint (Graphics& g)
{
g.fillAll (Colours::blue.withAlpha (0.3f));
}
private:
const SnapLine line;
const bool isVertical;
SnapGuideComponent (const SnapGuideComponent&);
SnapGuideComponent& operator= (const SnapGuideComponent&);
};
void drag (const MouseEvent& e)
{
const float snapThreshold = 8.0f;
getDocument().getUndoManager()->undoCurrentTransactionOnly();
Point<int> distance (e.getOffsetFromDragStart());
snapGuides.clear();
SnapLine snap (0, 0, 0);
const float snapX = findBestSnapDistance (verticalSnapTargets, getVerticalSnapPositions (distance), snap);
if (fabsf (snapX) < snapThreshold)
{
distance = Point<int> (distance.getX() + snapX, distance.getY());
if (snap.position != 0)
snapGuides.add (new SnapGuideComponent (snap, true, canvas.overlay));
}
const float snapY = findBestSnapDistance (horizontalSnapTargets, getHorizontalSnapPositions (distance), snap);
if (fabsf (snapY) < snapThreshold)
{
distance = Point<int> (distance.getX(), distance.getY() + snapY);
if (snap.position != 0)
snapGuides.add (new SnapGuideComponent (snap, false, canvas.overlay));
}
for (int n = 50;;)
{
// Need to repeatedly apply the new positions until they all settle down, in case some of
// the coords are relative to each other..
bool anyUpdated = false;
for (int i = 0; i < draggedComponents.size(); ++i)
if (dragItem (draggedComponents.getReference(i), distance, originalPositions.getReference(i)))
anyUpdated = true;
if (! anyUpdated)
break;
if (--n == 0)
{
jassertfalse;
break;
}
}
}
bool dragItem (ValueTree& v, const Point<int>& distance, const Rectangle<int>& originalPos)
{
const Rectangle<int> newBounds (zone.resizeRectangleBy (originalPos, distance));
RectangleCoordinates pr (getDocument().getCoordsFor (v));
ScopedPointer<Coordinate::MarkerResolver> markers (getDocument().createMarkerResolver (v));
pr.moveToAbsolute (newBounds, *markers);
return getDocument().setCoordsFor (v, pr);
}
const Array<SnapLine> getVerticalSnapPositions (const Point<int>& distance) const
{
Array<SnapLine> p (verticalSnapPositions);
for (int i = p.size(); --i >= 0;)
p.getReference(i).position += distance.getX();
return p;
}
const Array<SnapLine> getHorizontalSnapPositions (const Point<int>& distance) const
{
Array<SnapLine> p (horizontalSnapPositions);
for (int i = p.size(); --i >= 0;)
p.getReference(i).position += distance.getY();
return p;
}
static float findBestSnapDistance (const Array<SnapLine>& targets, const Array<SnapLine>& sources, SnapLine& line)
{
if (targets.size() == 0 || sources.size() == 0)
return 0.0f;
float best = 1.0e10f;
float absBest = fabsf (best);
line = SnapLine (1.0e10f, 0, 0);
for (int i = 0; i < targets.size(); ++i)
{
for (int j = 0; j < sources.size(); ++j)
{
SnapLine& target = targets.getReference(i);
SnapLine& source = sources.getReference(j);
const float diff = target.position - source.position;
const float absDiff = fabsf (diff);
if (absDiff < absBest)
{
line = SnapLine (target.position, jmin (target.start, source.start), jmax (target.end, source.end));
best = diff;
absBest = absDiff;
}
}
}
jassert (absBest < 1.0e10f);
return best;
}
private:
Canvas& canvas;
Array <ValueTree> draggedComponents;
Array <Rectangle<int> > originalPositions;
Array <SnapLine> verticalSnapPositions, horizontalSnapPositions;
Array <SnapLine> verticalSnapTargets, horizontalSnapTargets;
const ResizableBorderComponent::Zone zone;
OwnedArray<Component> snapGuides;
ComponentDocument& getDocument() throw() { return canvas.getDocument(); }
};
void beginDrag (const MouseEvent& e, const ResizableBorderComponent::Zone& zone)
{
dragger = new DragOperation (*this, getSelectedComps(), e, zone);
}
void continueDrag (const MouseEvent& e)
{
if (dragger != 0)
dragger->drag (e);
}
void endDrag (const MouseEvent& e)
{
if (dragger != 0)
{
dragger->drag (e);
dragger = 0;
}
}
private:
ComponentEditor& editor;
const BorderSize border;
const int resizerThickness;
ScopedPointer <DragOperation> dragger;
ResizableBorderComponent::Zone dragZone;
int dragStartWidth, dragStartHeight;
@@ -571,7 +716,7 @@ private:
if (component != 0)
{
updateDragZone (e.getPosition());
canvas.getDocument().beginDrag (canvas.getSelectedComps(), e, getParentComponent(), dragZone);
canvas.beginDrag (e, dragZone);
canvas.showSizeGuides();
}
}
@@ -579,7 +724,7 @@ private:
void mouseDrag (const MouseEvent& e)
{
if (component != 0)
canvas.getDocument().continueDrag (e);
canvas.continueDrag (e);
}
void mouseUp (const MouseEvent& e)
@@ -587,7 +732,7 @@ private:
canvas.hideSizeGuides();
if (component != 0)
canvas.getDocument().endDrag (e);
canvas.endDrag (e);
updateDragZone (e.getPosition());
}
@@ -720,11 +865,10 @@ private:
{
isDraggingClickedComp = true;
canvas.getSelection().addToSelectionOnMouseUp (mouseDownCompUID, e.mods, true, mouseDownResult);
canvas.getDocument().beginDrag (canvas.getSelectedComps(), e, getParentComponent(),
ResizableBorderComponent::Zone (ResizableBorderComponent::Zone::centre));
canvas.beginDrag (e, ResizableBorderComponent::Zone (ResizableBorderComponent::Zone::centre));
}
canvas.getDocument().continueDrag (e);
canvas.continueDrag (e);
showSizeGuides();
}
}
@@ -747,7 +891,7 @@ private:
canvas.getSelection().addToSelectionOnMouseUp (mouseDownCompUID, e.mods, ! e.mouseWasClicked(), mouseDownResult);
}
canvas.getDocument().endDrag (e);
canvas.endDrag (e);
}
void findLassoItemsInArea (Array <ComponentDocument::SelectedItems::ItemType>& itemsFound, int x, int y, int width, int height)


+ 0
- 360
extras/Jucer (experimental)/Source/utility/jucer_UtilityFunctions.cpp View File

@@ -503,363 +503,3 @@ int indexOfLineStartingWith (const StringArray& lines, const String& text, int s
return -1;
}
//==============================================================================
const char* Coordinate::parentLeftMarkerName = "parent.left";
const char* Coordinate::parentRightMarkerName = "parent.right";
const char* Coordinate::parentTopMarkerName = "parent.top";
const char* Coordinate::parentBottomMarkerName = "parent.bottom";
Coordinate::Coordinate (bool isHorizontal_)
: value (0), isProportion (false), isHorizontal (isHorizontal_)
{
}
Coordinate::Coordinate (double absoluteDistanceFromOrigin, bool isHorizontal_)
: value (absoluteDistanceFromOrigin), isProportion (false), isHorizontal (isHorizontal_)
{
}
Coordinate::Coordinate (double absoluteDistance, const String& source, bool isHorizontal_)
: anchor1 (source), value (absoluteDistance), isProportion (false), isHorizontal (isHorizontal_)
{
}
Coordinate::Coordinate (double relativeProportion, const String& pos1, const String& pos2, bool isHorizontal_)
: anchor1 (pos1), anchor2 (pos2), value (relativeProportion), isProportion (true), isHorizontal (isHorizontal_)
{
}
Coordinate::~Coordinate()
{
}
const Coordinate Coordinate::getAnchorPoint1() const
{
return Coordinate (0.0, anchor1, isHorizontal);
}
const Coordinate Coordinate::getAnchorPoint2() const
{
return Coordinate (0.0, anchor2, isHorizontal);
}
bool Coordinate::isOrigin (const String& name)
{
return name.isEmpty() || name == parentLeftMarkerName || name == parentTopMarkerName;
}
const String Coordinate::getOriginMarkerName() const
{
return isHorizontal ? parentLeftMarkerName : parentTopMarkerName;
}
const String Coordinate::getExtentMarkerName() const
{
return isHorizontal ? parentRightMarkerName : parentBottomMarkerName;
}
const String Coordinate::checkName (const String& name) const
{
return name.isEmpty() ? getOriginMarkerName() : name;
}
double Coordinate::getPosition (const String& name, MarkerResolver& markerResolver, int recursionCounter) const
{
if (isOrigin (name))
return 0.0;
return markerResolver.findMarker (name, isHorizontal)
.resolve (markerResolver, recursionCounter + 1);
}
struct RecursivePositionException
{
};
double Coordinate::resolve (MarkerResolver& markerResolver, int recursionCounter) const
{
if (recursionCounter > 100)
{
jassertfalse
throw RecursivePositionException();
}
const double pos1 = getPosition (anchor1, markerResolver, recursionCounter);
return isProportion ? pos1 + (getPosition (anchor2, markerResolver, recursionCounter) - pos1) * value
: pos1 + value;
}
double Coordinate::resolve (MarkerResolver& markerResolver) const
{
try
{
return resolve (markerResolver, 0);
}
catch (RecursivePositionException&)
{}
return 0.0;
}
void Coordinate::moveToAbsolute (double newPos, MarkerResolver& markerResolver)
{
try
{
const double pos1 = getPosition (anchor1, markerResolver, 0);
if (isProportion)
{
const double size = getPosition (anchor2, markerResolver, 0) - pos1;
if (size != 0)
value = (newPos - pos1) / size;
}
else
{
value = newPos - pos1;
}
}
catch (RecursivePositionException&)
{}
}
bool Coordinate::isRecursive (MarkerResolver& markerResolver) const
{
try
{
resolve (markerResolver, 0);
}
catch (RecursivePositionException&)
{
return true;
}
return false;
}
void Coordinate::skipWhitespace (const String& s, int& i)
{
while (CharacterFunctions::isWhitespace (s[i]))
++i;
}
const String Coordinate::readMarkerName (const String& s, int& i)
{
skipWhitespace (s, i);
if (CharacterFunctions::isLetter (s[i]) || s[i] == '_')
{
int start = i;
while (CharacterFunctions::isLetterOrDigit (s[i]) || s[i] == '_' || s[i] == '.')
++i;
return s.substring (start, i);
}
return String::empty;
}
double Coordinate::readNumber (const String& s, int& i)
{
skipWhitespace (s, i);
int start = i;
if (CharacterFunctions::isDigit (s[i]) || s[i] == '.' || s[i] == '-')
++i;
while (CharacterFunctions::isDigit (s[i]) || s[i] == '.')
++i;
if ((s[i] == 'e' || s[i] == 'E')
&& (CharacterFunctions::isDigit (s[i + 1])
|| s[i + 1] == '-'
|| s[i + 1] == '+'))
{
i += 2;
while (CharacterFunctions::isDigit (s[i]))
++i;
}
const double value = s.substring (start, i).getDoubleValue();
while (CharacterFunctions::isWhitespace (s[i]) || s[i] == ',')
++i;
return value;
}
Coordinate::Coordinate (const String& s, bool isHorizontal_)
: value (0), isProportion (false), isHorizontal (isHorizontal_)
{
int i = 0;
anchor1 = readMarkerName (s, i);
if (anchor1.isNotEmpty())
{
skipWhitespace (s, i);
if (s[i] == '+')
value = readNumber (s, ++i);
else if (s[i] == '-')
value = -readNumber (s, ++i);
}
else
{
value = readNumber (s, i);
skipWhitespace (s, i);
if (s[i] == '%')
{
isProportion = true;
value /= 100.0;
skipWhitespace (s, ++i);
if (s[i] == '*')
{
anchor1 = readMarkerName (s, ++i);
skipWhitespace (s, i);
if (s[i] == '-' && s[i + 1] == '>')
{
i += 2;
anchor2 = readMarkerName (s, i);
}
else
{
anchor2 = anchor1;
anchor1 = getOriginMarkerName();
}
}
else
{
anchor1 = getOriginMarkerName();
anchor2 = getExtentMarkerName();
}
}
}
}
const String Coordinate::toString() const
{
if (isProportion)
{
const String percent (value * 100.0);
if (isOrigin (anchor1))
{
if (anchor2 == parentRightMarkerName || anchor2 == parentBottomMarkerName)
return percent + "%";
else
return percent + "% * " + checkName (anchor2);
}
else
return percent + "% * " + checkName (anchor1) + " -> " + checkName (anchor2);
}
else
{
if (isOrigin (anchor1))
return String (value);
else if (value > 0)
return checkName (anchor1) + " + " + String (value);
else if (value < 0)
return checkName (anchor1) + " - " + String (-value);
else
return checkName (anchor1);
}
}
const double Coordinate::getEditableValue() const
{
return isProportion ? value * 100.0 : value;
}
void Coordinate::setEditableValue (const double newValue)
{
value = isProportion ? newValue / 100.0 : newValue;
}
void Coordinate::toggleProportionality (MarkerResolver& markerResolver)
{
const double oldValue = resolve (markerResolver);
isProportion = ! isProportion;
anchor1 = getOriginMarkerName();
anchor2 = getExtentMarkerName();
moveToAbsolute (oldValue, markerResolver);
}
void Coordinate::changeAnchor1 (const String& newMarkerName, MarkerResolver& markerResolver)
{
const double oldValue = resolve (markerResolver);
anchor1 = newMarkerName;
moveToAbsolute (oldValue, markerResolver);
}
void Coordinate::changeAnchor2 (const String& newMarkerName, MarkerResolver& markerResolver)
{
const double oldValue = resolve (markerResolver);
anchor2 = newMarkerName;
moveToAbsolute (oldValue, markerResolver);
}
//==============================================================================
RectangleCoordinates::RectangleCoordinates()
: left (true), right (true), top (false), bottom (false)
{
}
RectangleCoordinates::RectangleCoordinates (const Rectangle<int>& rect)
: left (rect.getX(), true),
right (rect.getWidth(), "left", true),
top (rect.getY(), false),
bottom (rect.getHeight(), "top", false)
{
}
RectangleCoordinates::RectangleCoordinates (const String& stringVersion)
: left (true), right (true), top (false), bottom (false)
{
StringArray tokens;
tokens.addTokens (stringVersion, ",", String::empty);
left = Coordinate (tokens [0], true);
top = Coordinate (tokens [1], false);
right = Coordinate (tokens [2], true);
bottom = Coordinate (tokens [3], false);
}
bool RectangleCoordinates::isRecursive (Coordinate::MarkerResolver& markerResolver) const
{
return left.isRecursive (markerResolver) || right.isRecursive (markerResolver)
|| top.isRecursive (markerResolver) || bottom.isRecursive (markerResolver);
}
const Rectangle<int> RectangleCoordinates::resolve (Coordinate::MarkerResolver& markerResolver) const
{
const int l = roundToInt (left.resolve (markerResolver));
const int r = roundToInt (right.resolve (markerResolver));
const int t = roundToInt (top.resolve (markerResolver));
const int b = roundToInt (bottom.resolve (markerResolver));
return Rectangle<int> (l, t, r - l, b - t);
}
void RectangleCoordinates::moveToAbsolute (const Rectangle<int>& newPos, Coordinate::MarkerResolver& markerResolver)
{
left.moveToAbsolute (newPos.getX(), markerResolver);
right.moveToAbsolute (newPos.getRight(), markerResolver);
top.moveToAbsolute (newPos.getY(), markerResolver);
bottom.moveToAbsolute (newPos.getBottom(), markerResolver);
}
const String RectangleCoordinates::toString() const
{
return left.toString() + ", " + top.toString() + ", " + right.toString() + ", " + bottom.toString();
}

+ 91
- 111
extras/Jucer (experimental)/Source/utility/jucer_UtilityFunctions.h View File

@@ -109,127 +109,107 @@ private:
int64 fileHashCode, fileSize;
};
//==============================================================================
/**
Holds a co-ordinate along the x or y axis, expressed either as an absolute
position, or relative to other named marker positions.
*/
class Coordinate
static const double tickSizes[] = { 1.0, 2.0, 5.0,
10.0, 20.0, 50.0,
100.0, 200.0, 500.0, 1000.0 };
class TickIterator
{
public:
//==============================================================================
/** Creates a zero coordinate. */
explicit Coordinate (bool isHorizontal);
TickIterator (const double startValue_, const double endValue_, const double valuePerPixel_,
int minPixelsPerTick, int minWidthForLabels)
: startValue (startValue_),
endValue (endValue_),
valuePerPixel (valuePerPixel_)
{
tickLevelIndex = findLevelIndexForValue (valuePerPixel * minPixelsPerTick);
labelLevelIndex = findLevelIndexForValue (valuePerPixel * minWidthForLabels);
tickPosition = pixelsToValue (-minWidthForLabels);
tickPosition = snapValueDown (tickPosition, tickLevelIndex);
}
/** Recreates a coordinate from its stringified version. */
Coordinate (const String& stringVersion, bool isHorizontal);
bool getNextTick (float& pixelX, float& tickLength, String& label)
{
const double tickUnits = tickSizes [tickLevelIndex];
tickPosition += tickUnits;
/** Creates an absolute position from the parent origin. */
Coordinate (double absoluteDistanceFromOrigin, bool isHorizontal);
const int totalLevels = sizeof (tickSizes) / sizeof (*tickSizes);
int highestIndex = tickLevelIndex;
/** Creates an absolute position relative to a named marker. */
Coordinate (double absolutePosition, const String& relativeToMarker, bool isHorizontal);
while (++highestIndex < totalLevels)
{
const double ticksAtThisLevel = tickPosition / tickSizes [highestIndex];
/** Creates a relative position between two named markers. */
Coordinate (double relativePosition, const String& marker1, const String& marker2, bool isHorizontal);
if (fabs (ticksAtThisLevel - floor (ticksAtThisLevel + 0.5)) > 0.000001)
break;
}
/** Destructor. */
~Coordinate();
--highestIndex;
//==============================================================================
/**
Provides an interface for looking up the position of a named marker.
*/
class MarkerResolver
{
public:
virtual ~MarkerResolver() {}
virtual const Coordinate findMarker (const String& name, bool isHorizontal) = 0;
};
/** Calculates the absolute position of this co-ordinate. */
double resolve (MarkerResolver& markerResolver) const;
/** Returns true if this co-ordinate is expressed in terms of markers that form a recursive loop. */
bool isRecursive (MarkerResolver& markerResolver) const;
/** Changes the value of this marker to make it resolve to the specified position. */
void moveToAbsolute (double newPos, MarkerResolver& markerResolver);
const Coordinate getAnchorPoint1() const;
const Coordinate getAnchorPoint2() const;
const double getEditableValue() const;
void setEditableValue (const double newValue);
bool isProportional() const throw() { return isProportion; }
void toggleProportionality (MarkerResolver& markerResolver);
const String getAnchor1() const { return anchor1; }
void changeAnchor1 (const String& newMarkerName, MarkerResolver& markerResolver);
const String getAnchor2() const { return anchor2; }
void changeAnchor2 (const String& newMarkerName, MarkerResolver& markerResolver);
//==============================================================================
/*
Position string formats:
123 = absolute pixels from parent origin
marker
marker + 123
marker - 123
50% = percentage between parent origin and parent extent
50% * marker = percentage between parent origin and marker
50% * marker1 -> marker2 = percentage between two markers
standard marker names:
"origin" = parent origin
"size" = parent right or bottom
"top", "left", "bottom", "right" = refer to the component's own left, right, top and bottom.
*/
const String toString() const;
//==============================================================================
static const char* parentLeftMarkerName;
static const char* parentRightMarkerName;
static const char* parentTopMarkerName;
static const char* parentBottomMarkerName;
if (highestIndex >= labelLevelIndex)
label = getDescriptionOfValue (tickPosition, labelLevelIndex);
else
label = String::empty;
tickLength = (highestIndex + 1 - tickLevelIndex) / (float) (totalLevels + 1 - tickLevelIndex);
pixelX = valueToPixels (tickPosition);
return tickPosition < endValue;
}
private:
//==============================================================================
String anchor1, anchor2;
double value;
bool isProportion, isHorizontal;
double resolve (MarkerResolver& markerResolver, int recursionCounter) const;
double getPosition (const String& name, MarkerResolver& markerResolver, int recursionCounter) const;
const String checkName (const String& name) const;
const String getOriginMarkerName() const;
const String getExtentMarkerName() const;
static bool isOrigin (const String& name);
static void skipWhitespace (const String& s, int& i);
static const String readMarkerName (const String& s, int& i);
static double readNumber (const String& s, int& i);
};
double tickPosition;
int tickLevelIndex, labelLevelIndex;
const double startValue, endValue, valuePerPixel;
//==============================================================================
/**
Describes a rectangle as a set of Coordinate values.
*/
class RectangleCoordinates
{
public:
//==============================================================================
RectangleCoordinates();
explicit RectangleCoordinates (const Rectangle<int>& rect);
explicit RectangleCoordinates (const String& stringVersion);
//==============================================================================
const Rectangle<int> resolve (Coordinate::MarkerResolver& markerResolver) const;
bool isRecursive (Coordinate::MarkerResolver& markerResolver) const;
void moveToAbsolute (const Rectangle<int>& newPos, Coordinate::MarkerResolver& markerResolver);
const String toString() const;
Coordinate left, right, top, bottom;
int findLevelIndexForValue (const double value) const
{
int i;
for (i = 0; i < sizeof (tickSizes) / sizeof (*tickSizes); ++i)
if (tickSizes [i] >= value)
break;
return i;
}
double pixelsToValue (int pixels) const
{
return startValue + pixels * valuePerPixel;
}
float valueToPixels (double value) const
{
return (float) ((value - startValue) / valuePerPixel);
}
static double snapValueToNearest (const double t, const int valueLevelIndex)
{
const double unitsPerInterval = tickSizes [valueLevelIndex];
return unitsPerInterval * floor (t / unitsPerInterval + 0.5);
}
static double snapValueDown (const double t, const int valueLevelIndex)
{
const double unitsPerInterval = tickSizes [valueLevelIndex];
return unitsPerInterval * floor (t / unitsPerInterval);
}
static inline int roundDoubleToInt (const double value)
{
union { int asInt[2]; double asDouble; } n;
n.asDouble = value + 6755399441055744.0;
#if TARGET_RT_BIG_ENDIAN
return n.asInt [1];
#else
return n.asInt [0];
#endif
}
static const String getDescriptionOfValue (const double value, const int valueLevelIndex)
{
return String (roundToInt (value));
}
};

+ 4
- 4
extras/amalgamator/Builds/Linux/Makefile View File

@@ -19,8 +19,8 @@ ifeq ($(CONFIG),Debug)
OUTDIR := build
CPPFLAGS := $(DEPFLAGS) -D "LINUX=1" -D "DEBUG=1" -D "_DEBUG=1" -I "/usr/include" -I "/usr/include/freetype2"
CFLAGS += $(CPPFLAGS) $(TARGET_ARCH) -g -ggdb -O0
CXXFLAGS += $(CFLAGS)
LDFLAGS += -L$(BINDIR) -L$(LIBDIR) -mwindows -L"/usr/X11R6/lib/" -L"../../../../../juce/bin" -lfreetype -lpthread -lrt -lX11 -lGL -lGLU -lXinerama -lasound
CXXFLAGS += $(CFLAGS)
LDFLAGS += -L$(BINDIR) -L$(LIBDIR) -L"/usr/X11R6/lib/" -L"../../../../../juce/bin" -lfreetype -lpthread -lrt -lX11 -lGL -lGLU -lXinerama -lasound
LDDEPS :=
RESFLAGS := -D "LINUX=1" -D "DEBUG=1" -D "_DEBUG=1" -I "/usr/include" -I "/usr/include/freetype2"
TARGET := amalgamator
@@ -34,8 +34,8 @@ ifeq ($(CONFIG),Release)
OUTDIR := build
CPPFLAGS := $(DEPFLAGS) -D "LINUX=1" -D "NDEBUG=1" -I "/usr/include" -I "/usr/include/freetype2"
CFLAGS += $(CPPFLAGS) $(TARGET_ARCH) -Os
CXXFLAGS += $(CFLAGS)
LDFLAGS += -L$(BINDIR) -L$(LIBDIR) -mwindows -L"/usr/X11R6/lib/" -L"../../../../../juce/bin" -lfreetype -lpthread -lrt -lX11 -lGL -lGLU -lXinerama -lasound
CXXFLAGS += $(CFLAGS)
LDFLAGS += -L$(BINDIR) -L$(LIBDIR) -L"/usr/X11R6/lib/" -L"../../../../../juce/bin" -lfreetype -lpthread -lrt -lX11 -lGL -lGLU -lXinerama -lasound
LDDEPS :=
RESFLAGS := -D "LINUX=1" -D "NDEBUG=1" -I "/usr/include" -I "/usr/include/freetype2"
TARGET := amalgamator


+ 4
- 4
extras/audio plugin host/Builds/Linux/Makefile View File

@@ -19,8 +19,8 @@ ifeq ($(CONFIG),Debug)
OUTDIR := build
CPPFLAGS := $(DEPFLAGS) -D "LINUX=1" -D "DEBUG=1" -D "_DEBUG=1" -I "/usr/include" -I "/usr/include/freetype2"
CFLAGS += $(CPPFLAGS) $(TARGET_ARCH) -g -ggdb -O0
CXXFLAGS += $(CFLAGS)
LDFLAGS += -L$(BINDIR) -L$(LIBDIR) -mwindows -L"/usr/X11R6/lib/" -L"../../../../../juce/bin" -lfreetype -lpthread -lrt -lX11 -lGL -lGLU -lXinerama -lasound
CXXFLAGS += $(CFLAGS)
LDFLAGS += -L$(BINDIR) -L$(LIBDIR) -L"/usr/X11R6/lib/" -L"../../../../../juce/bin" -lfreetype -lpthread -lrt -lX11 -lGL -lGLU -lXinerama -lasound
LDDEPS :=
RESFLAGS := -D "LINUX=1" -D "DEBUG=1" -D "_DEBUG=1" -I "/usr/include" -I "/usr/include/freetype2"
TARGET := Plugin\ Host
@@ -34,8 +34,8 @@ ifeq ($(CONFIG),Release)
OUTDIR := build
CPPFLAGS := $(DEPFLAGS) -D "LINUX=1" -D "NDEBUG=1" -I "/usr/include" -I "/usr/include/freetype2"
CFLAGS += $(CPPFLAGS) $(TARGET_ARCH) -Os
CXXFLAGS += $(CFLAGS)
LDFLAGS += -L$(BINDIR) -L$(LIBDIR) -mwindows -L"/usr/X11R6/lib/" -L"../../../../../juce/bin" -lfreetype -lpthread -lrt -lX11 -lGL -lGLU -lXinerama -lasound
CXXFLAGS += $(CFLAGS)
LDFLAGS += -L$(BINDIR) -L$(LIBDIR) -L"/usr/X11R6/lib/" -L"../../../../../juce/bin" -lfreetype -lpthread -lrt -lX11 -lGL -lGLU -lXinerama -lasound
LDDEPS :=
RESFLAGS := -D "LINUX=1" -D "NDEBUG=1" -I "/usr/include" -I "/usr/include/freetype2"
TARGET := Plugin\ Host


+ 4
- 4
extras/binarybuilder/Builds/Linux/Makefile View File

@@ -19,8 +19,8 @@ ifeq ($(CONFIG),Debug)
OUTDIR := build
CPPFLAGS := $(DEPFLAGS) -D "LINUX=1" -D "DEBUG=1" -D "_DEBUG=1" -I "/usr/include" -I "/usr/include/freetype2"
CFLAGS += $(CPPFLAGS) $(TARGET_ARCH) -g -ggdb -O0
CXXFLAGS += $(CFLAGS)
LDFLAGS += -L$(BINDIR) -L$(LIBDIR) -mwindows -L"/usr/X11R6/lib/" -L"../../../../../juce/bin" -lfreetype -lpthread -lrt -lX11 -lGL -lGLU -lXinerama -lasound
CXXFLAGS += $(CFLAGS)
LDFLAGS += -L$(BINDIR) -L$(LIBDIR) -L"/usr/X11R6/lib/" -L"../../../../../juce/bin" -lfreetype -lpthread -lrt -lX11 -lGL -lGLU -lXinerama -lasound
LDDEPS :=
RESFLAGS := -D "LINUX=1" -D "DEBUG=1" -D "_DEBUG=1" -I "/usr/include" -I "/usr/include/freetype2"
TARGET := BinaryBuilder
@@ -34,8 +34,8 @@ ifeq ($(CONFIG),Release)
OUTDIR := build
CPPFLAGS := $(DEPFLAGS) -D "LINUX=1" -D "NDEBUG=1" -I "/usr/include" -I "/usr/include/freetype2"
CFLAGS += $(CPPFLAGS) $(TARGET_ARCH) -Os
CXXFLAGS += $(CFLAGS)
LDFLAGS += -L$(BINDIR) -L$(LIBDIR) -mwindows -L"/usr/X11R6/lib/" -L"../../../../../juce/bin" -lfreetype -lpthread -lrt -lX11 -lGL -lGLU -lXinerama -lasound
CXXFLAGS += $(CFLAGS)
LDFLAGS += -L$(BINDIR) -L$(LIBDIR) -L"/usr/X11R6/lib/" -L"../../../../../juce/bin" -lfreetype -lpthread -lrt -lX11 -lGL -lGLU -lXinerama -lasound
LDDEPS :=
RESFLAGS := -D "LINUX=1" -D "NDEBUG=1" -I "/usr/include" -I "/usr/include/freetype2"
TARGET := BinaryBuilder


+ 4
- 4
extras/example projects/Builds/Linux/Makefile View File

@@ -19,8 +19,8 @@ ifeq ($(CONFIG),Debug)
OUTDIR := build
CPPFLAGS := $(DEPFLAGS) -D "LINUX=1" -D "DEBUG=1" -D "_DEBUG=1" -I "/usr/include" -I "/usr/include/freetype2"
CFLAGS += $(CPPFLAGS) $(TARGET_ARCH) -g -ggdb -O0
CXXFLAGS += $(CFLAGS)
LDFLAGS += -L$(BINDIR) -L$(LIBDIR) -mwindows -L"/usr/X11R6/lib/" -L"../../../../../juce/bin" -lfreetype -lpthread -lrt -lX11 -lGL -lGLU -lXinerama -lasound
CXXFLAGS += $(CFLAGS)
LDFLAGS += -L$(BINDIR) -L$(LIBDIR) -L"/usr/X11R6/lib/" -L"../../../../../juce/bin" -lfreetype -lpthread -lrt -lX11 -lGL -lGLU -lXinerama -lasound
LDDEPS :=
RESFLAGS := -D "LINUX=1" -D "DEBUG=1" -D "_DEBUG=1" -I "/usr/include" -I "/usr/include/freetype2"
TARGET := HelloWorld
@@ -34,8 +34,8 @@ ifeq ($(CONFIG),Release)
OUTDIR := build
CPPFLAGS := $(DEPFLAGS) -D "LINUX=1" -D "NDEBUG=1" -I "/usr/include" -I "/usr/include/freetype2"
CFLAGS += $(CPPFLAGS) $(TARGET_ARCH) -Os
CXXFLAGS += $(CFLAGS)
LDFLAGS += -L$(BINDIR) -L$(LIBDIR) -mwindows -L"/usr/X11R6/lib/" -L"../../../../../juce/bin" -lfreetype -lpthread -lrt -lX11 -lGL -lGLU -lXinerama -lasound
CXXFLAGS += $(CFLAGS)
LDFLAGS += -L$(BINDIR) -L$(LIBDIR) -L"/usr/X11R6/lib/" -L"../../../../../juce/bin" -lfreetype -lpthread -lrt -lX11 -lGL -lGLU -lXinerama -lasound
LDDEPS :=
RESFLAGS := -D "LINUX=1" -D "NDEBUG=1" -I "/usr/include" -I "/usr/include/freetype2"
TARGET := HelloWorld


+ 4
- 4
extras/juce demo/Builds/Linux/Makefile View File

@@ -19,8 +19,8 @@ ifeq ($(CONFIG),Debug)
OUTDIR := build
CPPFLAGS := $(DEPFLAGS) -D "LINUX=1" -D "DEBUG=1" -D "_DEBUG=1" -I "/usr/include" -I "/usr/include/freetype2"
CFLAGS += $(CPPFLAGS) $(TARGET_ARCH) -g -ggdb -O0
CXXFLAGS += $(CFLAGS)
LDFLAGS += -L$(BINDIR) -L$(LIBDIR) -mwindows -L"/usr/X11R6/lib/" -L"../../../../../juce/bin" -lfreetype -lpthread -lrt -lX11 -lGL -lGLU -lXinerama -lasound
CXXFLAGS += $(CFLAGS)
LDFLAGS += -L$(BINDIR) -L$(LIBDIR) -L"/usr/X11R6/lib/" -L"../../../../../juce/bin" -lfreetype -lpthread -lrt -lX11 -lGL -lGLU -lXinerama -lasound
LDDEPS :=
RESFLAGS := -D "LINUX=1" -D "DEBUG=1" -D "_DEBUG=1" -I "/usr/include" -I "/usr/include/freetype2"
TARGET := JuceDemo
@@ -34,8 +34,8 @@ ifeq ($(CONFIG),Release)
OUTDIR := build
CPPFLAGS := $(DEPFLAGS) -D "LINUX=1" -D "NDEBUG=1" -I "/usr/include" -I "/usr/include/freetype2"
CFLAGS += $(CPPFLAGS) $(TARGET_ARCH) -Os
CXXFLAGS += $(CFLAGS)
LDFLAGS += -L$(BINDIR) -L$(LIBDIR) -mwindows -L"/usr/X11R6/lib/" -L"../../../../../juce/bin" -lfreetype -lpthread -lrt -lX11 -lGL -lGLU -lXinerama -lasound
CXXFLAGS += $(CFLAGS)
LDFLAGS += -L$(BINDIR) -L$(LIBDIR) -L"/usr/X11R6/lib/" -L"../../../../../juce/bin" -lfreetype -lpthread -lrt -lX11 -lGL -lGLU -lXinerama -lasound
LDDEPS :=
RESFLAGS := -D "LINUX=1" -D "NDEBUG=1" -I "/usr/include" -I "/usr/include/freetype2"
TARGET := JuceDemo


+ 16
- 6
juce_amalgamated.cpp View File

@@ -10189,7 +10189,8 @@ public:
static juce_wchar* createCopy (const char* const src, const size_t numChars)
{
juce_wchar* const dest = createUninitialised (numChars);
CharacterFunctions::copy (dest, src, numChars + 1);
CharacterFunctions::copy (dest, src, numChars);
dest [numChars] = 0;
return dest;
}

@@ -17924,7 +17925,11 @@ FileBasedDocument::~FileBasedDocument()

void FileBasedDocument::setChangedFlag (const bool hasChanged)
{
changedSinceSave = hasChanged;
if (changedSinceSave != hasChanged)
{
changedSinceSave = hasChanged;
sendChangeMessage (this);
}
}

void FileBasedDocument::changed()
@@ -17938,7 +17943,7 @@ void FileBasedDocument::setFile (const File& newFile)
if (documentFile != newFile)
{
documentFile = newFile;
changedSinceSave = true;
changed();
}
}

@@ -48452,12 +48457,17 @@ void Slider::setTextValueSuffix (const String& suffix)
}
}

const String Slider::getTextValueSuffix() const
{
return textSuffix;
}

const String Slider::getTextFromValue (double v)
{
if (numDecimalPlaces > 0)
return String (v, numDecimalPlaces) + textSuffix;
if (getNumDecimalPlacesToDisplay() > 0)
return String (v, getNumDecimalPlacesToDisplay()) + getTextValueSuffix();
else
return String (roundToInt (v)) + textSuffix;
return String (roundToInt (v)) + getTextValueSuffix();
}

double Slider::getValueFromText (const String& text)


+ 5
- 1
juce_amalgamated.h View File

@@ -43,7 +43,7 @@

#define JUCE_MAJOR_VERSION 1
#define JUCE_MINOR_VERSION 51
#define JUCE_BUILDNUMBER 14
#define JUCE_BUILDNUMBER 15

#define JUCE_VERSION ((JUCE_MAJOR_VERSION << 16) + (JUCE_MINOR_VERSION << 8) + JUCE_BUILDNUMBER)

@@ -21367,6 +21367,8 @@ public:

void setTextValueSuffix (const String& suffix);

const String getTextValueSuffix() const;

virtual double proportionOfLengthToValue (double proportion);

virtual double valueToProportionOfLength (double value);
@@ -21415,6 +21417,8 @@ protected:
void colourChanged();
void valueChanged (Value& value);

int getNumDecimalPlacesToDisplay() const throw() { return numDecimalPlaces; }

private:
ListenerList <SliderListener> listeners;
Value currentValue, valueMin, valueMax;


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

@@ -47,7 +47,7 @@ public:
/** If the current value of destination is equal to requiredCurrentValue, this
will set it to newValue; otherwise, it will leave it unchanged.
@returns the new value of destination
@returns the original value of destination
*/
static int32 compareAndExchange (int32& destination, int32 newValue, int32 requiredCurrentValue);


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

@@ -33,7 +33,7 @@
*/
#define JUCE_MAJOR_VERSION 1
#define JUCE_MINOR_VERSION 51
#define JUCE_BUILDNUMBER 14
#define JUCE_BUILDNUMBER 15
/** Current Juce version number.


+ 8
- 3
src/gui/components/controls/juce_Slider.cpp View File

@@ -632,12 +632,17 @@ void Slider::setTextValueSuffix (const String& suffix)
}
}
const String Slider::getTextValueSuffix() const
{
return textSuffix;
}
const String Slider::getTextFromValue (double v)
{
if (numDecimalPlaces > 0)
return String (v, numDecimalPlaces) + textSuffix;
if (getNumDecimalPlacesToDisplay() > 0)
return String (v, getNumDecimalPlacesToDisplay()) + getTextValueSuffix();
else
return String (roundToInt (v)) + textSuffix;
return String (roundToInt (v)) + getTextValueSuffix();
}
double Slider::getValueFromText (const String& text)


+ 8
- 0
src/gui/components/controls/juce_Slider.h View File

@@ -620,6 +620,9 @@ public:
*/
void setTextValueSuffix (const String& suffix);
/** Returns the suffix that was set by setTextValueSuffix(). */
const String getTextValueSuffix() const;
//==============================================================================
/** Allows a user-defined mapping of distance along the slider to its value.
@@ -748,6 +751,11 @@ protected:
/** @internal */
void valueChanged (Value& value);
/** Returns the best number of decimal places to use when displaying numbers.
This is calculated from the slider's interval setting.
*/
int getNumDecimalPlacesToDisplay() const throw() { return numDecimalPlaces; }
private:
ListenerList <SliderListener> listeners;
Value currentValue, valueMin, valueMax;


+ 2
- 1
src/text/juce_String.cpp View File

@@ -78,7 +78,8 @@ public:
static juce_wchar* createCopy (const char* const src, const size_t numChars)
{
juce_wchar* const dest = createUninitialised (numChars);
CharacterFunctions::copy (dest, src, numChars + 1);
CharacterFunctions::copy (dest, src, numChars);
dest [numChars] = 0;
return dest;
}


+ 2
- 2
src/text/juce_String.h View File

@@ -565,7 +565,7 @@ public:
/** Returns a copy of this string, having removed a specified set of characters from its start.
Characters are removed from the start of the string until it finds one that is not in the
specified set, and then it stops.
@param charactersToTrim the set of characters to remove. This must not be null.
@param charactersToTrim the set of characters to remove.
@see trim, trimStart, trimCharactersAtEnd
*/
const String trimCharactersAtStart (const String& charactersToTrim) const;
@@ -573,7 +573,7 @@ public:
/** Returns a copy of this string, having removed a specified set of characters from its end.
Characters are removed from the end of the string until it finds one that is not in the
specified set, and then it stops.
@param charactersToTrim the set of characters to remove. This must not be null.
@param charactersToTrim the set of characters to remove.
@see trim, trimEnd, trimCharactersAtStart
*/
const String trimCharactersAtEnd (const String& charactersToTrim) const;


+ 6
- 2
src/utilities/juce_FileBasedDocument.cpp View File

@@ -54,7 +54,11 @@ FileBasedDocument::~FileBasedDocument()
//==============================================================================
void FileBasedDocument::setChangedFlag (const bool hasChanged)
{
changedSinceSave = hasChanged;
if (changedSinceSave != hasChanged)
{
changedSinceSave = hasChanged;
sendChangeMessage (this);
}
}
void FileBasedDocument::changed()
@@ -69,7 +73,7 @@ void FileBasedDocument::setFile (const File& newFile)
if (documentFile != newFile)
{
documentFile = newFile;
changedSinceSave = true;
changed();
}
}


Loading…
Cancel
Save