Browse Source

Added display rotation support for iOS - see the Desktop class for implementation methods. Also fixed a couple of minor build issues.

tags/2021-05-28
Julian Storer 15 years ago
parent
commit
4bc85a9dc3
22 changed files with 776 additions and 283 deletions
  1. +1
    -1
      extras/juce demo/Source/ApplicationStartup.cpp
  2. +313
    -135
      juce_amalgamated.cpp
  3. +73
    -5
      juce_amalgamated.h
  4. +1
    -0
      src/audio/audio_file_formats/juce_QuickTimeAudioFormat.cpp
  5. +3
    -0
      src/audio/dsp/juce_AudioDataConverters.h
  6. +48
    -48
      src/containers/juce_BigInteger.cpp
  7. +7
    -4
      src/containers/juce_BigInteger.h
  8. +3
    -0
      src/core/juce_Atomic.h
  9. +1
    -1
      src/core/juce_StandardHeader.h
  10. +19
    -1
      src/gui/components/juce_Desktop.cpp
  11. +32
    -0
      src/gui/components/juce_Desktop.h
  12. +6
    -4
      src/gui/components/windows/juce_CallOutBox.cpp
  13. +1
    -1
      src/gui/components/windows/juce_ResizableWindow.cpp
  14. +18
    -0
      src/native/juce_mac_NativeCode.mm
  15. +7
    -3
      src/native/linux/juce_linux_Windowing.cpp
  16. +0
    -16
      src/native/mac/juce_iphone_MiscUtilities.mm
  17. +182
    -54
      src/native/mac/juce_iphone_UIViewComponentPeer.mm
  18. +8
    -4
      src/native/mac/juce_mac_MiscUtilities.mm
  19. +3
    -6
      src/native/mac/juce_mac_NSViewComponentPeer.mm
  20. +5
    -0
      src/native/windows/juce_win32_Windowing.cpp
  21. +16
    -0
      src/utilities/juce_UnitTest.cpp
  22. +29
    -0
      src/utilities/juce_UnitTest.h

+ 1
- 1
extras/juce demo/Source/ApplicationStartup.cpp View File

@@ -45,7 +45,7 @@ public:
{ {
#if JUCE_IPHONE #if JUCE_IPHONE
theMainWindow.setVisible (true); theMainWindow.setVisible (true);
theMainWindow.setBounds (0, 20, 320, 460);
theMainWindow.setFullScreen (true);
#else #else
theMainWindow.centreWithSize (700, 600); theMainWindow.centreWithSize (700, 600);
theMainWindow.setVisible (true); theMainWindow.setVisible (true);


+ 313
- 135
juce_amalgamated.cpp View File

@@ -2531,7 +2531,7 @@ BigInteger::BigInteger()
values.calloc (numValues + 1); values.calloc (numValues + 1);
} }


BigInteger::BigInteger (const int value)
BigInteger::BigInteger (const int32 value)
: numValues (4), : numValues (4),
highestBit (31), highestBit (31),
negative (value < 0) negative (value < 0)
@@ -2541,6 +2541,16 @@ BigInteger::BigInteger (const int value)
highestBit = getHighestBit(); highestBit = getHighestBit();
} }


BigInteger::BigInteger (const uint32 value)
: numValues (4),
highestBit (31),
negative (false)
{
values.calloc (numValues + 1);
values[0] = value;
highestBit = getHighestBit();
}

BigInteger::BigInteger (int64 value) BigInteger::BigInteger (int64 value)
: numValues (4), : numValues (4),
highestBit (63), highestBit (63),
@@ -2551,28 +2561,18 @@ BigInteger::BigInteger (int64 value)
if (value < 0) if (value < 0)
value = -value; value = -value;


values[0] = (unsigned int) value;
values[1] = (unsigned int) (value >> 32);
highestBit = getHighestBit();
}

BigInteger::BigInteger (const unsigned int value)
: numValues (4),
highestBit (31),
negative (false)
{
values.calloc (numValues + 1);
values[0] = value;
values[0] = (uint32) value;
values[1] = (uint32) (value >> 32);
highestBit = getHighestBit(); highestBit = getHighestBit();
} }


BigInteger::BigInteger (const BigInteger& other) BigInteger::BigInteger (const BigInteger& other)
: numValues (jmax (4, (other.highestBit >> 5) + 1)),
: numValues (jmax (4, bitToIndex (other.highestBit) + 1)),
highestBit (other.getHighestBit()), highestBit (other.getHighestBit()),
negative (other.negative) negative (other.negative)
{ {
values.malloc (numValues + 1); values.malloc (numValues + 1);
memcpy (values, other.values, sizeof (unsigned int) * (numValues + 1));
memcpy (values, other.values, sizeof (uint32) * (numValues + 1));
} }


BigInteger::~BigInteger() BigInteger::~BigInteger()
@@ -2592,10 +2592,10 @@ BigInteger& BigInteger::operator= (const BigInteger& other)
if (this != &other) if (this != &other)
{ {
highestBit = other.getHighestBit(); highestBit = other.getHighestBit();
numValues = jmax (4, (highestBit >> 5) + 1);
numValues = jmax (4, bitToIndex (highestBit) + 1);
negative = other.negative; negative = other.negative;
values.malloc (numValues + 1); values.malloc (numValues + 1);
memcpy (values, other.values, sizeof (unsigned int) * (numValues + 1));
memcpy (values, other.values, sizeof (uint32) * (numValues + 1));
} }


return *this; return *this;
@@ -2617,7 +2617,7 @@ void BigInteger::ensureSize (const int numVals)
bool BigInteger::operator[] (const int bit) const throw() bool BigInteger::operator[] (const int bit) const throw()
{ {
return bit <= highestBit && bit >= 0 return bit <= highestBit && bit >= 0
&& ((values [bit >> 5] & (1 << (bit & 31))) != 0);
&& ((values [bitToIndex (bit)] & bitToMask (bit)) != 0);
} }


int BigInteger::toInteger() const throw() int BigInteger::toInteger() const throw()
@@ -2630,7 +2630,7 @@ const BigInteger BigInteger::getBitRange (int startBit, int numBits) const
{ {
BigInteger r; BigInteger r;
numBits = jmin (numBits, getHighestBit() + 1 - startBit); numBits = jmin (numBits, getHighestBit() + 1 - startBit);
r.ensureSize (numBits >> 5);
r.ensureSize (bitToIndex (numBits));
r.highestBit = numBits; r.highestBit = numBits;


int i = 0; int i = 0;
@@ -2658,7 +2658,7 @@ int BigInteger::getBitRangeAsInt (const int startBit, int numBits) const throw()
if (numBits <= 0) if (numBits <= 0)
return 0; return 0;


const int pos = startBit >> 5;
const int pos = bitToIndex (startBit);
const int offset = startBit & 31; const int offset = startBit & 31;
const int endSpace = 32 - numBits; const int endSpace = 32 - numBits;


@@ -2670,7 +2670,7 @@ int BigInteger::getBitRangeAsInt (const int startBit, int numBits) const throw()
return (int) (n & (((uint32) 0xffffffff) >> endSpace)); return (int) (n & (((uint32) 0xffffffff) >> endSpace));
} }


void BigInteger::setBitRangeAsInt (const int startBit, int numBits, unsigned int valueToSet)
void BigInteger::setBitRangeAsInt (const int startBit, int numBits, uint32 valueToSet)
{ {
if (numBits > 32) if (numBits > 32)
{ {
@@ -2694,7 +2694,7 @@ void BigInteger::clear()
} }
else else
{ {
zeromem (values, sizeof (unsigned int) * (numValues + 1));
zeromem (values, sizeof (uint32) * (numValues + 1));
} }


highestBit = -1; highestBit = -1;
@@ -2707,11 +2707,11 @@ void BigInteger::setBit (const int bit)
{ {
if (bit > highestBit) if (bit > highestBit)
{ {
ensureSize (bit >> 5);
ensureSize (bitToIndex (bit));
highestBit = bit; highestBit = bit;
} }


values [bit >> 5] |= (1 << (bit & 31));
values [bitToIndex (bit)] |= bitToMask (bit);
} }
} }


@@ -2726,7 +2726,7 @@ void BigInteger::setBit (const int bit, const bool shouldBeSet)
void BigInteger::clearBit (const int bit) throw() void BigInteger::clearBit (const int bit) throw()
{ {
if (bit >= 0 && bit <= highestBit) if (bit >= 0 && bit <= highestBit)
values [bit >> 5] &= ~(1 << (bit & 31));
values [bitToIndex (bit)] &= ~bitToMask (bit);
} }


