mirror of
https://github.com/juce-framework/JUCE.git
synced 2026-01-10 23:44:24 +00:00
String fix. Minor additional methods for FileBasedDocument and Slider. Jucer development.
This commit is contained in:
parent
643eea5fde
commit
a612dfdc2f
27 changed files with 1089 additions and 782 deletions
|
|
@ -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 $<)
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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"/>
|
||||
|
|
|
|||
|
|
@ -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"/>
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
extras/Jucer (experimental)/Source/model/jucer_Coordinate.cpp
Normal file
392
extras/Jucer (experimental)/Source/model/jucer_Coordinate.cpp
Normal 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
extras/Jucer (experimental)/Source/model/jucer_Coordinate.h
Normal file
157
extras/Jucer (experimental)/Source/model/jucer_Coordinate.h
Normal 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__
|
||||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
/** 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
|
||||
TickIterator (const double startValue_, const double endValue_, const double valuePerPixel_,
|
||||
int minPixelsPerTick, int minWidthForLabels)
|
||||
: startValue (startValue_),
|
||||
endValue (endValue_),
|
||||
valuePerPixel (valuePerPixel_)
|
||||
{
|
||||
public:
|
||||
virtual ~MarkerResolver() {}
|
||||
virtual const Coordinate findMarker (const String& name, bool isHorizontal) = 0;
|
||||
};
|
||||
tickLevelIndex = findLevelIndexForValue (valuePerPixel * minPixelsPerTick);
|
||||
labelLevelIndex = findLevelIndexForValue (valuePerPixel * minWidthForLabels);
|
||||
|
||||
/** Calculates the absolute position of this co-ordinate. */
|
||||
double resolve (MarkerResolver& markerResolver) const;
|
||||
tickPosition = pixelsToValue (-minWidthForLabels);
|
||||
tickPosition = snapValueDown (tickPosition, tickLevelIndex);
|
||||
}
|
||||
|
||||
/** Returns true if this co-ordinate is expressed in terms of markers that form a recursive loop. */
|
||||
bool isRecursive (MarkerResolver& markerResolver) const;
|
||||
bool getNextTick (float& pixelX, float& tickLength, String& label)
|
||||
{
|
||||
const double tickUnits = tickSizes [tickLevelIndex];
|
||||
tickPosition += tickUnits;
|
||||
|
||||
/** Changes the value of this marker to make it resolve to the specified position. */
|
||||
void moveToAbsolute (double newPos, MarkerResolver& markerResolver);
|
||||
const int totalLevels = sizeof (tickSizes) / sizeof (*tickSizes);
|
||||
int highestIndex = tickLevelIndex;
|
||||
|
||||
const Coordinate getAnchorPoint1() const;
|
||||
const Coordinate getAnchorPoint2() const;
|
||||
while (++highestIndex < totalLevels)
|
||||
{
|
||||
const double ticksAtThisLevel = tickPosition / tickSizes [highestIndex];
|
||||
|
||||
const double getEditableValue() const;
|
||||
void setEditableValue (const double newValue);
|
||||
if (fabs (ticksAtThisLevel - floor (ticksAtThisLevel + 0.5)) > 0.000001)
|
||||
break;
|
||||
}
|
||||
|
||||
bool isProportional() const throw() { return isProportion; }
|
||||
void toggleProportionality (MarkerResolver& markerResolver);
|
||||
--highestIndex;
|
||||
|
||||
const String getAnchor1() const { return anchor1; }
|
||||
void changeAnchor1 (const String& newMarkerName, MarkerResolver& markerResolver);
|
||||
if (highestIndex >= labelLevelIndex)
|
||||
label = getDescriptionOfValue (tickPosition, labelLevelIndex);
|
||||
else
|
||||
label = String::empty;
|
||||
|
||||
const String getAnchor2() const { return anchor2; }
|
||||
void changeAnchor2 (const String& newMarkerName, MarkerResolver& markerResolver);
|
||||
tickLength = (highestIndex + 1 - tickLevelIndex) / (float) (totalLevels + 1 - tickLevelIndex);
|
||||
pixelX = valueToPixels (tickPosition);
|
||||
|
||||
//==============================================================================
|
||||
/*
|
||||
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;
|
||||
return tickPosition < endValue;
|
||||
}
|
||||
|
||||
private:
|
||||
//==============================================================================
|
||||
String anchor1, anchor2;
|
||||
double value;
|
||||
bool isProportion, isHorizontal;
|
||||
double tickPosition;
|
||||
int tickLevelIndex, labelLevelIndex;
|
||||
const double startValue, endValue, valuePerPixel;
|
||||
|
||||
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;
|
||||
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));
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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…
Add table
Add a link
Reference in a new issue