Browse Source

Update juce; Fix LV2 time position

tags/2018-04-16
falkTX 8 years ago
parent
commit
2aa2419c82
11 changed files with 358 additions and 146 deletions
  1. +1
    -1
      libs/juce/source/modules/juce_audio_devices/native/juce_mac_CoreAudio.cpp
  2. +2
    -0
      libs/juce/source/modules/juce_audio_plugin_client/AU/juce_AU_Wrapper.mm
  3. +187
    -49
      libs/juce/source/modules/juce_audio_plugin_client/LV2/juce_LV2_Wrapper.cpp
  4. +1
    -1
      libs/juce/source/modules/juce_audio_plugin_client/utility/juce_IncludeModuleHeaders.h
  5. +10
    -0
      libs/juce/source/modules/juce_core/memory/juce_ContainerDeletePolicy.h
  6. +66
    -53
      libs/juce/source/modules/juce_graphics/geometry/juce_Rectangle.h
  7. +1
    -0
      libs/juce/source/modules/juce_gui_basics/buttons/juce_DrawableButton.cpp
  8. +19
    -1
      libs/juce/source/modules/juce_gui_basics/mouse/juce_DragAndDropContainer.cpp
  9. +3
    -0
      libs/juce/source/modules/juce_gui_basics/mouse/juce_DragAndDropContainer.h
  10. +47
    -23
      libs/juce/source/modules/juce_gui_basics/native/juce_mac_MouseCursor.mm
  11. +21
    -18
      libs/juce/source/modules/juce_gui_basics/native/juce_win32_Windowing.cpp

+ 1
- 1
libs/juce/source/modules/juce_audio_devices/native/juce_mac_CoreAudio.cpp View File