void BigInteger::setRange (int startBit, int numBits, const bool shouldBeSet) void BigInteger::setRange (int startBit, int numBits, const bool shouldBeSet)
@@ -2772,9 +2772,9 @@ int BigInteger::countNumberOfSetBits() const throw()
{ {
int total = 0; int total = 0;


for (int i = (highestBit >> 5) + 1; --i >= 0;)
for (int i = bitToIndex (highestBit) + 1; --i >= 0;)
{ {
unsigned int n = values[i];
uint32 n = values[i];


if (n == 0xffffffff) if (n == 0xffffffff)
{ {
@@ -2796,7 +2796,7 @@ int BigInteger::countNumberOfSetBits() const throw()
int BigInteger::getHighestBit() const throw() int BigInteger::getHighestBit() const throw()
{ {
for (int i = highestBit + 1; --i >= 0;) for (int i = highestBit + 1; --i >= 0;)
if ((values [i >> 5] & (1 << (i & 31))) != 0)
if ((values [bitToIndex (i)] & bitToMask (i)) != 0)
return i; return i;


return -1; return -1;
@@ -2805,7 +2805,7 @@ int BigInteger::getHighestBit() const throw()
int BigInteger::findNextSetBit (int i) const throw() int BigInteger::findNextSetBit (int i) const throw()
{ {
for (; i <= highestBit; ++i) for (; i <= highestBit; ++i)
if ((values [i >> 5] & (1 << (i & 31))) != 0)
if ((values [bitToIndex (i)] & bitToMask (i)) != 0)
return i; return i;


return -1; return -1;
@@ -2814,7 +2814,7 @@ int BigInteger::findNextSetBit (int i) const throw()
int BigInteger::findNextClearBit (int i) const throw() int BigInteger::findNextClearBit (int i) const throw()
{ {
for (; i <= highestBit; ++i) for (; i <= highestBit; ++i)
if ((values [i >> 5] & (1 << (i & 31))) == 0)
if ((values [bitToIndex (i)] & bitToMask (i)) == 0)
break; break;


return i; return i;
@@ -2848,7 +2848,7 @@ BigInteger& BigInteger::operator+= (const BigInteger& other)


++highestBit; ++highestBit;


const int numInts = (highestBit >> 5) + 1;
const int numInts = bitToIndex (highestBit) + 1;
ensureSize (numInts); ensureSize (numInts);


int64 remainder = 0; int64 remainder = 0;
@@ -2861,7 +2861,7 @@ BigInteger& BigInteger::operator+= (const BigInteger& other)
if (i < other.numValues) if (i < other.numValues)
remainder += other.values[i]; remainder += other.values[i];


values[i] = (unsigned int) remainder;
values[i] = (uint32) remainder;
remainder >>= 32; remainder >>= 32;
} }


@@ -2896,8 +2896,8 @@ BigInteger& BigInteger::operator-= (const BigInteger& other)
return *this; return *this;
} }


const int numInts = (highestBit >> 5) + 1;
const int maxOtherInts = (other.highestBit >> 5) + 1;
const int numInts = bitToIndex (highestBit) + 1;
const int maxOtherInts = bitToIndex (other.highestBit) + 1;
int64 amountToSubtract = 0; int64 amountToSubtract = 0;


for (int i = 0; i <= numInts; ++i) for (int i = 0; i <= numInts; ++i)
@@ -2907,13 +2907,13 @@ BigInteger& BigInteger::operator-= (const BigInteger& other)


if (values[i] >= amountToSubtract) if (values[i] >= amountToSubtract)
{ {
values[i] = (unsigned int) (values[i] - amountToSubtract);
values[i] = (uint32) (values[i] - amountToSubtract);
amountToSubtract = 0; amountToSubtract = 0;
} }
else else
{ {
const int64 n = ((int64) values[i] + (((int64) 1) << 32)) - amountToSubtract; const int64 n = ((int64) values[i] + (((int64) 1) << 32)) - amountToSubtract;
values[i] = (unsigned int) n;
values[i] = (uint32) n;
amountToSubtract = 1; amountToSubtract = 1;
} }
} }
@@ -3002,9 +3002,9 @@ BigInteger& BigInteger::operator|= (const BigInteger& other)


if (other.highestBit >= 0) if (other.highestBit >= 0)
{ {
ensureSize (other.highestBit >> 5);
ensureSize (bitToIndex (other.highestBit));


int n = (other.highestBit >> 5) + 1;
int n = bitToIndex (other.highestBit) + 1;


while (--n >= 0) while (--n >= 0)
values[n] |= other.values[n]; values[n] |= other.values[n];
@@ -3045,9 +3045,9 @@ BigInteger& BigInteger::operator^= (const BigInteger& other)


if (other.highestBit >= 0) if (other.highestBit >= 0)
{ {
ensureSize (other.highestBit >> 5);
ensureSize (bitToIndex (other.highestBit));


int n = (other.highestBit >> 5) + 1;
int n = bitToIndex (other.highestBit) + 1;


while (--n >= 0) while (--n >= 0)
values[n] ^= other.values[n]; values[n] ^= other.values[n];
@@ -3120,7 +3120,7 @@ int BigInteger::compareAbsolute (const BigInteger& other) const throw()
else if (h1 < h2) else if (h1 < h2)
return -1; return -1;


for (int i = (h1 >> 5) + 1; --i >= 0;)
for (int i = bitToIndex (h1) + 1; --i >= 0;)
if (values[i] != other.values[i]) if (values[i] != other.values[i])
return (values[i] > other.values[i]) ? 1 : -1; return (values[i] > other.values[i]) ? 1 : -1;


@@ -3172,8 +3172,8 @@ void BigInteger::shiftBits (int bits, const int startBit)
} }
else else
{ {
const int wordsToMove = bits >> 5;
int top = 1 + (highestBit >> 5) - wordsToMove;
const int wordsToMove = bitToIndex (bits);
int top = 1 + bitToIndex (highestBit) - wordsToMove;
highestBit -= bits; highestBit -= bits;


if (wordsToMove > 0) if (wordsToMove > 0)
@@ -3205,10 +3205,10 @@ void BigInteger::shiftBits (int bits, const int startBit)
else if (bits > 0) else if (bits > 0)
{ {
// left shift // left shift
ensureSize (((highestBit + bits) >> 5) + 1);
ensureSize (bitToIndex (highestBit + bits) + 1);


const int wordsToMove = bits >> 5;
int top = 1 + (highestBit >> 5);
const int wordsToMove = bitToIndex (bits);
int top = 1 + bitToIndex (highestBit);
highestBit += bits; highestBit += bits;


if (wordsToMove > 0) if (wordsToMove > 0)
@@ -3413,7 +3413,7 @@ void BigInteger::parseString (const String& text, const int base)
const juce_wchar c = *t++; const juce_wchar c = *t++;
const int digit = CharacterFunctions::getHexDigitValue (c); const int digit = CharacterFunctions::getHexDigitValue (c);


if (((unsigned int) digit) < (unsigned int) base)
if (((uint32) digit) < (uint32) base)
{ {
operator<<= (bits); operator<<= (bits);
operator+= (digit); operator+= (digit);
@@ -3426,7 +3426,7 @@ void BigInteger::parseString (const String& text, const int base)
} }
else if (base == 10) else if (base == 10)
{ {
const BigInteger ten ((unsigned int) 10);
const BigInteger ten ((uint32) 10);


for (;;) for (;;)
{ {
@@ -17695,11 +17695,17 @@ Array<UnitTest*>& UnitTest::getAllTests()
return tests; return tests;
} }


void UnitTest::initalise() {}
void UnitTest::shutdown() {}

void UnitTest::performTest (UnitTestRunner* const runner_) void UnitTest::performTest (UnitTestRunner* const runner_)
{ {
jassert (runner_ != 0); jassert (runner_ != 0);
runner = runner_; runner = runner_;

initalise();
runTest(); runTest();
shutdown();
} }


void UnitTest::logMessage (const String& message) void UnitTest::logMessage (const String& message)
@@ -17729,6 +17735,16 @@ UnitTestRunner::~UnitTestRunner()
{ {
} }


int UnitTestRunner::getNumResults() const throw()
{
return results.size();
}

const UnitTestRunner::TestResult* UnitTestRunner::getResult (int index) const throw()
{
return results [index];
}

void UnitTestRunner::resultsUpdated() void UnitTestRunner::resultsUpdated()
{ {
} }
@@ -42783,7 +42799,8 @@ BEGIN_JUCE_NAMESPACE


Desktop::Desktop() Desktop::Desktop()
: mouseClickCounter (0), : mouseClickCounter (0),
kioskModeComponent (0)
kioskModeComponent (0),
allowedOrientations (allOrientations)
{ {
createMouseInputSources(); createMouseInputSources();
refreshMonitorSizes(); refreshMonitorSizes();
@@ -43098,6 +43115,22 @@ void Desktop::setKioskModeComponent (Component* componentToUse, const bool allow
} }
} }


void Desktop::setOrientationsEnabled (const int newOrientations)
{
// Dodgy set of flags being passed here! Make sure you specify at least one permitted orientation.
jassert (newOrientations != 0 && (newOrientations & ~allOrientations) == 0);

allowedOrientations = newOrientations;
}

bool Desktop::isOrientationEnabled (const DisplayOrientation orientation) const throw()
{
// Make sure you only pass one valid flag in here...
jassert (orientation == upright || orientation == upsideDown || orientation == rotatedClockwise || orientation == rotatedAntiClockwise);

return (allowedOrientations & orientation) != 0;
}

END_JUCE_NAMESPACE END_JUCE_NAMESPACE
/*** End of inlined file: juce_Desktop.cpp ***/ /*** End of inlined file: juce_Desktop.cpp ***/


@@ -77589,11 +77622,13 @@ CallOutBox::CallOutBox (Component& contentComponent,


if (parentComponent != 0) if (parentComponent != 0)
{ {
updatePosition (parentComponent->getLocalBounds(),
componentToPointTo.getLocalBounds()
+ componentToPointTo.relativePositionToOtherComponent (parentComponent, Point<int>()));
parentComponent->addChildComponent (this);

updatePosition (componentToPointTo.getLocalBounds()
+ componentToPointTo.relativePositionToOtherComponent (parentComponent, Point<int>()),
parentComponent->getLocalBounds());


parentComponent->addAndMakeVisible (this);
setVisible (true);
} }
else else
{ {
@@ -79109,7 +79144,7 @@ void ResizableWindow::setFullScreen (const bool shouldBeFullScreen)


peer->setFullScreen (shouldBeFullScreen); peer->setFullScreen (shouldBeFullScreen);


if (! shouldBeFullScreen)
if ((! shouldBeFullScreen) && ! lastPos.isEmpty())
setBounds (lastPos); setBounds (lastPos);
} }
else else
@@ -241507,6 +241542,11 @@ bool Desktop::canUseSemiTransparentWindows() throw()
return updateLayeredWindow != 0; return updateLayeredWindow != 0;
} }


Desktop::DisplayOrientation Desktop::getCurrentOrientation() const
{
return upright;
}

const int extendedKeyModifier = 0x10000; const int extendedKeyModifier = 0x10000;


const int KeyPress::spaceKey = VK_SPACE; const int KeyPress::spaceKey = VK_SPACE;
@@ -258735,15 +258775,15 @@ public:


const int width = image.getWidth(); const int width = image.getWidth();
const int height = image.getHeight(); const int height = image.getHeight();
HeapBlock <char> colour (width * height);
HeapBlock <uint32> colour (width * height);
int index = 0; int index = 0;


for (int y = 0; y < height; ++y) for (int y = 0; y < height; ++y)
for (int x = 0; x < width; ++x) for (int x = 0; x < width; ++x)
colour[index++] = static_cast<char> (image.getPixelAt (x, y).getARGB());
colour[index++] = image.getPixelAt (x, y).getARGB();


XImage* ximage = XCreateImage (display, CopyFromParent, 24, ZPixmap, XImage* ximage = XCreateImage (display, CopyFromParent, 24, ZPixmap,
0, colour.getData(),
0, reinterpret_cast<char*> (colour.getData()),
width, height, 32, 0); width, height, 32, 0);


Pixmap pixmap = XCreatePixmap (display, DefaultRootWindow (display), Pixmap pixmap = XCreatePixmap (display, DefaultRootWindow (display),
@@ -260525,6 +260565,11 @@ void Desktop::setMousePosition (const Point<int>& newPosition)
XWarpPointer (display, None, root, 0, 0, 0, 0, newPosition.getX(), newPosition.getY()); XWarpPointer (display, None, root, 0, 0, 0, 0, newPosition.getX(), newPosition.getY());
} }


Desktop::DisplayOrientation Desktop::getCurrentOrientation() const
{
return upright;
}

static bool screenSaverAllowed = true; static bool screenSaverAllowed = true;


void Desktop::setScreenSaverEnabled (const bool isEnabled) void Desktop::setScreenSaverEnabled (const bool isEnabled)
@@ -263335,6 +263380,24 @@ BEGIN_JUCE_NAMESPACE


#undef Point #undef Point


template <class RectType>
static const Rectangle<int> convertToRectInt (const RectType& r)
{
return Rectangle<int> ((int) r.origin.x, (int) r.origin.y, (int) r.size.width, (int) r.size.height);
}

template <class RectType>
static const Rectangle<float> convertToRectFloat (const RectType& r)
{
return Rectangle<float> (r.origin.x, r.origin.y, r.size.width, r.size.height);
}

template <class RectType>
static CGRect convertToCGRect (const RectType& r)
{
return CGRectMake ((CGFloat) r.getX(), (CGFloat) r.getY(), (CGFloat) r.getWidth(), (CGFloat) r.getHeight());
}

#define JUCE_INCLUDED_FILE 1 #define JUCE_INCLUDED_FILE 1


// Now include the actual code files.. // Now include the actual code files..
@@ -265678,20 +265741,6 @@ bool Desktop::isScreenSaverEnabled()
return ! [[UIApplication sharedApplication] isIdleTimerDisabled]; return ! [[UIApplication sharedApplication] isIdleTimerDisabled];
} }


void juce_updateMultiMonitorInfo (Array <Rectangle <int> >& monitorCoords, const bool clipToWorkArea)
{
const ScopedAutoReleasePool pool;
monitorCoords.clear();

CGRect r = clipToWorkArea ? [[UIScreen mainScreen] applicationFrame]
: [[UIScreen mainScreen] bounds];

monitorCoords.add (Rectangle<int> ((int) r.origin.x,
(int) r.origin.y,
(int) r.size.width,
(int) r.size.height));
}

#endif #endif


#endif #endif
@@ -265829,6 +265878,11 @@ void Desktop::setMousePosition (const Point<int>& newPosition)
CGAssociateMouseAndMouseCursorPosition (true); CGAssociateMouseAndMouseCursorPosition (true);
} }


Desktop::DisplayOrientation Desktop::getCurrentOrientation() const
{
return upright;
}

#if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5 #if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5
class ScreenSaverDefeater : public Timer, class ScreenSaverDefeater : public Timer,
public DeletedAtShutdown public DeletedAtShutdown
@@ -265914,10 +265968,9 @@ void juce_updateMultiMonitorInfo (Array <Rectangle<int> >& monitorCoords, const
NSRect r = clipToWorkArea ? [s visibleFrame] NSRect r = clipToWorkArea ? [s visibleFrame]
: [s frame]; : [s frame];


monitorCoords.add (Rectangle<int> ((int) r.origin.x,
(int) (mainScreenBottom - (r.origin.y + r.size.height)),
(int) r.size.width,
(int) r.size.height));
r.origin.y = mainScreenBottom - (r.origin.y + r.size.height);

monitorCoords.add (convertToRectInt (r));
} }


jassert (monitorCoords.size() > 0); jassert (monitorCoords.size() > 0);
@@ -267302,6 +267355,16 @@ END_JUCE_NAMESPACE
- (BOOL) textView: (UITextView*) textView shouldChangeTextInRange: (NSRange) range replacementText: (NSString*) text; - (BOOL) textView: (UITextView*) textView shouldChangeTextInRange: (NSRange) range replacementText: (NSString*) text;
@end @end


#define JuceUIViewController MakeObjCClassName(JuceUIViewController)

@interface JuceUIViewController : UIViewController
{
}

- (BOOL) shouldAutorotateToInterfaceOrientation: (UIInterfaceOrientation) interfaceOrientation;
- (void) didRotateFromInterfaceOrientation: (UIInterfaceOrientation) fromInterfaceOrientation;
@end

#define JuceUIWindow MakeObjCClassName(JuceUIWindow) #define JuceUIWindow MakeObjCClassName(JuceUIWindow)


@interface JuceUIWindow : UIWindow @interface JuceUIWindow : UIWindow
@@ -267368,6 +267431,9 @@ public:
void updateHiddenTextContent (TextInputTarget* target); void updateHiddenTextContent (TextInputTarget* target);
void globalFocusChanged (Component*); void globalFocusChanged (Component*);


virtual BOOL shouldRotate (UIInterfaceOrientation interfaceOrientation);
virtual void displayRotated();

void handleTouches (UIEvent* e, bool isDown, bool isUp, bool isCancel); void handleTouches (UIEvent* e, bool isDown, bool isUp, bool isCancel);


void repaint (const Rectangle<int>& area); void repaint (const Rectangle<int>& area);
@@ -267377,6 +267443,7 @@ public:


UIWindow* window; UIWindow* window;
JuceUIView* view; JuceUIView* view;
JuceUIViewController* controller;
bool isSharedWindow, fullScreen, insideDrawRect; bool isSharedWindow, fullScreen, insideDrawRect;
static ModifierKeys currentModifiers; static ModifierKeys currentModifiers;


@@ -267386,11 +267453,83 @@ public:
+ (int64) ([e timestamp] * 1000.0); + (int64) ([e timestamp] * 1000.0);
} }


static const Rectangle<int> rotatedScreenPosToReal (const Rectangle<int>& r)
{
const Rectangle<int> screen (convertToRectInt ([[UIScreen mainScreen] bounds]));

switch ([[UIApplication sharedApplication] statusBarOrientation])
{
case UIInterfaceOrientationPortrait:
return r;

case UIInterfaceOrientationPortraitUpsideDown:
return Rectangle<int> (screen.getWidth() - r.getRight(), screen.getHeight() - r.getBottom(),
r.getWidth(), r.getHeight());

case UIInterfaceOrientationLandscapeLeft:
return Rectangle<int> (r.getY(), screen.getHeight() - r.getRight(),
r.getHeight(), r.getWidth());

case UIInterfaceOrientationLandscapeRight:
return Rectangle<int> (screen.getWidth() - r.getBottom(), r.getX(),
r.getHeight(), r.getWidth());

default: jassertfalse; // unknown orientation!
}

return r;
}

static const Rectangle<int> realScreenPosToRotated (const Rectangle<int>& r)
{
const Rectangle<int> screen (convertToRectInt ([[UIScreen mainScreen] bounds]));

switch ([[UIApplication sharedApplication] statusBarOrientation])
{
case UIInterfaceOrientationPortrait:
return r;

case UIInterfaceOrientationPortraitUpsideDown:
return Rectangle<int> (screen.getWidth() - r.getRight(), screen.getHeight() - r.getBottom(),
r.getWidth(), r.getHeight());

case UIInterfaceOrientationLandscapeLeft:
return Rectangle<int> (screen.getHeight() - r.getBottom(), r.getX(),
r.getHeight(), r.getWidth());

case UIInterfaceOrientationLandscapeRight:
return Rectangle<int> (r.getY(), screen.getWidth() - r.getRight(),
r.getHeight(), r.getWidth());

default: jassertfalse; // unknown orientation!
}

return r;
}

Array <UITouch*> currentTouches; Array <UITouch*> currentTouches;
}; };


END_JUCE_NAMESPACE END_JUCE_NAMESPACE


@implementation JuceUIViewController

- (BOOL) shouldAutorotateToInterfaceOrientation: (UIInterfaceOrientation) interfaceOrientation
{
JuceUIView* juceView = (JuceUIView*) [self view];
jassert (juceView != 0 && juceView->owner != 0);
return juceView->owner->shouldRotate (interfaceOrientation);
}

- (void) didRotateFromInterfaceOrientation: (UIInterfaceOrientation) fromInterfaceOrientation
{
JuceUIView* juceView = (JuceUIView*) [self view];
jassert (juceView != 0 && juceView->owner != 0);
juceView->owner->displayRotated();
}

@end

@implementation JuceUIView @implementation JuceUIView


- (JuceUIView*) initWithOwner: (UIViewComponentPeer*) owner_ - (JuceUIView*) initWithOwner: (UIViewComponentPeer*) owner_
@@ -267528,12 +267667,12 @@ UIViewComponentPeer::UIViewComponentPeer (Component* const component,
UIView* viewToAttachTo) UIView* viewToAttachTo)
: ComponentPeer (component, windowStyleFlags), : ComponentPeer (component, windowStyleFlags),
window (0), window (0),
view (0),
view (0), controller (0),
isSharedWindow (viewToAttachTo != 0), isSharedWindow (viewToAttachTo != 0),
fullScreen (false), fullScreen (false),
insideDrawRect (false) insideDrawRect (false)
{ {
CGRect r = CGRectMake (0, 0, (float) component->getWidth(), (float) component->getHeight());
CGRect r = convertToCGRect (component->getLocalBounds());


view = [[JuceUIView alloc] initWithOwner: this withFrame: r]; view = [[JuceUIView alloc] initWithOwner: this withFrame: r];


@@ -267546,8 +267685,10 @@ UIViewComponentPeer::UIViewComponentPeer (Component* const component,
} }
else else
{ {
r.origin.x = (float) component->getX();
r.origin.y = (float) component->getY();
controller = [[JuceUIViewController alloc] init];
controller.view = view;

r = convertToCGRect (rotatedScreenPosToReal (component->getBounds()));
r.origin.y = [[UIScreen mainScreen] bounds].size.height - (r.origin.y + r.size.height); r.origin.y = [[UIScreen mainScreen] bounds].size.height - (r.origin.y + r.size.height);


window = [[JuceUIWindow alloc] init]; window = [[JuceUIWindow alloc] init];
@@ -267584,6 +267725,7 @@ UIViewComponentPeer::~UIViewComponentPeer()
view->owner = 0; view->owner = 0;
[view removeFromSuperview]; [view removeFromSuperview];
[view release]; [view release];
[controller release];


if (! isSharedWindow) if (! isSharedWindow)
{ {
@@ -267626,15 +267768,9 @@ void UIViewComponentPeer::setBounds (int x, int y, int w, int h, const bool isNo
w = jmax (0, w); w = jmax (0, w);
h = jmax (0, h); h = jmax (0, h);


CGRect r;
r.origin.x = (float) x;
r.origin.y = (float) y;
r.size.width = (float) w;
r.size.height = (float) h;

if (isSharedWindow) if (isSharedWindow)
{ {
//r.origin.y = [[view superview] frame].size.height - (r.origin.y + r.size.height);
CGRect r = CGRectMake ((float) x, (float) y, (float) w, (float) h);


if ([view frame].size.width != r.size.width if ([view frame].size.width != r.size.width
|| [view frame].size.height != r.size.height) || [view frame].size.height != r.size.height)
@@ -267644,8 +267780,11 @@ void UIViewComponentPeer::setBounds (int x, int y, int w, int h, const bool isNo
} }
else else
{ {
window.frame = r;
view.frame = CGRectMake (0, 0, r.size.width, r.size.height);
const Rectangle<int> bounds (rotatedScreenPosToReal (Rectangle<int> (x, y, w, h)));
window.frame = convertToCGRect (bounds);
view.frame = CGRectMake (0, 0, (float) bounds.getWidth(), (float) bounds.getHeight());

handleMovedOrResized();
} }
} }


@@ -267657,12 +267796,14 @@ const Rectangle<int> UIViewComponentPeer::getBounds (const bool global) const
{ {
r = [view convertRect: r toView: nil]; r = [view convertRect: r toView: nil];
CGRect wr = [[view window] frame]; CGRect wr = [[view window] frame];
r.origin.x += wr.origin.x;
r.origin.y += wr.origin.y;

const Rectangle<int> windowBounds (realScreenPosToRotated (convertToRectInt (wr)));

r.origin.x = windowBounds.getX();
r.origin.y = windowBounds.getY();
} }


return Rectangle<int> ((int) r.origin.x, (int) r.origin.y,
(int) r.size.width, (int) r.size.height);
return convertToRectInt (r);
} }


const Rectangle<int> UIViewComponentPeer::getBounds() const const Rectangle<int> UIViewComponentPeer::getBounds() const
@@ -267694,11 +267835,8 @@ CGRect UIViewComponentPeer::constrainRect (CGRect r)


r.origin.y = [[UIScreen mainScreen] bounds].size.height - r.origin.y - r.size.height; r.origin.y = [[UIScreen mainScreen] bounds].size.height - r.origin.y - r.size.height;


Rectangle<int> pos ((int) r.origin.x, (int) r.origin.y,
(int) r.size.width, (int) r.size.height);

Rectangle<int> original ((int) current.origin.x, (int) current.origin.y,
(int) current.size.width, (int) current.size.height);
Rectangle<int> pos (convertToRectInt (r));
Rectangle<int> original (convertToRectInt (current));


constrainer->checkBounds (pos, original, constrainer->checkBounds (pos, original,
Desktop::getInstance().getAllMonitorDisplayAreas().getBounds(), Desktop::getInstance().getAllMonitorDisplayAreas().getBounds(),
@@ -267718,7 +267856,6 @@ CGRect UIViewComponentPeer::constrainRect (CGRect r)


void UIViewComponentPeer::setMinimised (bool shouldBeMinimised) void UIViewComponentPeer::setMinimised (bool shouldBeMinimised)
{ {
// xxx
} }


bool UIViewComponentPeer::isMinimised() const bool UIViewComponentPeer::isMinimised() const
@@ -267730,19 +267867,17 @@ void UIViewComponentPeer::setFullScreen (bool shouldBeFullScreen)
{ {
if (! isSharedWindow) if (! isSharedWindow)
{ {
Rectangle<int> r (lastNonFullscreenBounds);
Rectangle<int> r (shouldBeFullScreen ? Desktop::getInstance().getMainMonitorArea()
: lastNonFullscreenBounds);


setMinimised (false);
if ((! shouldBeFullScreen) && r.isEmpty())
r = getBounds();


if (fullScreen != shouldBeFullScreen)
{
if (shouldBeFullScreen)
r = Desktop::getInstance().getMainMonitorArea();
// (can't call the component's setBounds method because that'll reset our fullscreen flag)
if (! r.isEmpty())
setBounds (r.getX(), r.getY(), r.getWidth(), r.getHeight(), shouldBeFullScreen);


// (can't call the component's setBounds method because that'll reset our fullscreen flag)
if (r != getComponent()->getBounds() && ! r.isEmpty())
setBounds (r.getX(), r.getY(), r.getWidth(), r.getHeight(), shouldBeFullScreen);
}
component->repaint();
} }
} }


@@ -267751,17 +267886,61 @@ bool UIViewComponentPeer::isFullScreen() const
return fullScreen; return fullScreen;
} }


static Desktop::DisplayOrientation convertToJuceOrientation (UIInterfaceOrientation interfaceOrientation)
{
switch (interfaceOrientation)
{
case UIInterfaceOrientationPortrait: return Desktop::upright;
case UIInterfaceOrientationPortraitUpsideDown: return Desktop::upsideDown;
case UIInterfaceOrientationLandscapeLeft: return Desktop::rotatedClockwise;
case UIInterfaceOrientationLandscapeRight: return Desktop::rotatedAntiClockwise;
default: jassertfalse; // unknown orientation!
}

return Desktop::upright;
}

BOOL UIViewComponentPeer::shouldRotate (UIInterfaceOrientation interfaceOrientation)
{
return Desktop::getInstance().isOrientationEnabled (convertToJuceOrientation (interfaceOrientation));
}

void UIViewComponentPeer::displayRotated()
{
const Rectangle<int> oldArea (component->getBounds());
const Rectangle<int> oldDesktop (Desktop::getInstance().getMainMonitorArea());
Desktop::getInstance().refreshMonitorSizes();

if (fullScreen)
{
fullScreen = false;
setFullScreen (true);
}
else
{
const float l = oldArea.getX() / (float) oldDesktop.getWidth();
const float r = oldArea.getRight() / (float) oldDesktop.getWidth();
const float t = oldArea.getY() / (float) oldDesktop.getHeight();
const float b = oldArea.getBottom() / (float) oldDesktop.getHeight();

const Rectangle<int> newDesktop (Desktop::getInstance().getMainMonitorArea());

setBounds ((int) (l * newDesktop.getWidth()),
(int) (t * newDesktop.getHeight()),
(int) ((r - l) * newDesktop.getWidth()),
(int) ((b - t) * newDesktop.getHeight()),
false);
}
}

bool UIViewComponentPeer::contains (const Point<int>& position, bool trueIfInAChildWindow) const bool UIViewComponentPeer::contains (const Point<int>& position, bool trueIfInAChildWindow) const
{ {
if (((unsigned int) position.getX()) >= (unsigned int) component->getWidth() if (((unsigned int) position.getX()) >= (unsigned int) component->getWidth()
|| ((unsigned int) position.getY()) >= (unsigned int) component->getHeight()) || ((unsigned int) position.getY()) >= (unsigned int) component->getHeight())
return false; return false;


CGPoint p;
p.x = (float) position.getX();
p.y = (float) position.getY();

UIView* v = [view hitTest: p withEvent: nil];
UIView* v = [view hitTest: CGPointMake ((float) position.getX(), (float) position.getY())
withEvent: nil];


if (trueIfInAChildWindow) if (trueIfInAChildWindow)
return v != nil; return v != nil;
@@ -267771,20 +267950,7 @@ bool UIViewComponentPeer::contains (const Point<int>& position, bool trueIfInACh


const BorderSize UIViewComponentPeer::getFrameSize() const const BorderSize UIViewComponentPeer::getFrameSize() const
{ {
BorderSize b;

if (! isSharedWindow)
{
CGRect v = [view convertRect: [view frame] toView: nil];
CGRect w = [window frame];

b.setTop ((int) (w.size.height - (v.origin.y + v.size.height)));
b.setBottom ((int) v.origin.y);
b.setLeft ((int) v.origin.x);
b.setRight ((int) (w.size.width - (v.origin.x + v.size.width)));
}

return b;
return BorderSize();
} }


bool UIViewComponentPeer::setAlwaysOnTop (bool alwaysOnTop) bool UIViewComponentPeer::setAlwaysOnTop (bool alwaysOnTop)
@@ -268043,8 +268209,7 @@ void UIViewComponentPeer::repaint (const Rectangle<int>& area)
} }
else else
{ {
[view setNeedsDisplayInRect: CGRectMake ((float) area.getX(), (float) area.getY(),
(float) area.getWidth(), (float) area.getHeight())];
[view setNeedsDisplayInRect: convertToCGRect (area)];
} }
} }


@@ -268082,6 +268247,22 @@ void Desktop::setMousePosition (const Point<int>&)
{ {
} }


Desktop::DisplayOrientation Desktop::getCurrentOrientation() const
{
return convertToJuceOrientation ([[UIApplication sharedApplication] statusBarOrientation]);
}

void juce_updateMultiMonitorInfo (Array <Rectangle <int> >& monitorCoords, const bool clipToWorkArea)
{
const ScopedAutoReleasePool pool;
monitorCoords.clear();

CGRect r = clipToWorkArea ? [[UIScreen mainScreen] applicationFrame]
: [[UIScreen mainScreen] bounds];

monitorCoords.add (UIViewComponentPeer::realScreenPosToRotated (convertToRectInt (r)));
}

const int KeyPress::spaceKey = ' '; const int KeyPress::spaceKey = ' ';
const int KeyPress::returnKey = 0x0d; const int KeyPress::returnKey = 0x0d;
const int KeyPress::escapeKey = 0x1b; const int KeyPress::escapeKey = 0x1b;
@@ -272823,7 +273004,7 @@ const Rectangle<int> NSViewComponentPeer::getBounds (const bool global) const
r.origin.y = [[view superview] frame].size.height - r.origin.y - r.size.height; r.origin.y = [[view superview] frame].size.height - r.origin.y - r.size.height;
} }


return Rectangle<int> ((int) r.origin.x, (int) r.origin.y, (int) r.size.width, (int) r.size.height);
return Rectangle<int> (convertToRectInt (r));
} }


const Rectangle<int> NSViewComponentPeer::getBounds() const const Rectangle<int> NSViewComponentPeer::getBounds() const
@@ -272855,11 +273036,8 @@ NSRect NSViewComponentPeer::constrainRect (NSRect r)


r.origin.y = [[[NSScreen screens] objectAtIndex: 0] frame].size.height - r.origin.y - r.size.height; r.origin.y = [[[NSScreen screens] objectAtIndex: 0] frame].size.height - r.origin.y - r.size.height;


Rectangle<int> pos ((int) r.origin.x, (int) r.origin.y,
(int) r.size.width, (int) r.size.height);

Rectangle<int> original ((int) current.origin.x, (int) current.origin.y,
(int) current.size.width, (int) current.size.height);
Rectangle<int> pos (convertToRectInt (r));
Rectangle<int> original (convertToRectInt (current));


constrainer->checkBounds (pos, original, constrainer->checkBounds (pos, original,
Desktop::getInstance().getAllMonitorDisplayAreas().getBounds(), Desktop::getInstance().getAllMonitorDisplayAreas().getBounds(),


+ 73
- 5
juce_amalgamated.h View File

@@ -64,7 +64,7 @@
*/ */
#define JUCE_MAJOR_VERSION 1 #define JUCE_MAJOR_VERSION 1
#define JUCE_MINOR_VERSION 52 #define JUCE_MINOR_VERSION 52
#define JUCE_BUILDNUMBER 75
#define JUCE_BUILDNUMBER 76


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


@@ -2898,6 +2898,9 @@ private:
static inline Type castFrom64Bit (int64 value) throw() { return *(Type*) &value; } static inline Type castFrom64Bit (int64 value) throw() { return *(Type*) &value; }
static inline int32 castTo32Bit (Type value) throw() { return *(int32*) &value; } static inline int32 castTo32Bit (Type value) throw() { return *(int32*) &value; }
static inline int64 castTo64Bit (Type value) throw() { return *(int64*) &value; } static inline int64 castTo64Bit (Type value) throw() { return *(int64*) &value; }

Type operator++ (int); // better to just use pre-increment with atomics..
Type operator-- (int);
}; };