@@ -277,7 +277,7 @@ public:
if (OK (AudioObjectGetPropertyData (deviceID, &pa, 0, nullptr, &size, ranges)))
{
static const double possibleRates[] = { 44100.0, 48000.0, 88200.0, 96000.0, 176400.0, 192000.0 };
static const double possibleRates[] = { 44100.0, 48000.0, 88200.0, 96000.0, 176400.0, 192000.0, 384000.0 };
for (int i = 0; i < numElementsInArray (possibleRates); ++i)
{


+ 2
- 0
libs/juce/source/modules/juce_audio_plugin_client/AU/juce_AU_Wrapper.mm View File

@@ -1005,6 +1005,8 @@ public:
#if ! JucePlugin_SilenceInProducesSilenceOut
ioActionFlags &= (AudioUnitRenderActionFlags) ~kAudioUnitRenderAction_OutputIsSilence;
#else
ignoreUnused (ioActionFlags);
#endif
}


+ 187
- 49
libs/juce/source/modules/juce_audio_plugin_client/LV2/juce_LV2_Wrapper.cpp View File

@@ -67,7 +67,6 @@
#include "includes/state.h"
#include "includes/time.h"
#include "includes/ui.h"
#include "includes/units.h"
#include "includes/urid.h"
#include "includes/lv2_external_ui.h"
#include "includes/lv2_programs.h"
@@ -249,13 +248,12 @@ const String makePluginFile (AudioProcessor* const filter)
String text;

// Header
text += "@prefix atom: <" LV2_ATOM_PREFIX "> .\n";
text += "@prefix doap: <http://usefulinc.com/ns/doap#> .\n";
text += "@prefix foaf: <http://xmlns.com/foaf/0.1/> .\n";
text += "@prefix lv2: <" LV2_CORE_PREFIX "> .\n";
text += "@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .\n";
text += "@prefix ui: <" LV2_UI_PREFIX "> .\n";
text += "@prefix units: <" LV2_UNITS_PREFIX "> .\n";
text += "@prefix atom: <" LV2_ATOM_PREFIX "> .\n";
text += "@prefix doap: <http://usefulinc.com/ns/doap#> .\n";
text += "@prefix foaf: <http://xmlns.com/foaf/0.1/> .\n";
text += "@prefix lv2: <" LV2_CORE_PREFIX "> .\n";
text += "@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .\n";
text += "@prefix ui: <" LV2_UI_PREFIX "> .\n";
text += "\n";

// Plugin
@@ -399,18 +397,6 @@ const String makePluginFile (AudioProcessor* const filter)
text += " lv2:minimum 0.0 ;\n";
text += " lv2:maximum 1.0 ;\n";

String label(filter->getParameterLabel(i));

if (label.isNotEmpty())
{
text += " units:unit [\n";
text += " a units:Unit ;\n";
text += " rdfs:label \"" + label + "\" ;\n";
text += " units:symbol \"" + label + "\" ;\n";
text += " units:render \"%f " + label + "\" ;\n";
text += " ] ;\n";
}

if (! filter->isParameterAutomatable(i))
text += " lv2:portProperty <" LV2_PORT_PROPS__expensive "> ;\n";

@@ -871,7 +857,7 @@ public:
#if JucePlugin_ProducesMidiOutput
controlPortOffset += 1;
#endif
controlPortOffset += 2; // freewheel and sampleRate
controlPortOffset += 2; // freewheel and latency
controlPortOffset += JucePlugin_MaxNumInputChannels;
controlPortOffset += JucePlugin_MaxNumOutputChannels;

@@ -1119,6 +1105,7 @@ public:
uridMap (nullptr),
uridAtomBlank (0),
uridAtomObject (0),
uridAtomDouble (0),
uridAtomFloat (0),
uridAtomInt (0),
uridAtomLong (0),
@@ -1200,6 +1187,7 @@ public:

uridAtomBlank = uridMap->map(uridMap->handle, LV2_ATOM__Blank);
uridAtomObject = uridMap->map(uridMap->handle, LV2_ATOM__Object);
uridAtomDouble = uridMap->map(uridMap->handle, LV2_ATOM__Double);
uridAtomFloat = uridMap->map(uridMap->handle, LV2_ATOM__Float);
uridAtomInt = uridMap->map(uridMap->handle, LV2_ATOM__Int);
uridAtomLong = uridMap->map(uridMap->handle, LV2_ATOM__Long);
@@ -1413,59 +1401,140 @@ public:

LV2_Atom* bar = nullptr;
LV2_Atom* barBeat = nullptr;
LV2_Atom* beatsPerBar = nullptr;
LV2_Atom* bpm = nullptr;
LV2_Atom* beatUnit = nullptr;
LV2_Atom* beatsPerBar = nullptr;
LV2_Atom* beatsPerMinute = nullptr;
LV2_Atom* frame = nullptr;
LV2_Atom* speed = nullptr;

lv2_atom_object_get (obj,
uridTimeBar, &bar,
uridTimeBarBeat, &barBeat,
uridTimeBeatsPerBar, &beatsPerBar,
uridTimeBeatsPerMinute, &bpm,
uridTimeBeatUnit, &beatUnit,
uridTimeBeatsPerBar, &beatsPerBar,
uridTimeBeatsPerMinute, &beatsPerMinute,
uridTimeFrame, &frame,
uridTimeSpeed, &speed,
nullptr);

if (bpm != nullptr && bpm->type == uridAtomFloat)
curPosInfo.bpm = ((LV2_Atom_Float*)bpm)->body;
// need to handle this first as other values depend on it
if (speed != nullptr)
{
/**/ if (speed->type == uridAtomDouble)
lastPositionData.speed = ((LV2_Atom_Double*)speed)->body;
else if (speed->type == uridAtomFloat)
lastPositionData.speed = ((LV2_Atom_Float*)speed)->body;
else if (speed->type == uridAtomInt)
lastPositionData.speed = ((LV2_Atom_Int*)speed)->body;
else if (speed->type == uridAtomLong)
lastPositionData.speed = ((LV2_Atom_Long*)speed)->body;

curPosInfo.isPlaying = lastPositionData.speed != 0.0;
}

if (beatsPerBar != nullptr && beatsPerBar->type == uridAtomFloat)
if (bar != nullptr)
{
float beatsPerBarValue = ((LV2_Atom_Float*)beatsPerBar)->body;
curPosInfo.timeSigNumerator = beatsPerBarValue;
/**/ if (bar->type == uridAtomDouble)
lastPositionData.bar = ((LV2_Atom_Double*)bar)->body;
else if (bar->type == uridAtomFloat)
lastPositionData.bar = ((LV2_Atom_Float*)bar)->body;
else if (bar->type == uridAtomInt)
lastPositionData.bar = ((LV2_Atom_Int*)bar)->body;
else if (bar->type == uridAtomLong)
lastPositionData.bar = ((LV2_Atom_Long*)bar)->body;
}

if (bar != nullptr && bar->type == uridAtomLong)
{
float barValue = ((LV2_Atom_Long*)bar)->body;
curPosInfo.ppqPositionOfLastBarStart = barValue * beatsPerBarValue;

if (barBeat != nullptr && barBeat->type == uridAtomFloat)
{
float barBeatValue = ((LV2_Atom_Float*)barBeat)->body;
curPosInfo.ppqPosition = curPosInfo.ppqPositionOfLastBarStart + barBeatValue;
}
}
if (barBeat != nullptr)
{
/**/ if (barBeat->type == uridAtomDouble)
lastPositionData.barBeat = ((LV2_Atom_Double*)barBeat)->body;
else if (barBeat->type == uridAtomFloat)
lastPositionData.barBeat = ((LV2_Atom_Float*)barBeat)->body;
else if (barBeat->type == uridAtomInt)
lastPositionData.barBeat = ((LV2_Atom_Int*)barBeat)->body;
else if (barBeat->type == uridAtomLong)
lastPositionData.barBeat = ((LV2_Atom_Long*)barBeat)->body;
}

if (beatUnit != nullptr)
{
if (beatUnit->type == uridAtomInt)
curPosInfo.timeSigDenominator = ((LV2_Atom_Int*)beatUnit)->body;
/**/ if (beatUnit->type == uridAtomDouble)
lastPositionData.beatUnit = ((LV2_Atom_Double*)beatUnit)->body;
else if (beatUnit->type == uridAtomFloat)
curPosInfo.timeSigDenominator = ((LV2_Atom_Float*)beatUnit)->body;
lastPositionData.beatUnit = ((LV2_Atom_Float*)beatUnit)->body;
else if (beatUnit->type == uridAtomInt)
lastPositionData.beatUnit = ((LV2_Atom_Int*)beatUnit)->body;
else if (beatUnit->type == uridAtomLong)
lastPositionData.beatUnit = ((LV2_Atom_Long*)beatUnit)->body;

if (lastPositionData.beatUnit > 0)
curPosInfo.timeSigDenominator = lastPositionData.beatUnit;
}

if (beatsPerBar != nullptr)
{
/**/ if (beatsPerBar->type == uridAtomDouble)
lastPositionData.beatsPerBar = ((LV2_Atom_Double*)beatsPerBar)->body;
else if (beatsPerBar->type == uridAtomFloat)
lastPositionData.beatsPerBar = ((LV2_Atom_Float*)beatsPerBar)->body;
else if (beatsPerBar->type == uridAtomInt)
lastPositionData.beatsPerBar = ((LV2_Atom_Int*)beatsPerBar)->body;
else if (beatsPerBar->type == uridAtomLong)
lastPositionData.beatsPerBar = ((LV2_Atom_Long*)beatsPerBar)->body;

if (lastPositionData.beatsPerBar > 0.0f)
curPosInfo.timeSigNumerator = lastPositionData.beatsPerBar;
}

if (frame != nullptr && frame->type == uridAtomLong)
if (beatsPerMinute != nullptr)
{
curPosInfo.timeInSamples = ((LV2_Atom_Long*)frame)->body;
curPosInfo.timeInSeconds = double(curPosInfo.timeInSamples)/sampleRate;
/**/ if (beatsPerMinute->type == uridAtomDouble)
lastPositionData.beatsPerMinute = ((LV2_Atom_Double*)beatsPerMinute)->body;
else if (beatsPerMinute->type == uridAtomFloat)
lastPositionData.beatsPerMinute = ((LV2_Atom_Float*)beatsPerMinute)->body;
else if (beatsPerMinute->type == uridAtomInt)
lastPositionData.beatsPerMinute = ((LV2_Atom_Int*)beatsPerMinute)->body;
else if (beatsPerMinute->type == uridAtomLong)
lastPositionData.beatsPerMinute = ((LV2_Atom_Long*)beatsPerMinute)->body;

if (lastPositionData.beatsPerMinute > 0.0f)
{
curPosInfo.bpm = lastPositionData.beatsPerMinute;

if (lastPositionData.speed != 0)
curPosInfo.bpm *= std::abs(lastPositionData.speed);
}
}

if (speed != nullptr && speed->type == uridAtomFloat)
curPosInfo.isPlaying = ((LV2_Atom_Float*)speed)->body == 1.0f;
if (frame != nullptr)
{
/**/ if (frame->type == uridAtomDouble)
lastPositionData.frame = ((LV2_Atom_Double*)frame)->body;
else if (frame->type == uridAtomFloat)
lastPositionData.frame = ((LV2_Atom_Float*)frame)->body;
else if (frame->type == uridAtomInt)
lastPositionData.frame = ((LV2_Atom_Int*)frame)->body;
else if (frame->type == uridAtomLong)
lastPositionData.frame = ((LV2_Atom_Long*)frame)->body;

if (lastPositionData.frame >= 0)
{
curPosInfo.timeInSamples = lastPositionData.frame;
curPosInfo.timeInSeconds = double(curPosInfo.timeInSamples)/sampleRate;
}
}

if (lastPositionData.bar >= 0 && lastPositionData.beatsPerBar > 0.0f)
{
curPosInfo.ppqPositionOfLastBarStart = lastPositionData.bar * lastPositionData.beatsPerBar;

if (lastPositionData.barBeat >= 0.0f)
curPosInfo.ppqPosition = curPosInfo.ppqPositionOfLastBarStart + lastPositionData.barBeat;
}

lastPositionData.extraValid = (lastPositionData.beatsPerMinute > 0.0 &&
lastPositionData.beatUnit > 0 &&
lastPositionData.beatsPerBar > 0.0f);
}
#endif
}
@@ -1478,6 +1547,52 @@ public:
}
}