/* /*
@@ -4976,14 +4979,14 @@ public:


The low 32 bits of the number are initialised with this value. The low 32 bits of the number are initialised with this value.
*/ */
BigInteger (unsigned int value);
BigInteger (uint32 value);


/** Creates a BigInteger containing an integer value in its low bits. /** Creates a BigInteger containing an integer value in its low bits.


The low 32 bits of the number are initialised with the absolute value The low 32 bits of the number are initialised with the absolute value
passed in, and its sign is set to reflect the sign of the number. passed in, and its sign is set to reflect the sign of the number.
*/ */
BigInteger (int value);
BigInteger (int32 value);


/** Creates a BigInteger containing an integer value in its low bits. /** Creates a BigInteger containing an integer value in its low bits.


@@ -5064,7 +5067,7 @@ public:
Copies the given integer onto a range of bits, starting at startBit, Copies the given integer onto a range of bits, starting at startBit,
and using up to numBits of the available bits. and using up to numBits of the available bits.
*/ */
void setBitRangeAsInt (int startBit, int numBits, unsigned int valueToSet);
void setBitRangeAsInt (int startBit, int numBits, uint32 valueToSet);


/** Shifts a section of bits left or right. /** Shifts a section of bits left or right.


@@ -5223,12 +5226,15 @@ public:
juce_UseDebuggingNewOperator juce_UseDebuggingNewOperator


private: private:
HeapBlock <unsigned int> values;
HeapBlock <uint32> values;
int numValues, highestBit; int numValues, highestBit;
bool negative; bool negative;


void ensureSize (int numVals); void ensureSize (int numVals);
static const BigInteger simpleGCD (BigInteger* m, BigInteger* n); static const BigInteger simpleGCD (BigInteger* m, BigInteger* n);

static inline int bitToIndex (const int bit) throw() { return bit >> 5; }
static inline uint32 bitToMask (const int bit) throw() { return 1 << (bit & 31); }
}; };


/** Writes a BigInteger to an OutputStream as a UTF8 decimal string. */ /** Writes a BigInteger to an OutputStream as a UTF8 decimal string. */
@@ -29038,6 +29044,34 @@ public:
*/ */
MouseInputSource* getDraggingMouseSource (int index) const throw(); MouseInputSource* getDraggingMouseSource (int index) const throw();


/** In a tablet device which can be turned around, this is used to inidicate the orientation. */
enum DisplayOrientation
{
upright = 1, /**< Indicates that the display is the normal way up. */
upsideDown = 2, /**< Indicates that the display is upside-down. */
rotatedClockwise = 4, /**< Indicates that the display is turned 90 degrees clockwise from its upright position. */
rotatedAntiClockwise = 8, /**< Indicates that the display is turned 90 degrees anti-clockwise from its upright position. */

allOrientations = 1 + 2 + 4 + 8 /**< A combination of all the orientation values */
};

/** In a tablet device which can be turned around, this returns the current orientation. */
DisplayOrientation getCurrentOrientation() const;

/** Sets which orientations the display is allowed to auto-rotate to.

For devices that support rotating desktops, this lets you specify which of the orientations your app can use.

The parameter is a bitwise or-ed combination of the values in DisplayOrientation, and must contain at least one
set bit.
*/
void setOrientationsEnabled (int allowedOrientations);

/** Returns whether the display is allowed to auto-rotate to the given orientation.
Each orientation can be enabled using setOrientationEnabled(). By default, all orientations are allowed.
*/
bool isOrientationEnabled (DisplayOrientation orientation) const throw();

juce_UseDebuggingNewOperator juce_UseDebuggingNewOperator


/** Tells this object to refresh its idea of what the screen resolution is. /** Tells this object to refresh its idea of what the screen resolution is.
@@ -29078,6 +29112,8 @@ private:
Component* kioskModeComponent; Component* kioskModeComponent;
Rectangle<int> kioskComponentOriginalBounds; Rectangle<int> kioskComponentOriginalBounds;


int allowedOrientations;

void timerCallback(); void timerCallback();
void resetTimer(); void resetTimer();


@@ -29985,6 +30021,9 @@ public:
SampleFormat data; SampleFormat data;


inline void advance() throw() { advanceData (data); } inline void advance() throw() { advanceData (data); }

Pointer operator++ (int); // private to force you to use the more efficient pre-increment!
Pointer operator-- (int);
}; };


/** A base class for objects that are used to convert between two different sample formats. /** A base class for objects that are used to convert between two different sample formats.
@@ -62372,6 +62411,16 @@ public:
/** Returns the set of all UnitTest objects that currently exist. */ /** Returns the set of all UnitTest objects that currently exist. */
static Array<UnitTest*>& getAllTests(); static Array<UnitTest*>& getAllTests();


/** You can optionally implement this method to set up your test.
This method will be called before runTest().
*/
virtual void initalise();

/** You can optionally implement this method to clear up after your test has been run.
This method will be called after runTest() has returned.
*/
virtual void shutdown();

/** Implement this method in your subclass to actually run your tests. /** Implement this method in your subclass to actually run your tests.


The content of your implementation should call beginTest() and expect() The content of your implementation should call beginTest() and expect()
@@ -62405,6 +62454,25 @@ public:
*/ */
void expect (bool testResult, const String& failureMessage = String::empty); void expect (bool testResult, const String& failureMessage = String::empty);


/** Compares two values, and if they don't match, prints out a message containing the
expected and actual result values.
*/
template <class ValueType>
void expectEquals (ValueType actual, ValueType expected, String failureMessage = String::empty)
{
const bool result = (actual == expected);

if (! result)
{
if (failureMessage.isNotEmpty())
failureMessage << " -- ";

failureMessage << "Expected value: " << expected << ", Actual value: " << actual;
}

expect (result, failureMessage);
}

/** Writes a message to the test log. /** Writes a message to the test log.
This can only be called from within your runTest() method. This can only be called from within your runTest() method.
*/ */


+ 1
- 0
src/audio/audio_file_formats/juce_QuickTimeAudioFormat.cpp View File

@@ -66,6 +66,7 @@ BEGIN_JUCE_NAMESPACE
#include "../../threads/juce_Thread.h" #include "../../threads/juce_Thread.h"
#include "../../io/network/juce_URL.h" #include "../../io/network/juce_URL.h"
#include "../../containers/juce_ScopedPointer.h" #include "../../containers/juce_ScopedPointer.h"
#include "../../core/juce_PlatformUtilities.h"
bool juce_OpenQuickTimeMovieFromStream (InputStream* input, Movie& movie, Handle& dataHandle); bool juce_OpenQuickTimeMovieFromStream (InputStream* input, Movie& movie, Handle& dataHandle);


+ 3
- 0
src/audio/dsp/juce_AudioDataConverters.h View File

@@ -262,6 +262,9 @@ public:
SampleFormat data; SampleFormat data;
inline void advance() throw() { advanceData (data); } inline void advance() throw() { advanceData (data); }
Pointer operator++ (int); // private to force you to use the more efficient pre-increment!
Pointer operator-- (int);
}; };
//============================================================================== //==============================================================================


+ 48
- 48
src/containers/juce_BigInteger.cpp View File