#if JucePlugin_WantsLV2TimePos
// update timePos for next callback
if (lastPositionData.speed != 0.0)
{
if (lastPositionData.speed > 0.0)
{
// playing forwards
lastPositionData.frame += sampleCount;
}
else
{
// playing backwards
lastPositionData.frame -= sampleCount;

if (lastPositionData.frame < 0)
lastPositionData.frame = 0;
}

curPosInfo.timeInSamples = lastPositionData.frame;
curPosInfo.timeInSeconds = double(curPosInfo.timeInSamples)/sampleRate;

if (lastPositionData.extraValid)
{
const double beatsPerMinute = lastPositionData.beatsPerMinute * lastPositionData.speed;
const double framesPerBeat = 60.0 * sampleRate / beatsPerMinute;
const double addedBarBeats = double(sampleCount) / framesPerBeat;

if (lastPositionData.bar >= 0 && lastPositionData.barBeat >= 0.0f)
{
lastPositionData.bar += std::floor((lastPositionData.barBeat+addedBarBeats)/
lastPositionData.beatsPerBar);
lastPositionData.barBeat = std::fmod(lastPositionData.barBeat+addedBarBeats,
lastPositionData.beatsPerBar);

if (lastPositionData.bar < 0)
lastPositionData.bar = 0;

curPosInfo.ppqPositionOfLastBarStart = lastPositionData.bar * lastPositionData.beatsPerBar;
curPosInfo.ppqPosition = curPosInfo.ppqPositionOfLastBarStart + lastPositionData.barBeat;
}

curPosInfo.bpm = std::abs(beatsPerMinute);
}
}
#endif