@@ -41,7 +41,7 @@ BigInteger::BigInteger()
values.calloc (numValues + 1); values.calloc (numValues + 1);
} }
BigInteger::BigInteger (const int value)
BigInteger::BigInteger (const int32 value)
: numValues (4), : numValues (4),
highestBit (31), highestBit (31),
negative (value < 0) negative (value < 0)
@@ -51,6 +51,16 @@ BigInteger::BigInteger (const int value)
highestBit = getHighestBit(); highestBit = getHighestBit();
} }
BigInteger::BigInteger (const uint32 value)
: numValues (4),
highestBit (31),
negative (false)
{
values.calloc (numValues + 1);
values[0] = value;
highestBit = getHighestBit();
}
BigInteger::BigInteger (int64 value) BigInteger::BigInteger (int64 value)
: numValues (4), : numValues (4),
highestBit (63), highestBit (63),
@@ -61,28 +71,18 @@ BigInteger::BigInteger (int64 value)
if (value < 0) if (value < 0)
value = -value; value = -value;
values[0] = (unsigned int) value;
values[1] = (unsigned int) (value >> 32);
highestBit = getHighestBit();
}
BigInteger::BigInteger (const unsigned int value)
: numValues (4),
highestBit (31),
negative (false)
{
values.calloc (numValues + 1);
values[0] = value;
values[0] = (uint32) value;
values[1] = (uint32) (value >> 32);
highestBit = getHighestBit(); highestBit = getHighestBit();
} }
BigInteger::BigInteger (const BigInteger& other) BigInteger::BigInteger (const BigInteger& other)
: numValues (jmax (4, (other.highestBit >> 5) + 1)),
: numValues (jmax (4, bitToIndex (other.highestBit) + 1)),
highestBit (other.getHighestBit()), highestBit (other.getHighestBit()),
negative (other.negative) negative (other.negative)
{ {
values.malloc (numValues + 1); values.malloc (numValues + 1);
memcpy (values, other.values, sizeof (unsigned int) * (numValues + 1));
memcpy (values, other.values, sizeof (uint32) * (numValues + 1));
} }
BigInteger::~BigInteger() BigInteger::~BigInteger()
@@ -102,10 +102,10 @@ BigInteger& BigInteger::operator= (const BigInteger& other)
if (this != &other) if (this != &other)
{ {
highestBit = other.getHighestBit(); highestBit = other.getHighestBit();
numValues = jmax (4, (highestBit >> 5) + 1);
numValues = jmax (4, bitToIndex (highestBit) + 1);
negative = other.negative; negative = other.negative;
values.malloc (numValues + 1); values.malloc (numValues + 1);
memcpy (values, other.values, sizeof (unsigned int) * (numValues + 1));
memcpy (values, other.values, sizeof (uint32) * (numValues + 1));
} }
return *this; return *this;
@@ -128,7 +128,7 @@ void BigInteger::ensureSize (const int numVals)
bool BigInteger::operator[] (const int bit) const throw() bool BigInteger::operator[] (const int bit) const throw()
{ {
return bit <= highestBit && bit >= 0 return bit <= highestBit && bit >= 0
&& ((values [bit >> 5] & (1 << (bit & 31))) != 0);
&& ((values [bitToIndex (bit)] & bitToMask (bit)) != 0);
} }
int BigInteger::toInteger() const throw() int BigInteger::toInteger() const throw()
@@ -141,7 +141,7 @@ const BigInteger BigInteger::getBitRange (int startBit, int numBits) const
{ {
BigInteger r; BigInteger r;
numBits = jmin (numBits, getHighestBit() + 1 - startBit); numBits = jmin (numBits, getHighestBit() + 1 - startBit);
r.ensureSize (numBits >> 5);
r.ensureSize (bitToIndex (numBits));
r.highestBit = numBits; r.highestBit = numBits;
int i = 0; int i = 0;
@@ -169,7 +169,7 @@ int BigInteger::getBitRangeAsInt (const int startBit, int numBits) const throw()
if (numBits <= 0) if (numBits <= 0)
return 0; return 0;
const int pos = startBit >> 5;
const int pos = bitToIndex (startBit);
const int offset = startBit & 31; const int offset = startBit & 31;
const int endSpace = 32 - numBits; const int endSpace = 32 - numBits;
@@ -181,7 +181,7 @@ int BigInteger::getBitRangeAsInt (const int startBit, int numBits) const throw()
return (int) (n & (((uint32) 0xffffffff) >> endSpace)); return (int) (n & (((uint32) 0xffffffff) >> endSpace));
} }
void BigInteger::setBitRangeAsInt (const int startBit, int numBits, unsigned int valueToSet)
void BigInteger::setBitRangeAsInt (const int startBit, int numBits, uint32 valueToSet)
{ {
if (numBits > 32) if (numBits > 32)
{ {
@@ -206,7 +206,7 @@ void BigInteger::clear()
} }
else else
{ {
zeromem (values, sizeof (unsigned int) * (numValues + 1));
zeromem (values, sizeof (uint32) * (numValues + 1));
} }
highestBit = -1; highestBit = -1;
@@ -219,11 +219,11 @@ void BigInteger::setBit (const int bit)
{ {
if (bit > highestBit) if (bit > highestBit)
{ {
ensureSize (bit >> 5);
ensureSize (bitToIndex (bit));
highestBit = bit; highestBit = bit;
} }
values [bit >> 5] |= (1 << (bit & 31));
values [bitToIndex (bit)] |= bitToMask (bit);
} }
} }
@@ -238,7 +238,7 @@ void BigInteger::setBit (const int bit, const bool shouldBeSet)
void BigInteger::clearBit (const int bit) throw() void BigInteger::clearBit (const int bit) throw()
{ {
if (bit >= 0 && bit <= highestBit) if (bit >= 0 && bit <= highestBit)
values [bit >> 5] &= ~(1 << (bit & 31));
values [bitToIndex (bit)] &= ~bitToMask (bit);
} }
void BigInteger::setRange (int startBit, int numBits, const bool shouldBeSet) void BigInteger::setRange (int startBit, int numBits, const bool shouldBeSet)
@@ -285,9 +285,9 @@ int BigInteger::countNumberOfSetBits() const throw()
{ {
int total = 0; int total = 0;
for (int i = (highestBit >> 5) + 1; --i >= 0;)
for (int i = bitToIndex (highestBit) + 1; --i >= 0;)
{ {
unsigned int n = values[i];
uint32 n = values[i];
if (n == 0xffffffff) if (n == 0xffffffff)
{ {
@@ -309,7 +309,7 @@ int BigInteger::countNumberOfSetBits() const throw()
int BigInteger::getHighestBit() const throw() int BigInteger::getHighestBit() const throw()
{ {
for (int i = highestBit + 1; --i >= 0;) for (int i = highestBit + 1; --i >= 0;)
if ((values [i >> 5] & (1 << (i & 31))) != 0)
if ((values [bitToIndex (i)] & bitToMask (i)) != 0)
return i; return i;
return -1; return -1;
@@ -318,7 +318,7 @@ int BigInteger::getHighestBit() const throw()
int BigInteger::findNextSetBit (int i) const throw() int BigInteger::findNextSetBit (int i) const throw()
{ {
for (; i <= highestBit; ++i) for (; i <= highestBit; ++i)
if ((values [i >> 5] & (1 << (i & 31))) != 0)
if ((values [bitToIndex (i)] & bitToMask (i)) != 0)
return i; return i;
return -1; return -1;
@@ -327,7 +327,7 @@ int BigInteger::findNextSetBit (int i) const throw()
int BigInteger::findNextClearBit (int i) const throw() int BigInteger::findNextClearBit (int i) const throw()
{ {
for (; i <= highestBit; ++i) for (; i <= highestBit; ++i)
if ((values [i >> 5] & (1 << (i & 31))) == 0)
if ((values [bitToIndex (i)] & bitToMask (i)) == 0)
break; break;
return i; return i;
@@ -362,7 +362,7 @@ BigInteger& BigInteger::operator+= (const BigInteger& other)
++highestBit; ++highestBit;
const int numInts = (highestBit >> 5) + 1;
const int numInts = bitToIndex (highestBit) + 1;
ensureSize (numInts); ensureSize (numInts);
int64 remainder = 0; int64 remainder = 0;
@@ -375,7 +375,7 @@ BigInteger& BigInteger::operator+= (const BigInteger& other)
if (i < other.numValues) if (i < other.numValues)
remainder += other.values[i]; remainder += other.values[i];
values[i] = (unsigned int) remainder;
values[i] = (uint32) remainder;
remainder >>= 32; remainder >>= 32;
} }
@@ -410,8 +410,8 @@ BigInteger& BigInteger::operator-= (const BigInteger& other)
return *this; return *this;
} }
const int numInts = (highestBit >> 5) + 1;
const int maxOtherInts = (other.highestBit >> 5) + 1;
const int numInts = bitToIndex (highestBit) + 1;
const int maxOtherInts = bitToIndex (other.highestBit) + 1;
int64 amountToSubtract = 0; int64 amountToSubtract = 0;
for (int i = 0; i <= numInts; ++i) for (int i = 0; i <= numInts; ++i)
@@ -421,13 +421,13 @@ BigInteger& BigInteger::operator-= (const BigInteger& other)
if (values[i] >= amountToSubtract) if (values[i] >= amountToSubtract)
{ {
values[i] = (unsigned int) (values[i] - amountToSubtract);
values[i] = (uint32) (values[i] - amountToSubtract);
amountToSubtract = 0; amountToSubtract = 0;
} }
else else
{ {
const int64 n = ((int64) values[i] + (((int64) 1) << 32)) - amountToSubtract; const int64 n = ((int64) values[i] + (((int64) 1) << 32)) - amountToSubtract;
values[i] = (unsigned int) n;
values[i] = (uint32) n;
amountToSubtract = 1; amountToSubtract = 1;
} }
} }
@@ -516,9 +516,9 @@ BigInteger& BigInteger::operator|= (const BigInteger& other)
if (other.highestBit >= 0) if (other.highestBit >= 0)
{ {
ensureSize (other.highestBit >> 5);
ensureSize (bitToIndex (other.highestBit));
int n = (other.highestBit >> 5) + 1;
int n = bitToIndex (other.highestBit) + 1;
while (--n >= 0) while (--n >= 0)
values[n] |= other.values[n]; values[n] |= other.values[n];
@@ -559,9 +559,9 @@ BigInteger& BigInteger::operator^= (const BigInteger& other)
if (other.highestBit >= 0) if (other.highestBit >= 0)
{ {
ensureSize (other.highestBit >> 5);
ensureSize (bitToIndex (other.highestBit));
int n = (other.highestBit >> 5) + 1;
int n = bitToIndex (other.highestBit) + 1;
while (--n >= 0) while (--n >= 0)
values[n] ^= other.values[n]; values[n] ^= other.values[n];
@@ -635,7 +635,7 @@ int BigInteger::compareAbsolute (const BigInteger& other) const throw()
else if (h1 < h2) else if (h1 < h2)
return -1; return -1;
for (int i = (h1 >> 5) + 1; --i >= 0;)
for (int i = bitToIndex (h1) + 1; --i >= 0;)
if (values[i] != other.values[i]) if (values[i] != other.values[i])
return (values[i] > other.values[i]) ? 1 : -1; return (values[i] > other.values[i]) ? 1 : -1;
@@ -688,8 +688,8 @@ void BigInteger::shiftBits (int bits, const int startBit)
} }
else else
{ {
const int wordsToMove = bits >> 5;
int top = 1 + (highestBit >> 5) - wordsToMove;
const int wordsToMove = bitToIndex (bits);
int top = 1 + bitToIndex (highestBit) - wordsToMove;
highestBit -= bits; highestBit -= bits;
if (wordsToMove > 0) if (wordsToMove > 0)
@@ -721,10 +721,10 @@ void BigInteger::shiftBits (int bits, const int startBit)
else if (bits > 0) else if (bits > 0)
{ {
// left shift // left shift
ensureSize (((highestBit + bits) >> 5) + 1);
ensureSize (bitToIndex (highestBit + bits) + 1);
const int wordsToMove = bits >> 5;
int top = 1 + (highestBit >> 5);
const int wordsToMove = bitToIndex (bits);
int top = 1 + bitToIndex (highestBit);
highestBit += bits; highestBit += bits;
if (wordsToMove > 0) if (wordsToMove > 0)
@@ -931,7 +931,7 @@ void BigInteger::parseString (const String& text, const int base)
const juce_wchar c = *t++; const juce_wchar c = *t++;
const int digit = CharacterFunctions::getHexDigitValue (c); const int digit = CharacterFunctions::getHexDigitValue (c);
if (((unsigned int) digit) < (unsigned int) base)
if (((uint32) digit) < (uint32) base)
{ {
operator<<= (bits); operator<<= (bits);
operator+= (digit); operator+= (digit);
@@ -944,7 +944,7 @@ void BigInteger::parseString (const String& text, const int base)
} }
else if (base == 10) else if (base == 10)
{ {
const BigInteger ten ((unsigned int) 10);
const BigInteger ten ((uint32) 10);
for (;;) for (;;)
{ {


+ 7
- 4
src/containers/juce_BigInteger.h View File

@@ -52,14 +52,14 @@ public:
The low 32 bits of the number are initialised with this value. The low 32 bits of the number are initialised with this value.
*/ */
BigInteger (unsigned int value);
BigInteger (uint32 value);
/** Creates a BigInteger containing an integer value in its low bits. /** Creates a BigInteger containing an integer value in its low bits.
The low 32 bits of the number are initialised with the absolute value The low 32 bits of the number are initialised with the absolute value
passed in, and its sign is set to reflect the sign of the number. passed in, and its sign is set to reflect the sign of the number.
*/ */
BigInteger (int value);
BigInteger (int32 value);
/** Creates a BigInteger containing an integer value in its low bits. /** Creates a BigInteger containing an integer value in its low bits.
@@ -143,7 +143,7 @@ public:
Copies the given integer onto a range of bits, starting at startBit, Copies the given integer onto a range of bits, starting at startBit,
and using up to numBits of the available bits. and using up to numBits of the available bits.
*/ */
void setBitRangeAsInt (int startBit, int numBits, unsigned int valueToSet);
void setBitRangeAsInt (int startBit, int numBits, uint32 valueToSet);
/** Shifts a section of bits left or right. /** Shifts a section of bits left or right.
@@ -308,12 +308,15 @@ public:
juce_UseDebuggingNewOperator juce_UseDebuggingNewOperator
private: private:
HeapBlock <unsigned int> values;
HeapBlock <uint32> values;
int numValues, highestBit; int numValues, highestBit;
bool negative; bool negative;
void ensureSize (int numVals); void ensureSize (int numVals);
static const BigInteger simpleGCD (BigInteger* m, BigInteger* n); static const BigInteger simpleGCD (BigInteger* m, BigInteger* n);
static inline int bitToIndex (const int bit) throw() { return bit >> 5; }
static inline uint32 bitToMask (const int bit) throw() { return 1 << (bit & 31); }
}; };
/** Writes a BigInteger to an OutputStream as a UTF8 decimal string. */ /** Writes a BigInteger to an OutputStream as a UTF8 decimal string. */


+ 3
- 0
src/core/juce_Atomic.h View File

@@ -150,6 +150,9 @@ private:
static inline Type castFrom64Bit (int64 value) throw() { return *(Type*) &value; } static inline Type castFrom64Bit (int64 value) throw() { return *(Type*) &value; }
static inline int32 castTo32Bit (Type value) throw() { return *(int32*) &value; } static inline int32 castTo32Bit (Type value) throw() { return *(int32*) &value; }
static inline int64 castTo64Bit (Type value) throw() { return *(int64*) &value; } static inline int64 castTo64Bit (Type value) throw() { return *(int64*) &value; }
Type operator++ (int); // better to just use pre-increment with atomics..
Type operator-- (int);
}; };


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

@@ -33,7 +33,7 @@
*/ */
#define JUCE_MAJOR_VERSION 1 #define JUCE_MAJOR_VERSION 1
#define JUCE_MINOR_VERSION 52 #define JUCE_MINOR_VERSION 52
#define JUCE_BUILDNUMBER 75
#define JUCE_BUILDNUMBER 76
/** Current Juce version number. /** Current Juce version number.


+ 19
- 1
src/gui/components/juce_Desktop.cpp View File

@@ -37,7 +37,8 @@ BEGIN_JUCE_NAMESPACE
//============================================================================== //==============================================================================
Desktop::Desktop() Desktop::Desktop()
: mouseClickCounter (0), : mouseClickCounter (0),
kioskModeComponent (0)
kioskModeComponent (0),
allowedOrientations (allOrientations)
{ {
createMouseInputSources(); createMouseInputSources();
refreshMonitorSizes(); refreshMonitorSizes();
@@ -359,5 +360,22 @@ void Desktop::setKioskModeComponent (Component* componentToUse, const bool allow
} }
} }
//==============================================================================
void Desktop::setOrientationsEnabled (const int newOrientations)
{
// Dodgy set of flags being passed here! Make sure you specify at least one permitted orientation.
jassert (newOrientations != 0 && (newOrientations & ~allOrientations) == 0);
allowedOrientations = newOrientations;
}
bool Desktop::isOrientationEnabled (const DisplayOrientation orientation) const throw()
{
// Make sure you only pass one valid flag in here...
jassert (orientation == upright || orientation == upsideDown || orientation == rotatedClockwise || orientation == rotatedAntiClockwise);
return (allowedOrientations & orientation) != 0;
}
END_JUCE_NAMESPACE END_JUCE_NAMESPACE

+ 32
- 0
src/gui/components/juce_Desktop.h View File

@@ -261,6 +261,36 @@ public:
*/ */
MouseInputSource* getDraggingMouseSource (int index) const throw(); MouseInputSource* getDraggingMouseSource (int index) const throw();
//==============================================================================
/** In a tablet device which can be turned around, this is used to inidicate the orientation. */
enum DisplayOrientation
{
upright = 1, /**< Indicates that the display is the normal way up. */
upsideDown = 2, /**< Indicates that the display is upside-down. */
rotatedClockwise = 4, /**< Indicates that the display is turned 90 degrees clockwise from its upright position. */
rotatedAntiClockwise = 8, /**< Indicates that the display is turned 90 degrees anti-clockwise from its upright position. */
allOrientations = 1 + 2 + 4 + 8 /**< A combination of all the orientation values */
};
/** In a tablet device which can be turned around, this returns the current orientation. */
DisplayOrientation getCurrentOrientation() const;
/** Sets which orientations the display is allowed to auto-rotate to.
For devices that support rotating desktops, this lets you specify which of the orientations your app can use.
The parameter is a bitwise or-ed combination of the values in DisplayOrientation, and must contain at least one
set bit.
*/
void setOrientationsEnabled (int allowedOrientations);
/** Returns whether the display is allowed to auto-rotate to the given orientation.
Each orientation can be enabled using setOrientationEnabled(). By default, all orientations are allowed.
*/
bool isOrientationEnabled (DisplayOrientation orientation) const throw();
//============================================================================== //==============================================================================
juce_UseDebuggingNewOperator juce_UseDebuggingNewOperator
@@ -302,6 +332,8 @@ private:
Component* kioskModeComponent; Component* kioskModeComponent;
Rectangle<int> kioskComponentOriginalBounds; Rectangle<int> kioskComponentOriginalBounds;
int allowedOrientations;
void timerCallback(); void timerCallback();
void resetTimer(); void resetTimer();


+ 6
- 4
src/gui/components/windows/juce_CallOutBox.cpp View File

@@ -43,11 +43,13 @@ CallOutBox::CallOutBox (Component& contentComponent,
if (parentComponent != 0) if (parentComponent != 0)
{ {
updatePosition (parentComponent->getLocalBounds(),
componentToPointTo.getLocalBounds()
+ componentToPointTo.relativePositionToOtherComponent (parentComponent, Point<int>()));
parentComponent->addChildComponent (this);
parentComponent->addAndMakeVisible (this);
updatePosition (componentToPointTo.getLocalBounds()
+ componentToPointTo.relativePositionToOtherComponent (parentComponent, Point<int>()),
parentComponent->getLocalBounds());
setVisible (true);
} }
else else
{ {


+ 1
- 1
src/gui/components/windows/juce_ResizableWindow.cpp View File

@@ -400,7 +400,7 @@ void ResizableWindow::setFullScreen (const bool shouldBeFullScreen)
peer->setFullScreen (shouldBeFullScreen); peer->setFullScreen (shouldBeFullScreen);
if (! shouldBeFullScreen)
if ((! shouldBeFullScreen) && ! lastPos.isEmpty())
setBounds (lastPos); setBounds (lastPos);
} }
else else


+ 18
- 0
src/native/juce_mac_NativeCode.mm View File

@@ -88,6 +88,24 @@ BEGIN_JUCE_NAMESPACE
#include "common/juce_MidiDataConcatenator.h" #include "common/juce_MidiDataConcatenator.h"
#undef Point #undef Point
template <class RectType>
static const Rectangle<int> convertToRectInt (const RectType& r)
{
return Rectangle<int> ((int) r.origin.x, (int) r.origin.y, (int) r.size.width, (int) r.size.height);
}
template <class RectType>
static const Rectangle<float> convertToRectFloat (const RectType& r)
{
return Rectangle<float> (r.origin.x, r.origin.y, r.size.width, r.size.height);
}
template <class RectType>
static CGRect convertToCGRect (const RectType& r)
{
return CGRectMake ((CGFloat) r.getX(), (CGFloat) r.getY(), (CGFloat) r.getWidth(), (CGFloat) r.getHeight());
}
//============================================================================== //==============================================================================
#define JUCE_INCLUDED_FILE 1 #define JUCE_INCLUDED_FILE 1


+ 7
- 3
src/native/linux/juce_linux_Windowing.cpp View File

@@ -1098,15 +1098,15 @@ public:
const int width = image.getWidth(); const int width = image.getWidth();
const int height = image.getHeight(); const int height = image.getHeight();
HeapBlock <char> colour (width * height);
HeapBlock <uint32> colour (width * height);
int index = 0; int index = 0;
for (int y = 0; y < height; ++y) for (int y = 0; y < height; ++y)
for (int x = 0; x < width; ++x) for (int x = 0; x < width; ++x)
colour[index++] = static_cast<char> (image.getPixelAt (x, y).getARGB());
colour[index++] = image.getPixelAt (x, y).getARGB();
XImage* ximage = XCreateImage (display, CopyFromParent, 24, ZPixmap, XImage* ximage = XCreateImage (display, CopyFromParent, 24, ZPixmap,
0, colour.getData(),
0, reinterpret_cast<char*> (colour.getData()),
width, height, 32, 0); width, height, 32, 0);
Pixmap pixmap = XCreatePixmap (display, DefaultRootWindow (display), Pixmap pixmap = XCreatePixmap (display, DefaultRootWindow (display),
@@ -2902,6 +2902,10 @@ void Desktop::setMousePosition (const Point<int>& newPosition)
XWarpPointer (display, None, root, 0, 0, 0, 0, newPosition.getX(), newPosition.getY()); XWarpPointer (display, None, root, 0, 0, 0, 0, newPosition.getX(), newPosition.getY());
} }
Desktop::DisplayOrientation Desktop::getCurrentOrientation() const
{
return upright;
}
//============================================================================== //==============================================================================
static bool screenSaverAllowed = true; static bool screenSaverAllowed = true;


+ 0
- 16
src/native/mac/juce_iphone_MiscUtilities.mm View File

@@ -177,22 +177,6 @@ bool Desktop::isScreenSaverEnabled()
} }
//==============================================================================
void juce_updateMultiMonitorInfo (Array <Rectangle <int> >& monitorCoords, const bool clipToWorkArea)
{
const ScopedAutoReleasePool pool;
monitorCoords.clear();
CGRect r = clipToWorkArea ? [[UIScreen mainScreen] applicationFrame]
: [[UIScreen mainScreen] bounds];
monitorCoords.add (Rectangle<int> ((int) r.origin.x,
(int) r.origin.y,
(int) r.size.width,
(int) r.size.height));
}
#endif #endif
#endif #endif

+ 182
- 54
src/native/mac/juce_iphone_UIViewComponentPeer.mm View File

@@ -61,6 +61,16 @@ END_JUCE_NAMESPACE
@end @end
#define JuceUIViewController MakeObjCClassName(JuceUIViewController)
@interface JuceUIViewController : UIViewController
{
}
- (BOOL) shouldAutorotateToInterfaceOrientation: (UIInterfaceOrientation) interfaceOrientation;
- (void) didRotateFromInterfaceOrientation: (UIInterfaceOrientation) fromInterfaceOrientation;
@end
//============================================================================== //==============================================================================
#define JuceUIWindow MakeObjCClassName(JuceUIWindow) #define JuceUIWindow MakeObjCClassName(JuceUIWindow)
@@ -131,6 +141,9 @@ public:
void updateHiddenTextContent (TextInputTarget* target); void updateHiddenTextContent (TextInputTarget* target);
void globalFocusChanged (Component*); void globalFocusChanged (Component*);
virtual BOOL shouldRotate (UIInterfaceOrientation interfaceOrientation);
virtual void displayRotated();
void handleTouches (UIEvent* e, bool isDown, bool isUp, bool isCancel); void handleTouches (UIEvent* e, bool isDown, bool isUp, bool isCancel);
//============================================================================== //==============================================================================
@@ -142,6 +155,7 @@ public:
UIWindow* window; UIWindow* window;
JuceUIView* view; JuceUIView* view;
JuceUIViewController* controller;
bool isSharedWindow, fullScreen, insideDrawRect; bool isSharedWindow, fullScreen, insideDrawRect;
static ModifierKeys currentModifiers; static ModifierKeys currentModifiers;
@@ -151,12 +165,84 @@ public:
+ (int64) ([e timestamp] * 1000.0); + (int64) ([e timestamp] * 1000.0);
} }
static const Rectangle<int> rotatedScreenPosToReal (const Rectangle<int>& r)
{
const Rectangle<int> screen (convertToRectInt ([[UIScreen mainScreen] bounds]));
switch ([[UIApplication sharedApplication] statusBarOrientation])
{
case UIInterfaceOrientationPortrait:
return r;
case UIInterfaceOrientationPortraitUpsideDown:
return Rectangle<int> (screen.getWidth() - r.getRight(), screen.getHeight() - r.getBottom(),
r.getWidth(), r.getHeight());
case UIInterfaceOrientationLandscapeLeft:
return Rectangle<int> (r.getY(), screen.getHeight() - r.getRight(),
r.getHeight(), r.getWidth());
case UIInterfaceOrientationLandscapeRight:
return Rectangle<int> (screen.getWidth() - r.getBottom(), r.getX(),
r.getHeight(), r.getWidth());
default: jassertfalse; // unknown orientation!
}
return r;
}
static const Rectangle<int> realScreenPosToRotated (const Rectangle<int>& r)
{
const Rectangle<int> screen (convertToRectInt ([[UIScreen mainScreen] bounds]));
switch ([[UIApplication sharedApplication] statusBarOrientation])
{
case UIInterfaceOrientationPortrait:
return r;
case UIInterfaceOrientationPortraitUpsideDown:
return Rectangle<int> (screen.getWidth() - r.getRight(), screen.getHeight() - r.getBottom(),
r.getWidth(), r.getHeight());
case UIInterfaceOrientationLandscapeLeft:
return Rectangle<int> (screen.getHeight() - r.getBottom(), r.getX(),
r.getHeight(), r.getWidth());
case UIInterfaceOrientationLandscapeRight:
return Rectangle<int> (r.getY(), screen.getWidth() - r.getRight(),
r.getHeight(), r.getWidth());
default: jassertfalse; // unknown orientation!
}
return r;
}
Array <UITouch*> currentTouches; Array <UITouch*> currentTouches;
}; };
//============================================================================== //==============================================================================
END_JUCE_NAMESPACE END_JUCE_NAMESPACE
@implementation JuceUIViewController
- (BOOL) shouldAutorotateToInterfaceOrientation: (UIInterfaceOrientation) interfaceOrientation
{
JuceUIView* juceView = (JuceUIView*) [self view];
jassert (juceView != 0 && juceView->owner != 0);
return juceView->owner->shouldRotate (interfaceOrientation);
}
- (void) didRotateFromInterfaceOrientation: (UIInterfaceOrientation) fromInterfaceOrientation
{
JuceUIView* juceView = (JuceUIView*) [self view];
jassert (juceView != 0 && juceView->owner != 0);
juceView->owner->displayRotated();
}
@end
@implementation JuceUIView @implementation JuceUIView
- (JuceUIView*) initWithOwner: (UIViewComponentPeer*) owner_ - (JuceUIView*) initWithOwner: (UIViewComponentPeer*) owner_
@@ -302,12 +388,12 @@ UIViewComponentPeer::UIViewComponentPeer (Component* const component,
UIView* viewToAttachTo) UIView* viewToAttachTo)
: ComponentPeer (component, windowStyleFlags), : ComponentPeer (component, windowStyleFlags),
window (0), window (0),
view (0),
view (0), controller (0),
isSharedWindow (viewToAttachTo != 0), isSharedWindow (viewToAttachTo != 0),
fullScreen (false), fullScreen (false),
insideDrawRect (false) insideDrawRect (false)
{ {
CGRect r = CGRectMake (0, 0, (float) component->getWidth(), (float) component->getHeight());
CGRect r = convertToCGRect (component->getLocalBounds());
view = [[JuceUIView alloc] initWithOwner: this withFrame: r]; view = [[JuceUIView alloc] initWithOwner: this withFrame: r];
@@ -320,8 +406,10 @@ UIViewComponentPeer::UIViewComponentPeer (Component* const component,
} }
else else
{ {
r.origin.x = (float) component->getX();
r.origin.y = (float) component->getY();
controller = [[JuceUIViewController alloc] init];
controller.view = view;
r = convertToCGRect (rotatedScreenPosToReal (component->getBounds()));
r.origin.y = [[UIScreen mainScreen] bounds].size.height - (r.origin.y + r.size.height); r.origin.y = [[UIScreen mainScreen] bounds].size.height - (r.origin.y + r.size.height);
window = [[JuceUIWindow alloc] init]; window = [[JuceUIWindow alloc] init];
@@ -358,6 +446,7 @@ UIViewComponentPeer::~UIViewComponentPeer()
view->owner = 0; view->owner = 0;
[view removeFromSuperview]; [view removeFromSuperview];
[view release]; [view release];
[controller release];
if (! isSharedWindow) if (! isSharedWindow)
{ {
@@ -401,15 +490,9 @@ void UIViewComponentPeer::setBounds (int x, int y, int w, int h, const bool isNo
w = jmax (0, w); w = jmax (0, w);
h = jmax (0, h); h = jmax (0, h);
CGRect r;
r.origin.x = (float) x;
r.origin.y = (float) y;
r.size.width = (float) w;
r.size.height = (float) h;
if (isSharedWindow) if (isSharedWindow)
{ {
//r.origin.y = [[view superview] frame].size.height - (r.origin.y + r.size.height);
CGRect r = CGRectMake ((float) x, (float) y, (float) w, (float) h);
if ([view frame].size.width != r.size.width if ([view frame].size.width != r.size.width
|| [view frame].size.height != r.size.height) || [view frame].size.height != r.size.height)
@@ -419,8 +502,11 @@ void UIViewComponentPeer::setBounds (int x, int y, int w, int h, const bool isNo
} }
else else
{ {
window.frame = r;
view.frame = CGRectMake (0, 0, r.size.width, r.size.height);
const Rectangle<int> bounds (rotatedScreenPosToReal (Rectangle<int> (x, y, w, h)));
window.frame = convertToCGRect (bounds);
view.frame = CGRectMake (0, 0, (float) bounds.getWidth(), (float) bounds.getHeight());
handleMovedOrResized();
} }
} }
@@ -432,12 +518,14 @@ const Rectangle<int> UIViewComponentPeer::getBounds (const bool global) const
{ {
r = [view convertRect: r toView: nil]; r = [view convertRect: r toView: nil];
CGRect wr = [[view window] frame]; CGRect wr = [[view window] frame];
r.origin.x += wr.origin.x;
r.origin.y += wr.origin.y;
const Rectangle<int> windowBounds (realScreenPosToRotated (convertToRectInt (wr)));
r.origin.x = windowBounds.getX();
r.origin.y = windowBounds.getY();
} }
return Rectangle<int> ((int) r.origin.x, (int) r.origin.y,
(int) r.size.width, (int) r.size.height);
return convertToRectInt (r);
} }
const Rectangle<int> UIViewComponentPeer::getBounds() const const Rectangle<int> UIViewComponentPeer::getBounds() const
@@ -469,11 +557,8 @@ CGRect UIViewComponentPeer::constrainRect (CGRect r)
r.origin.y = [[UIScreen mainScreen] bounds].size.height - r.origin.y - r.size.height; r.origin.y = [[UIScreen mainScreen] bounds].size.height - r.origin.y - r.size.height;
Rectangle<int> pos ((int) r.origin.x, (int) r.origin.y,
(int) r.size.width, (int) r.size.height);
Rectangle<int> original ((int) current.origin.x, (int) current.origin.y,
(int) current.size.width, (int) current.size.height);
Rectangle<int> pos (convertToRectInt (r));
Rectangle<int> original (convertToRectInt (current));
constrainer->checkBounds (pos, original, constrainer->checkBounds (pos, original,
Desktop::getInstance().getAllMonitorDisplayAreas().getBounds(), Desktop::getInstance().getAllMonitorDisplayAreas().getBounds(),
@@ -493,7 +578,6 @@ CGRect UIViewComponentPeer::constrainRect (CGRect r)
void UIViewComponentPeer::setMinimised (bool shouldBeMinimised) void UIViewComponentPeer::setMinimised (bool shouldBeMinimised)
{ {
// xxx
} }
bool UIViewComponentPeer::isMinimised() const bool UIViewComponentPeer::isMinimised() const
@@ -505,19 +589,17 @@ void UIViewComponentPeer::setFullScreen (bool shouldBeFullScreen)
{ {
if (! isSharedWindow) if (! isSharedWindow)
{ {
Rectangle<int> r (lastNonFullscreenBounds);
Rectangle<int> r (shouldBeFullScreen ? Desktop::getInstance().getMainMonitorArea()
: lastNonFullscreenBounds);
setMinimised (false);
if ((! shouldBeFullScreen) && r.isEmpty())
r = getBounds();
if (fullScreen != shouldBeFullScreen)
{
if (shouldBeFullScreen)
r = Desktop::getInstance().getMainMonitorArea();
// (can't call the component's setBounds method because that'll reset our fullscreen flag)
if (! r.isEmpty())
setBounds (r.getX(), r.getY(), r.getWidth(), r.getHeight(), shouldBeFullScreen);
// (can't call the component's setBounds method because that'll reset our fullscreen flag)
if (r != getComponent()->getBounds() && ! r.isEmpty())
setBounds (r.getX(), r.getY(), r.getWidth(), r.getHeight(), shouldBeFullScreen);
}
component->repaint();
} }
} }
@@ -526,17 +608,61 @@ bool UIViewComponentPeer::isFullScreen() const
return fullScreen; return fullScreen;
} }
static Desktop::DisplayOrientation convertToJuceOrientation (UIInterfaceOrientation interfaceOrientation)
{
switch (interfaceOrientation)
{
case UIInterfaceOrientationPortrait: return Desktop::upright;
case UIInterfaceOrientationPortraitUpsideDown: return Desktop::upsideDown;
case UIInterfaceOrientationLandscapeLeft: return Desktop::rotatedClockwise;
case UIInterfaceOrientationLandscapeRight: return Desktop::rotatedAntiClockwise;
default: jassertfalse; // unknown orientation!
}
return Desktop::upright;
}
BOOL UIViewComponentPeer::shouldRotate (UIInterfaceOrientation interfaceOrientation)
{
return Desktop::getInstance().isOrientationEnabled (convertToJuceOrientation (interfaceOrientation));
}
void UIViewComponentPeer::displayRotated()
{
const Rectangle<int> oldArea (component->getBounds());
const Rectangle<int> oldDesktop (Desktop::getInstance().getMainMonitorArea());
Desktop::getInstance().refreshMonitorSizes();
if (fullScreen)
{
fullScreen = false;
setFullScreen (true);
}
else
{
const float l = oldArea.getX() / (float) oldDesktop.getWidth();
const float r = oldArea.getRight() / (float) oldDesktop.getWidth();
const float t = oldArea.getY() / (float) oldDesktop.getHeight();
const float b = oldArea.getBottom() / (float) oldDesktop.getHeight();
const Rectangle<int> newDesktop (Desktop::getInstance().getMainMonitorArea());
setBounds ((int) (l * newDesktop.getWidth()),
(int) (t * newDesktop.getHeight()),
(int) ((r - l) * newDesktop.getWidth()),
(int) ((b - t) * newDesktop.getHeight()),
false);
}
}
bool UIViewComponentPeer::contains (const Point<int>& position, bool trueIfInAChildWindow) const bool UIViewComponentPeer::contains (const Point<int>& position, bool trueIfInAChildWindow) const
{ {
if (((unsigned int) position.getX()) >= (unsigned int) component->getWidth() if (((unsigned int) position.getX()) >= (unsigned int) component->getWidth()
|| ((unsigned int) position.getY()) >= (unsigned int) component->getHeight()) || ((unsigned int) position.getY()) >= (unsigned int) component->getHeight())
return false; return false;
CGPoint p;
p.x = (float) position.getX();
p.y = (float) position.getY();
UIView* v = [view hitTest: p withEvent: nil];
UIView* v = [view hitTest: CGPointMake ((float) position.getX(), (float) position.getY())
withEvent: nil];
if (trueIfInAChildWindow) if (trueIfInAChildWindow)
return v != nil; return v != nil;
@@ -546,20 +672,7 @@ bool UIViewComponentPeer::contains (const Point<int>& position, bool trueIfInACh
const BorderSize UIViewComponentPeer::getFrameSize() const const BorderSize UIViewComponentPeer::getFrameSize() const
{ {
BorderSize b;
if (! isSharedWindow)
{
CGRect v = [view convertRect: [view frame] toView: nil];
CGRect w = [window frame];
b.setTop ((int) (w.size.height - (v.origin.y + v.size.height)));
b.setBottom ((int) v.origin.y);
b.setLeft ((int) v.origin.x);
b.setRight ((int) (w.size.width - (v.origin.x + v.size.width)));
}
return b;
return BorderSize();
} }
bool UIViewComponentPeer::setAlwaysOnTop (bool alwaysOnTop) bool UIViewComponentPeer::setAlwaysOnTop (bool alwaysOnTop)
@@ -824,8 +937,7 @@ void UIViewComponentPeer::repaint (const Rectangle<int>& area)
} }
else else
{ {
[view setNeedsDisplayInRect: CGRectMake ((float) area.getX(), (float) area.getY(),
(float) area.getWidth(), (float) area.getHeight())];
[view setNeedsDisplayInRect: convertToCGRect (area)];
} }
} }
@@ -865,6 +977,22 @@ void Desktop::setMousePosition (const Point<int>&)
{ {
} }
Desktop::DisplayOrientation Desktop::getCurrentOrientation() const
{
return convertToJuceOrientation ([[UIApplication sharedApplication] statusBarOrientation]);
}
void juce_updateMultiMonitorInfo (Array <Rectangle <int> >& monitorCoords, const bool clipToWorkArea)
{
const ScopedAutoReleasePool pool;
monitorCoords.clear();
CGRect r = clipToWorkArea ? [[UIScreen mainScreen] applicationFrame]
: [[UIScreen mainScreen] bounds];
monitorCoords.add (UIViewComponentPeer::realScreenPosToRotated (convertToRectInt (r)));
}
//============================================================================== //==============================================================================
const int KeyPress::spaceKey = ' '; const int KeyPress::spaceKey = ' ';
const int KeyPress::returnKey = 0x0d; const int KeyPress::returnKey = 0x0d;


+ 8
- 4
src/native/mac/juce_mac_MiscUtilities.mm View File

@@ -159,6 +159,11 @@ void Desktop::setMousePosition (const Point<int>& newPosition)
CGAssociateMouseAndMouseCursorPosition (true); CGAssociateMouseAndMouseCursorPosition (true);
} }
Desktop::DisplayOrientation Desktop::getCurrentOrientation() const
{
return upright;
}
//============================================================================== //==============================================================================
#if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5 #if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5
class ScreenSaverDefeater : public Timer, class ScreenSaverDefeater : public Timer,
@@ -246,10 +251,9 @@ void juce_updateMultiMonitorInfo (Array <Rectangle<int> >& monitorCoords, const
NSRect r = clipToWorkArea ? [s visibleFrame] NSRect r = clipToWorkArea ? [s visibleFrame]
: [s frame]; : [s frame];
monitorCoords.add (Rectangle<int> ((int) r.origin.x,
(int) (mainScreenBottom - (r.origin.y + r.size.height)),
(int) r.size.width,
(int) r.size.height));
r.origin.y = mainScreenBottom - (r.origin.y + r.size.height);
monitorCoords.add (convertToRectInt (r));
} }
jassert (monitorCoords.size() > 0); jassert (monitorCoords.size() > 0);


+ 3
- 6
src/native/mac/juce_mac_NSViewComponentPeer.mm View File

@@ -1034,7 +1034,7 @@ const Rectangle<int> NSViewComponentPeer::getBounds (const bool global) const
r.origin.y = [[view superview] frame].size.height - r.origin.y - r.size.height; r.origin.y = [[view superview] frame].size.height - r.origin.y - r.size.height;
} }
return Rectangle<int> ((int) r.origin.x, (int) r.origin.y, (int) r.size.width, (int) r.size.height);
return Rectangle<int> (convertToRectInt (r));
} }
const Rectangle<int> NSViewComponentPeer::getBounds() const const Rectangle<int> NSViewComponentPeer::getBounds() const
@@ -1066,11 +1066,8 @@ NSRect NSViewComponentPeer::constrainRect (NSRect r)
r.origin.y = [[[NSScreen screens] objectAtIndex: 0] frame].size.height - r.origin.y - r.size.height; r.origin.y = [[[NSScreen screens] objectAtIndex: 0] frame].size.height - r.origin.y - r.size.height;
Rectangle<int> pos ((int) r.origin.x, (int) r.origin.y,
(int) r.size.width, (int) r.size.height);
Rectangle<int> original ((int) current.origin.x, (int) current.origin.y,
(int) current.size.width, (int) current.size.height);
Rectangle<int> pos (convertToRectInt (r));
Rectangle<int> original (convertToRectInt (current));
constrainer->checkBounds (pos, original, constrainer->checkBounds (pos, original,
Desktop::getInstance().getAllMonitorDisplayAreas().getBounds(), Desktop::getInstance().getAllMonitorDisplayAreas().getBounds(),


+ 5
- 0
src/native/windows/juce_win32_Windowing.cpp View File

@@ -81,6 +81,11 @@ bool Desktop::canUseSemiTransparentWindows() throw()
return updateLayeredWindow != 0; return updateLayeredWindow != 0;
} }
Desktop::DisplayOrientation Desktop::getCurrentOrientation() const
{
return upright;
}
//============================================================================== //==============================================================================
const int extendedKeyModifier = 0x10000; const int extendedKeyModifier = 0x10000;


+ 16
- 0
src/utilities/juce_UnitTest.cpp View File

@@ -49,11 +49,17 @@ Array<UnitTest*>& UnitTest::getAllTests()
return tests; return tests;
} }
void UnitTest::initalise() {}
void UnitTest::shutdown() {}
void UnitTest::performTest (UnitTestRunner* const runner_) void UnitTest::performTest (UnitTestRunner* const runner_)
{ {
jassert (runner_ != 0); jassert (runner_ != 0);
runner = runner_; runner = runner_;
initalise();
runTest(); runTest();
shutdown();
} }
void UnitTest::logMessage (const String& message) void UnitTest::logMessage (const String& message)
@@ -84,6 +90,16 @@ UnitTestRunner::~UnitTestRunner()
{ {
} }
int UnitTestRunner::getNumResults() const throw()
{
return results.size();
}
const UnitTestRunner::TestResult* UnitTestRunner::getResult (int index) const throw()
{
return results [index];
}
void UnitTestRunner::resultsUpdated() void UnitTestRunner::resultsUpdated()
{ {
} }


+ 29
- 0
src/utilities/juce_UnitTest.h View File

@@ -92,6 +92,16 @@ public:
static Array<UnitTest*>& getAllTests(); static Array<UnitTest*>& getAllTests();
//============================================================================== //==============================================================================
/** You can optionally implement this method to set up your test.
This method will be called before runTest().
*/
virtual void initalise();
/** You can optionally implement this method to clear up after your test has been run.
This method will be called after runTest() has returned.
*/
virtual void shutdown();
/** Implement this method in your subclass to actually run your tests. /** Implement this method in your subclass to actually run your tests.
The content of your implementation should call beginTest() and expect() The content of your implementation should call beginTest() and expect()
@@ -127,6 +137,25 @@ public:
*/ */
void expect (bool testResult, const String& failureMessage = String::empty); void expect (bool testResult, const String& failureMessage = String::empty);
/** Compares two values, and if they don't match, prints out a message containing the
expected and actual result values.
*/
template <class ValueType>
void expectEquals (ValueType actual, ValueType expected, String failureMessage = String::empty)
{
const bool result = (actual == expected);
if (! result)
{
if (failureMessage.isNotEmpty())
failureMessage << " -- ";
failureMessage << "Expected value: " << expected << ", Actual value: " << actual;
}
expect (result, failureMessage);
}
//============================================================================== //==============================================================================
/** Writes a message to the test log. /** Writes a message to the test log.
This can only be called from within your runTest() method. This can only be called from within your runTest() method.


Loading…
Cancel
Save