if (! midiEvents.isEmpty())
{
#if JucePlugin_ProducesMidiOutput
@@ -1725,9 +1840,32 @@ private:
Array<float> lastControlValues;
AudioPlayHead::CurrentPositionInfo curPosInfo;

struct Lv2PositionData {
int64_t bar;
float barBeat;
uint32_t beatUnit;
float beatsPerBar;
float beatsPerMinute;
int64_t frame;
double speed;
bool extraValid;

Lv2PositionData()
: bar(-1),
barBeat(-1.0f),
beatUnit(0),
beatsPerBar(0.0f),
beatsPerMinute(0.0f),
frame(-1),
speed(0.0),
extraValid(false) {}
};
Lv2PositionData lastPositionData;

const LV2_URID_Map* uridMap;
LV2_URID uridAtomBlank;
LV2_URID uridAtomObject;
LV2_URID uridAtomDouble;
LV2_URID uridAtomFloat;
LV2_URID uridAtomInt;
LV2_URID uridAtomLong;


+ 1
- 1
libs/juce/source/modules/juce_audio_plugin_client/utility/juce_IncludeModuleHeaders.h View File

@@ -31,7 +31,7 @@ using namespace juce;
namespace juce
{
#if JUCE_MAC && ! DOXYGEN
#if JUCE_MAC
#define Point juce::Point
#define Component juce::Component


+ 10
- 0
libs/juce/source/modules/juce_core/memory/juce_ContainerDeletePolicy.h View File

@@ -45,6 +45,16 @@ struct ContainerDeletePolicy
{
static void destroy (ObjectType* object)
{
// If the line below triggers a compiler error, it means that you are using
// an incomplete type for ObjectType (for example, a type that is declared
// but not defined). This is a problem because then the following delete is
// undefined behaviour. The purpose of the sizeof is to capture this situation.
// If this was caused by a ScopedPointer to a forward-declared type, move the
// implementation of all methods trying to use the ScopedPointer (e.g. the destructor
// of the class owning it) into cpp files where they can see to the definition
// of ObjectType. This should fix the error.
ignoreUnused (sizeof (ObjectType));
delete object;
}
};


+ 66
- 53
libs/juce/source/modules/juce_graphics/geometry/juce_Rectangle.h View File

@@ -52,21 +52,21 @@ public:
}
/** Creates a rectangle with a given position and size. */
Rectangle (const ValueType initialX, const ValueType initialY,
const ValueType width, const ValueType height) noexcept
Rectangle (ValueType initialX, ValueType initialY,
ValueType width, ValueType height) noexcept
: pos (initialX, initialY),
w (width), h (height)
{
}
/** Creates a rectangle with a given size, and a position of (0, 0). */
Rectangle (const ValueType width, const ValueType height) noexcept
Rectangle (ValueType width, ValueType height) noexcept
: w (width), h (height)
{
}
/** Creates a Rectangle from the positions of two opposite corners. */
Rectangle (const Point<ValueType> corner1, const Point<ValueType> corner2) noexcept
Rectangle (Point<ValueType> corner1, Point<ValueType> corner2) noexcept
: pos (jmin (corner1.x, corner2.x),
jmin (corner1.y, corner2.y)),
w (corner1.x - corner2.x),
@@ -80,8 +80,8 @@ public:
The right and bottom values must be larger than the left and top ones, or the resulting
rectangle will have a negative size.
*/
static Rectangle leftTopRightBottom (const ValueType left, const ValueType top,
const ValueType right, const ValueType bottom) noexcept
static Rectangle leftTopRightBottom (ValueType left, ValueType top,
ValueType right, ValueType bottom) noexcept
{
return Rectangle (left, top, right - left, bottom - top);
}
@@ -134,17 +134,17 @@ public:
/** Returns the aspect ratio of the rectangle's width / height.
If widthOverHeight is true, it returns width / height; if widthOverHeight is false,
it returns height / width. */
ValueType getAspectRatio (const bool widthOverHeight = true) const noexcept { return widthOverHeight ? w / h : h / w; }
ValueType getAspectRatio (bool widthOverHeight = true) const noexcept { return widthOverHeight ? w / h : h / w; }
//==============================================================================
/** Returns the rectangle's top-left position as a Point. */
inline Point<ValueType> getPosition() const noexcept { return pos; }
/** Changes the position of the rectangle's top-left corner (leaving its size unchanged). */
inline void setPosition (const Point<ValueType> newPos) noexcept { pos = newPos; }
inline void setPosition (Point<ValueType> newPos) noexcept { pos = newPos; }
/** Changes the position of the rectangle's top-left corner (leaving its size unchanged). */
inline void setPosition (const ValueType newX, const ValueType newY) noexcept { pos.setXY (newX, newY); }
inline void setPosition (ValueType newX, ValueType newY) noexcept { pos.setXY (newX, newY); }
/** Returns the rectangle's top-left position as a Point. */
Point<ValueType> getTopLeft() const noexcept { return pos; }
@@ -158,62 +158,75 @@ public:
/** Returns the rectangle's bottom-right position as a Point. */
Point<ValueType> getBottomRight() const noexcept { return Point<ValueType> (pos.x + w, pos.y + h); }
/** Returns the rectangle's left and right positions as a Range. */
Range<ValueType> getHorizontalRange() const noexcept { return Range<ValueType>::withStartAndLength (pos.x, w); }
/** Returns the rectangle's top and bottom positions as a Range. */
Range<ValueType> getVerticalRange() const noexcept { return Range<ValueType>::withStartAndLength (pos.y, h); }
/** Changes the rectangle's size, leaving the position of its top-left corner unchanged. */
void setSize (const ValueType newWidth, const ValueType newHeight) noexcept { w = newWidth; h = newHeight; }
void setSize (ValueType newWidth, ValueType newHeight) noexcept { w = newWidth; h = newHeight; }
/** Changes all the rectangle's coordinates. */
void setBounds (const ValueType newX, const ValueType newY,
const ValueType newWidth, const ValueType newHeight) noexcept { pos.x = newX; pos.y = newY; w = newWidth; h = newHeight; }
void setBounds (ValueType newX, ValueType newY,
ValueType newWidth, ValueType newHeight) noexcept { pos.x = newX; pos.y = newY; w = newWidth; h = newHeight; }
/** Changes the rectangle's X coordinate */
inline void setX (const ValueType newX) noexcept { pos.x = newX; }
inline void setX (ValueType newX) noexcept { pos.x = newX; }
/** Changes the rectangle's Y coordinate */
inline void setY (const ValueType newY) noexcept { pos.y = newY; }
inline void setY (ValueType newY) noexcept { pos.y = newY; }
/** Changes the rectangle's width */
inline void setWidth (const ValueType newWidth) noexcept { w = newWidth; }
inline void setWidth (ValueType newWidth) noexcept { w = newWidth; }
/** Changes the rectangle's height */
inline void setHeight (const ValueType newHeight) noexcept { h = newHeight; }
inline void setHeight (ValueType newHeight) noexcept { h = newHeight; }
/** Changes the position of the rectangle's centre (leaving its size unchanged). */
inline void setCentre (const ValueType newCentreX, const ValueType newCentreY) noexcept { pos.x = newCentreX - w / (ValueType) 2; pos.y = newCentreY - h / (ValueType) 2; }
inline void setCentre (ValueType newCentreX, ValueType newCentreY) noexcept { pos.x = newCentreX - w / (ValueType) 2;
pos.y = newCentreY - h / (ValueType) 2; }
/** Changes the position of the rectangle's centre (leaving its size unchanged). */
inline void setCentre (const Point<ValueType> newCentre) noexcept { setCentre (newCentre.x, newCentre.y); }
inline void setCentre (Point<ValueType> newCentre) noexcept { setCentre (newCentre.x, newCentre.y); }
/** Changes the position of the rectangle's left and right edges. */
void setHorizontalRange (Range<ValueType> range) noexcept { pos.x = range.getStart(); w = range.getLength(); }
/** Changes the position of the rectangle's top and bottom edges. */
void setVerticalRange (Range<ValueType> range) noexcept { pos.y = range.getStart(); h = range.getLength(); }
/** Returns a rectangle which has the same size and y-position as this one, but with a different x-position. */
Rectangle withX (const ValueType newX) const noexcept { return Rectangle (newX, pos.y, w, h); }
Rectangle withX (ValueType newX) const noexcept { return Rectangle (newX, pos.y, w, h); }
/** Returns a rectangle which has the same size and x-position as this one, but with a different y-position. */
Rectangle withY (const ValueType newY) const noexcept { return Rectangle (pos.x, newY, w, h); }
Rectangle withY (ValueType newY) const noexcept { return Rectangle (pos.x, newY, w, h); }
/** Returns a rectangle with the same size as this one, but a new position. */
Rectangle withPosition (const ValueType newX, const ValueType newY) const noexcept { return Rectangle (newX, newY, w, h); }
Rectangle withPosition (ValueType newX, ValueType newY) const noexcept { return Rectangle (newX, newY, w, h); }
/** Returns a rectangle with the same size as this one, but a new position. */
Rectangle withPosition (const Point<ValueType> newPos) const noexcept { return Rectangle (newPos.x, newPos.y, w, h); }
Rectangle withPosition (Point<ValueType> newPos) const noexcept { return Rectangle (newPos.x, newPos.y, w, h); }
/** Returns a rectangle whose size is the same as this one, but whose top-left position is (0, 0). */
Rectangle withZeroOrigin() const noexcept { return Rectangle (w, h); }
Rectangle withZeroOrigin() const noexcept { return Rectangle (w, h); }
/** Returns a rectangle with the same size as this one, but a new centre position. */
Rectangle withCentre (const Point<ValueType> newCentre) const noexcept { return Rectangle (newCentre.x - w / (ValueType) 2,
newCentre.y - h / (ValueType) 2, w, h); }
Rectangle withCentre (Point<ValueType> newCentre) const noexcept { return Rectangle (newCentre.x - w / (ValueType) 2,
newCentre.y - h / (ValueType) 2, w, h); }
/** Returns a rectangle which has the same position and height as this one, but with a different width. */
Rectangle withWidth (ValueType newWidth) const noexcept { return Rectangle (pos.x, pos.y, newWidth, h); }
Rectangle withWidth (ValueType newWidth) const noexcept { return Rectangle (pos.x, pos.y, newWidth, h); }
/** Returns a rectangle which has the same position and width as this one, but with a different height. */
Rectangle withHeight (ValueType newHeight) const noexcept { return Rectangle (pos.x, pos.y, w, newHeight); }
Rectangle withHeight (ValueType newHeight) const noexcept { return Rectangle (pos.x, pos.y, w, newHeight); }
/** Returns a rectangle with the same top-left position as this one, but a new size. */
Rectangle withSize (ValueType newWidth, ValueType newHeight) const noexcept { return Rectangle (pos.x, pos.y, newWidth, newHeight); }
Rectangle withSize (ValueType newWidth, ValueType newHeight) const noexcept { return Rectangle (pos.x, pos.y, newWidth, newHeight); }
/** Returns a rectangle with the same centre position as this one, but a new size. */
Rectangle withSizeKeepingCentre (ValueType newWidth, ValueType newHeight) const noexcept { return Rectangle (pos.x + (w - newWidth) / (ValueType) 2,
pos.y + (h - newHeight) / (ValueType) 2, newWidth, newHeight); }
Rectangle withSizeKeepingCentre (ValueType newWidth, ValueType newHeight) const noexcept { return Rectangle (pos.x + (w - newWidth) / (ValueType) 2,
pos.y + (h - newHeight) / (ValueType) 2, newWidth, newHeight); }
/** Moves the x position, adjusting the width so that the right-hand edge remains in the same place.
If the x is moved to be on the right of the current right-hand edge, the width will be set to zero.
@@ -277,41 +290,41 @@ public:
//==============================================================================
/** Moves the rectangle's position by adding amount to its x and y coordinates. */
void translate (const ValueType deltaX,
const ValueType deltaY) noexcept
void translate (ValueType deltaX,
ValueType deltaY) noexcept
{
pos.x += deltaX;
pos.y += deltaY;
}
/** Returns a rectangle which is the same as this one moved by a given amount. */
Rectangle translated (const ValueType deltaX,
const ValueType deltaY) const noexcept
Rectangle translated (ValueType deltaX,
ValueType deltaY) const noexcept
{
return Rectangle (pos.x + deltaX, pos.y + deltaY, w, h);
}
/** Returns a rectangle which is the same as this one moved by a given amount. */
Rectangle operator+ (const Point<ValueType> deltaPosition) const noexcept
Rectangle operator+ (Point<ValueType> deltaPosition) const noexcept
{
return Rectangle (pos.x + deltaPosition.x, pos.y + deltaPosition.y, w, h);
}
/** Moves this rectangle by a given amount. */
Rectangle& operator+= (const Point<ValueType> deltaPosition) noexcept
Rectangle& operator+= (Point<ValueType> deltaPosition) noexcept
{
pos += deltaPosition;
return *this;
}
/** Returns a rectangle which is the same as this one moved by a given amount. */
Rectangle operator- (const Point<ValueType> deltaPosition) const noexcept
Rectangle operator- (Point<ValueType> deltaPosition) const noexcept
{
return Rectangle (pos.x - deltaPosition.x, pos.y - deltaPosition.y, w, h);
}
/** Moves this rectangle by a given amount. */
Rectangle& operator-= (const Point<ValueType> deltaPosition) noexcept
Rectangle& operator-= (Point<ValueType> deltaPosition) noexcept
{
pos -= deltaPosition;
return *this;
@@ -396,8 +409,8 @@ public:
Effectively, its new size is (x - deltaX, y - deltaY, w + deltaX * 2, h + deltaY * 2).
@see expanded, reduce, reduced
*/
void expand (const ValueType deltaX,
const ValueType deltaY) noexcept
void expand (ValueType deltaX,
ValueType deltaY) noexcept
{
const ValueType nw = jmax (ValueType(), w + deltaX * 2);
const ValueType nh = jmax (ValueType(), h + deltaY * 2);
@@ -409,8 +422,8 @@ public:
Effectively, the rectangle returned is (x - deltaX, y - deltaY, w + deltaX * 2, h + deltaY * 2).
@see expand, reduce, reduced
*/
Rectangle expanded (const ValueType deltaX,
const ValueType deltaY) const noexcept
Rectangle expanded (ValueType deltaX,
ValueType deltaY) const noexcept
{
const ValueType nw = jmax (ValueType(), w + deltaX * 2);
const ValueType nh = jmax (ValueType(), h + deltaY * 2);
@@ -422,7 +435,7 @@ public:
Effectively, the rectangle returned is (x - delta, y - delta, w + delta * 2, h + delta * 2).
@see expand, reduce, reduced
*/
Rectangle expanded (const ValueType delta) const noexcept
Rectangle expanded (ValueType delta) const noexcept
{
return expanded (delta, delta);
}
@@ -432,8 +445,8 @@ public:
Effectively, its new size is (x + deltaX, y + deltaY, w - deltaX * 2, h - deltaY * 2).
@see reduced, expand, expanded
*/
void reduce (const ValueType deltaX,
const ValueType deltaY) noexcept
void reduce (ValueType deltaX,
ValueType deltaY) noexcept
{
expand (-deltaX, -deltaY);
}
@@ -443,8 +456,8 @@ public:
Effectively, the rectangle returned is (x + deltaX, y + deltaY, w - deltaX * 2, h - deltaY * 2).
@see reduce, expand, expanded
*/
Rectangle reduced (const ValueType deltaX,
const ValueType deltaY) const noexcept
Rectangle reduced (ValueType deltaX,
ValueType deltaY) const noexcept
{
return expanded (-deltaX, -deltaY);
}
@@ -454,7 +467,7 @@ public:
Effectively, the rectangle returned is (x + delta, y + delta, w - delta * 2, h - delta * 2).
@see reduce, expand, expanded
*/
Rectangle reduced (const ValueType delta) const noexcept
Rectangle reduced (ValueType delta) const noexcept
{
return reduced (delta, delta);
}
@@ -468,7 +481,7 @@ public:
If amountToRemove is greater than the height of this rectangle, it'll be clipped to
that value.
*/
Rectangle removeFromTop (const ValueType amountToRemove) noexcept
Rectangle removeFromTop (ValueType amountToRemove) noexcept
{
const Rectangle r (pos.x, pos.y, w, jmin (amountToRemove, h));
pos.y += r.h; h -= r.h;
@@ -484,7 +497,7 @@ public:
If amountToRemove is greater than the width of this rectangle, it'll be clipped to
that value.
*/
Rectangle removeFromLeft (const ValueType amountToRemove) noexcept
Rectangle removeFromLeft (ValueType amountToRemove) noexcept
{
const Rectangle r (pos.x, pos.y, jmin (amountToRemove, w), h);
pos.x += r.w; w -= r.w;
@@ -533,13 +546,13 @@ public:
bool operator!= (const Rectangle& other) const noexcept { return pos != other.pos || w != other.w || h != other.h; }
/** Returns true if this coordinate is inside the rectangle. */
bool contains (const ValueType xCoord, const ValueType yCoord) const noexcept
bool contains (ValueType xCoord, ValueType yCoord) const noexcept
{
return xCoord >= pos.x && yCoord >= pos.y && xCoord < pos.x + w && yCoord < pos.y + h;
}
/** Returns true if this coordinate is inside the rectangle. */
bool contains (const Point<ValueType> point) const noexcept
bool contains (Point<ValueType> point) const noexcept
{
return point.x >= pos.x && point.y >= pos.y && point.x < pos.x + w && point.y < pos.y + h;
}
@@ -552,7 +565,7 @@ public:
}
/** Returns the nearest point to the specified point that lies within this rectangle. */
Point<ValueType> getConstrainedPoint (const Point<ValueType> point) const noexcept
Point<ValueType> getConstrainedPoint (Point<ValueType> point) const noexcept
{
return Point<ValueType> (jlimit (pos.x, pos.x + w, point.x),
jlimit (pos.y, pos.y + h, point.y));


+ 1
- 0
libs/juce/source/modules/juce_gui_basics/buttons/juce_DrawableButton.cpp View File

@@ -59,6 +59,7 @@ void DrawableButton::setImages (const Drawable* normal,
overImageOn = copyDrawableIfNotNull (overOn);
downImageOn = copyDrawableIfNotNull (downOn);
disabledImageOn = copyDrawableIfNotNull (disabledOn);
currentImage = nullptr;
buttonStateChanged();
}


+ 19
- 1
libs/juce/source/modules/juce_gui_basics/mouse/juce_DragAndDropContainer.cpp View File

@@ -43,7 +43,7 @@ public:
imageOffset (offset),
hasCheckedForExternalDrag (false)
{
setSize (im.getWidth(), im.getHeight());
updateSize();
if (mouseDragSource == nullptr)
mouseDragSource = sourceComponent;
@@ -160,6 +160,13 @@ public:
forceMouseCursorUpdate();
}
void updateImage (const Image& newImage)
{
image = newImage;
updateSize();
repaint();
}
void timerCallback() override
{
forceMouseCursorUpdate();
@@ -207,6 +214,11 @@ private:
bool hasCheckedForExternalDrag;
Time lastTimeOverTarget;
void updateSize()
{
setSize (image.getWidth(), image.getHeight());
}
void forceMouseCursorUpdate()
{
Desktop::getInstance().getMainMouseSource().forceMouseCursorUpdate();
@@ -472,6 +484,12 @@ var DragAndDropContainer::getCurrentDragDescription() const
: var();
}
void DragAndDropContainer::setCurrentDragImage (const Image& newImage)
{
if (dragImageComponent != nullptr)
dragImageComponent->updateImage (newImage);
}
DragAndDropContainer* DragAndDropContainer::findParentDragContainerFor (Component* c)
{
return c != nullptr ? c->findParentComponentOfClass<DragAndDropContainer>() : nullptr;


+ 3
- 0
libs/juce/source/modules/juce_gui_basics/mouse/juce_DragAndDropContainer.h View File

@@ -102,6 +102,9 @@ public:
*/
var getCurrentDragDescription() const;
/** If a drag is in progress, this allows the image being shown to be dynamically updated. */
void setCurrentDragImage (const Image& newImage);
/** Utility to find the DragAndDropContainer for a given Component.
This will search up this component's parent hierarchy looking for the first


+ 47
- 23
libs/juce/source/modules/juce_gui_basics/native/juce_mac_MouseCursor.mm View File

@@ -50,34 +50,57 @@ namespace MouseCursorHelpers
}
}
static void* fromWebKitFile (const char* filename, float hx, float hy)
static NSCursor* fromNSImage (NSImage* im, NSPoint hotspot)
{
FileInputStream fileStream (File ("/System/Library/Frameworks/WebKit.framework/Frameworks/WebCore.framework/Resources")
.getChildFile (filename));
NSCursor* c = [[NSCursor alloc] initWithImage: im
hotSpot: hotspot];
[im release];
return c;
}
if (fileStream.openedOk())
static void* fromHIServices (const char* filename)
{
JUCE_AUTORELEASEPOOL
{
BufferedInputStream buf (fileStream, 4096);
const String cursorPath (String ("/System/Library/Frameworks/ApplicationServices.framework/Versions/A/Frameworks/"
"HIServices.framework/Versions/A/Resources/cursors/")
+ filename);
PNGImageFormat pngFormat;
Image im (pngFormat.decodeImage (buf));
NSImage* originalImage = [[NSImage alloc] initByReferencingFile: juceStringToNS (cursorPath + "/cursor.pdf")];
NSSize originalSize = [originalImage size];
NSImage* resultImage = [[NSImage alloc] initWithSize: originalSize];
if (im.isValid())
return CustomMouseCursorInfo (im, (int) (hx * im.getWidth()),
(int) (hy * im.getHeight())).create();
}
for (int scale = 1; scale <= 4; ++scale)
{
NSAffineTransform* scaleTransform = [NSAffineTransform transform];
[scaleTransform scaleBy: (float) scale];
CGImageRef rasterCGImage = [originalImage CGImageForProposedRect: nil
context: nil
hints: [NSDictionary dictionaryWithObjectsAndKeys:
NSImageHintCTM, scaleTransform, nil]];
return nullptr;
NSBitmapImageRep* imageRep = [[NSBitmapImageRep alloc] initWithCGImage: rasterCGImage];
[imageRep setSize: originalSize];
[resultImage addRepresentation: imageRep];
[imageRep release];
}
NSDictionary* info = [NSDictionary dictionaryWithContentsOfFile: juceStringToNS (cursorPath + "/info.plist")];
const float hotspotX = (float) [[info valueForKey: nsStringLiteral ("hotx")] doubleValue];
const float hotspotY = (float) [[info valueForKey: nsStringLiteral ("hoty")] doubleValue];
return fromNSImage (resultImage, NSMakePoint (hotspotX, hotspotY));
}
}
}
void* CustomMouseCursorInfo::create() const
{
NSImage* im = MouseCursorHelpers::createNSImage (image);
NSCursor* c = [[NSCursor alloc] initWithImage: im
hotSpot: NSMakePoint (hotspot.x, hotspot.y)];
[im release];
return c;
return MouseCursorHelpers::fromNSImage (MouseCursorHelpers::createNSImage (image),
NSMakePoint (hotspot.x, hotspot.y));
}
void* MouseCursor::createStandardMouseCursor (MouseCursor::StandardCursorType type)
@@ -102,9 +125,10 @@ void* MouseCursor::createStandardMouseCursor (MouseCursor::StandardCursorType ty
case CopyingCursor:
{
#if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_6
if (void* m = MouseCursorHelpers::fromWebKitFile ("copyCursor.png", 0, 0))
if (void* m = MouseCursorHelpers::fromHIServices ("copy"))
return m;
#endif
c = [NSCursor dragCopyCursor]; // added in 10.6
break;
}
@@ -112,10 +136,10 @@ void* MouseCursor::createStandardMouseCursor (MouseCursor::StandardCursorType ty
case UpDownResizeCursor:
case TopEdgeResizeCursor:
case BottomEdgeResizeCursor:
return MouseCursorHelpers::fromWebKitFile ("northSouthResizeCursor.png", 0.5f, 0.5f);
return MouseCursorHelpers::fromHIServices ("resizenorthsouth");
case LeftRightResizeCursor:
if (void* m = MouseCursorHelpers::fromWebKitFile ("eastWestResizeCursor.png", 0.5f, 0.5f))
if (void* m = MouseCursorHelpers::fromHIServices ("resizeeastwest"))
return m;
c = [NSCursor resizeLeftRightCursor];
@@ -123,14 +147,14 @@ void* MouseCursor::createStandardMouseCursor (MouseCursor::StandardCursorType ty
case TopLeftCornerResizeCursor:
case BottomRightCornerResizeCursor:
return MouseCursorHelpers::fromWebKitFile ("northWestSouthEastResizeCursor.png", 0.5f, 0.5f);
return MouseCursorHelpers::fromHIServices ("resizenorthwestsoutheast");
case TopRightCornerResizeCursor:
case BottomLeftCornerResizeCursor:
return MouseCursorHelpers::fromWebKitFile ("northEastSouthWestResizeCursor.png", 0.5f, 0.5f);
return MouseCursorHelpers::fromHIServices ("resizenortheastsouthwest");
case UpDownLeftRightResizeCursor:
return MouseCursorHelpers::fromWebKitFile ("moveCursor.png", 0.5f, 0.5f);
return MouseCursorHelpers::fromHIServices ("move");
default:
jassertfalse;


+ 21
- 18
libs/juce/source/modules/juce_gui_basics/native/juce_win32_Windowing.cpp View File

@@ -2968,24 +2968,27 @@ bool KeyPress::isKeyCurrentlyDown (const int keyCode)
{
SHORT k = (SHORT) keyCode;
if ((keyCode & extendedKeyModifier) == 0
&& (k >= (SHORT) 'a' && k <= (SHORT) 'z'))
k += (SHORT) 'A' - (SHORT) 'a';
const SHORT translatedValues[] = { (SHORT) ',', VK_OEM_COMMA,
(SHORT) '+', VK_OEM_PLUS,
(SHORT) '-', VK_OEM_MINUS,
(SHORT) '.', VK_OEM_PERIOD,
(SHORT) ';', VK_OEM_1,
(SHORT) ':', VK_OEM_1,
(SHORT) '/', VK_OEM_2,
(SHORT) '?', VK_OEM_2,
(SHORT) '[', VK_OEM_4,
(SHORT) ']', VK_OEM_6 };
for (int i = 0; i < numElementsInArray (translatedValues); i += 2)
if (k == translatedValues [i])
k = translatedValues [i + 1];
if ((keyCode & extendedKeyModifier) == 0)
{
if (k >= (SHORT) 'a' && k <= (SHORT) 'z')
k += (SHORT) 'A' - (SHORT) 'a';
// Only translate if extendedKeyModifier flag is not set
const SHORT translatedValues[] = { (SHORT) ',', VK_OEM_COMMA,
(SHORT) '+', VK_OEM_PLUS,
(SHORT) '-', VK_OEM_MINUS,
(SHORT) '.', VK_OEM_PERIOD,
(SHORT) ';', VK_OEM_1,
(SHORT) ':', VK_OEM_1,
(SHORT) '/', VK_OEM_2,
(SHORT) '?', VK_OEM_2,
(SHORT) '[', VK_OEM_4,
(SHORT) ']', VK_OEM_6 };
for (int i = 0; i < numElementsInArray (translatedValues); i += 2)
if (k == translatedValues [i])
k = translatedValues [i + 1];
}
return HWNDComponentPeer::isKeyDown (k);
}


Loading…
Cancel
Save