Browse Source

OSX10.4 menu fix. Graphics::drawSingleLineText justification.

tags/2021-05-28
jules 14 years ago
parent
commit
27d7185f34
13 changed files with 110 additions and 39 deletions
  1. +1
    -1
      modules/juce_audio_utils/gui/juce_AudioThumbnailCache.cpp
  2. +25
    -0
      modules/juce_core/maths/juce_MathsFunctions.h
  3. +1
    -1
      modules/juce_core/streams/juce_InputStream.cpp
  4. +1
    -1
      modules/juce_core/streams/juce_InputStream.h
  5. +21
    -2
      modules/juce_graphics/contexts/juce_GraphicsContext.cpp
  6. +7
    -4
      modules/juce_graphics/contexts/juce_GraphicsContext.h
  7. +23
    -23
      modules/juce_graphics/contexts/juce_LowLevelGraphicsSoftwareRenderer.cpp
  8. +3
    -3
      modules/juce_graphics/geometry/juce_EdgeTable.h
  9. +1
    -1
      modules/juce_gui_basics/components/juce_Component.cpp
  10. +24
    -0
      modules/juce_gui_basics/native/juce_mac_MainMenu.mm
  11. +1
    -1
      modules/juce_gui_basics/widgets/juce_TextEditor.cpp
  12. +1
    -1
      modules/juce_gui_extra/native/juce_ios_UIViewComponent.mm
  13. +1
    -1
      modules/juce_gui_extra/native/juce_mac_NSViewComponent.mm

+ 1
- 1
modules/juce_audio_utils/gui/juce_AudioThumbnailCache.cpp View File

@@ -40,7 +40,7 @@ public:
{ {
hash = in.readInt64(); hash = in.readInt64();
const int64 len = in.readInt64(); const int64 len = in.readInt64();
in.readIntoMemoryBlock (data, len);
in.readIntoMemoryBlock (data, (ssize_t) len);
} }
void write (OutputStream& out) void write (OutputStream& out)


+ 25
- 0
modules/juce_core/maths/juce_MathsFunctions.h View File

@@ -91,6 +91,10 @@ typedef unsigned int uint32;
typedef unsigned int pointer_sized_uint; typedef unsigned int pointer_sized_uint;
#endif #endif
#if JUCE_MSVC
typedef pointer_sized_int ssize_t;
#endif
//============================================================================== //==============================================================================
// Some indispensible min/max functions // Some indispensible min/max functions
@@ -351,6 +355,10 @@ inline bool juce_isfinite (FloatingPointType value)
} }
//============================================================================== //==============================================================================
#if JUCE_MSVC
#pragma optimize ("t", off)
#endif
/** Fast floating-point-to-integer conversion. /** Fast floating-point-to-integer conversion.
This is faster than using the normal c++ cast to convert a float to an int, and This is faster than using the normal c++ cast to convert a float to an int, and
@@ -374,6 +382,10 @@ inline int roundToInt (const FloatType value) noexcept
#endif #endif
} }
#if JUCE_MSVC
#pragma optimize ("", on) // resets optimisations to the project defaults
#endif
/** Fast floating-point-to-integer conversion. /** Fast floating-point-to-integer conversion.
This is a slightly slower and slightly more accurate version of roundDoubleToInt(). It works This is a slightly slower and slightly more accurate version of roundDoubleToInt(). It works
@@ -424,6 +436,19 @@ bool isPowerOfTwo (IntegerType value)
return (value & (value - 1)) == 0; return (value & (value - 1)) == 0;
} }
/** Returns the next power-of-two which is equal to or greater than the given integer.
*/
inline int nextPowerOfTwo (int n)
{
--n;
n |= (n >> 1);
n |= (n >> 2);
n |= (n >> 4);
n |= (n >> 8);
n |= (n >> 16);
return n + 1;
}
/** Performs a modulo operation, but can cope with the dividend being negative. /** Performs a modulo operation, but can cope with the dividend being negative.
The divisor must be greater than zero. The divisor must be greater than zero.
*/ */


+ 1
- 1
modules/juce_core/streams/juce_InputStream.cpp View File

@@ -199,7 +199,7 @@ String InputStream::readNextLine()
return String::fromUTF8 (data, (int) i); return String::fromUTF8 (data, (int) i);
} }
int InputStream::readIntoMemoryBlock (MemoryBlock& block, int numBytes)
int InputStream::readIntoMemoryBlock (MemoryBlock& block, ssize_t numBytes)
{ {
MemoryOutputStream mo (block, true); MemoryOutputStream mo (block, true);
return mo.writeFromInputStream (*this, numBytes); return mo.writeFromInputStream (*this, numBytes);


+ 1
- 1
modules/juce_core/streams/juce_InputStream.h View File

@@ -245,7 +245,7 @@ public:
@returns the number of bytes that were added to the memory block @returns the number of bytes that were added to the memory block
*/ */
virtual int readIntoMemoryBlock (MemoryBlock& destBlock, virtual int readIntoMemoryBlock (MemoryBlock& destBlock,
int maxNumBytesToRead = -1);
ssize_t maxNumBytesToRead = -1);
//============================================================================== //==============================================================================
/** Returns the offset of the next byte that will be read from the stream. /** Returns the offset of the next byte that will be read from the stream.


+ 21
- 2
modules/juce_graphics/contexts/juce_GraphicsContext.cpp View File

@@ -231,14 +231,33 @@ Font Graphics::getCurrentFont() const
} }
//============================================================================== //==============================================================================
void Graphics::drawSingleLineText (const String& text, const int startX, const int baselineY) const
void Graphics::drawSingleLineText (const String& text, const int startX, const int baselineY,
const Justification& justification) const
{ {
if (text.isNotEmpty() if (text.isNotEmpty()
&& startX < context->getClipBounds().getRight()) && startX < context->getClipBounds().getRight())
{ {
GlyphArrangement arr; GlyphArrangement arr;
arr.addLineOfText (context->getFont(), text, (float) startX, (float) baselineY); arr.addLineOfText (context->getFont(), text, (float) startX, (float) baselineY);
arr.draw (*this);
// Don't pass any vertical placement flags to this method - they'll be ignored.
jassert (justification.getOnlyVerticalFlags() == 0);
const int flags = justification.getOnlyHorizontalFlags();
if (flags != Justification::left)
{
float w = arr.getBoundingBox (0, -1, true).getWidth();
if ((flags & (Justification::horizontallyCentred | Justification::horizontallyJustified)) != 0)
w /= 2.0f;
arr.draw (*this, AffineTransform::translation (-w, 0));
}
else
{
arr.draw (*this);
}
} }
} }


+ 7
- 4
modules/juce_graphics/contexts/juce_GraphicsContext.h View File

@@ -138,13 +138,16 @@ public:
This will use the current colour (or brush) to fill the text. The font is the last This will use the current colour (or brush) to fill the text. The font is the last
one specified by setFont(). one specified by setFont().
@param text the string to draw
@param startX the position to draw the left-hand edge of the text
@param baselineY the position of the text's baseline
@param text the string to draw
@param startX the position to draw the left-hand edge of the text
@param baselineY the position of the text's baseline
@param justification the horizontal flags indicate which end of the text string is
anchored at the specified point.
@see drawMultiLineText, drawText, drawFittedText, GlyphArrangement::addLineOfText @see drawMultiLineText, drawText, drawFittedText, GlyphArrangement::addLineOfText
*/ */
void drawSingleLineText (const String& text, void drawSingleLineText (const String& text,
int startX, int baselineY) const;
int startX, int baselineY,
const Justification& justification = Justification::left) const;
/** Draws text across multiple lines. /** Draws text across multiple lines.


+ 23
- 23
modules/juce_graphics/contexts/juce_LowLevelGraphicsSoftwareRenderer.cpp View File

@@ -1012,7 +1012,7 @@ public:
virtual Ptr clipToPath (const Path& p, const AffineTransform& transform) = 0; virtual Ptr clipToPath (const Path& p, const AffineTransform& transform) = 0;
virtual Ptr clipToEdgeTable (const EdgeTable& et) = 0; virtual Ptr clipToEdgeTable (const EdgeTable& et) = 0;
virtual Ptr clipToImageAlpha (const Image& image, const AffineTransform& t, const bool betterQuality) = 0; virtual Ptr clipToImageAlpha (const Image& image, const AffineTransform& t, const bool betterQuality) = 0;
virtual Ptr translated (const Point<int>& delta) = 0;
virtual void translate (const Point<int>& delta) = 0;
virtual bool clipRegionIntersects (const Rectangle<int>& r) const = 0; virtual bool clipRegionIntersects (const Rectangle<int>& r) const = 0;
virtual Rectangle<int> getClipBounds() const = 0; virtual Rectangle<int> getClipBounds() const = 0;
@@ -1294,10 +1294,9 @@ public:
return edgeTable.isEmpty() ? nullptr : this; return edgeTable.isEmpty() ? nullptr : this;
} }
Ptr translated (const Point<int>& delta)
void translate (const Point<int>& delta)
{ {
edgeTable.translate ((float) delta.getX(), delta.getY()); edgeTable.translate ((float) delta.getX(), delta.getY());
return edgeTable.isEmpty() ? nullptr : this;
} }
bool clipRegionIntersects (const Rectangle<int>& r) const bool clipRegionIntersects (const Rectangle<int>& r) const
@@ -1451,10 +1450,9 @@ public:
return toEdgeTable()->clipToImageAlpha (image, transform, betterQuality); return toEdgeTable()->clipToImageAlpha (image, transform, betterQuality);
} }
Ptr translated (const Point<int>& delta)
void translate (const Point<int>& delta)
{ {
clip.offsetAll (delta.getX(), delta.getY()); clip.offsetAll (delta.getX(), delta.getY());
return clip.isEmpty() ? nullptr : this;
} }
bool clipRegionIntersects (const Rectangle<int>& r) const bool clipRegionIntersects (const Rectangle<int>& r) const
@@ -1821,12 +1819,6 @@ public:
return false; return false;
} }
Rectangle<int> getUntransformedClipBounds() const
{
return clip != nullptr ? clip->getClipBounds()
: Rectangle<int>();
}
Rectangle<int> getClipBounds() const Rectangle<int> getClipBounds() const
{ {
return clip != nullptr ? transform.deviceSpaceToUserSpace (clip->getClipBounds()) return clip != nullptr ? transform.deviceSpaceToUserSpace (clip->getClipBounds())
@@ -1835,26 +1827,34 @@ public:
SavedState* beginTransparencyLayer (float opacity) SavedState* beginTransparencyLayer (float opacity)
{ {
const Rectangle<int> layerBounds (getUntransformedClipBounds());
SavedState* s = new SavedState (*this); SavedState* s = new SavedState (*this);
s->image = Image (Image::ARGB, layerBounds.getWidth(), layerBounds.getHeight(), true);
s->transparencyLayerAlpha = opacity;
s->transform.moveOriginInDeviceSpace (-layerBounds.getX(), -layerBounds.getY());
s->cloneClipIfMultiplyReferenced();
s->clip = s->clip->translated (-layerBounds.getPosition());
if (clip != nullptr)
{
const Rectangle<int> layerBounds (clip->getClipBounds());
s->image = Image (Image::ARGB, layerBounds.getWidth(), layerBounds.getHeight(), true);
s->transparencyLayerAlpha = opacity;
s->transform.moveOriginInDeviceSpace (-layerBounds.getX(), -layerBounds.getY());
s->cloneClipIfMultiplyReferenced();
s->clip->translate (-layerBounds.getPosition());
}
return s; return s;
} }
void endTransparencyLayer (SavedState& finishedLayerState) void endTransparencyLayer (SavedState& finishedLayerState)
{ {
const Rectangle<int> layerBounds (getUntransformedClipBounds());
if (clip != nullptr)
{
const Rectangle<int> layerBounds (clip->getClipBounds());
const ScopedPointer<LowLevelGraphicsContext> g (image.createLowLevelContext());
g->setOpacity (finishedLayerState.transparencyLayerAlpha);
g->drawImage (finishedLayerState.image, AffineTransform::translation ((float) layerBounds.getX(),
(float) layerBounds.getY()));
const ScopedPointer<LowLevelGraphicsContext> g (image.createLowLevelContext());
g->setOpacity (finishedLayerState.transparencyLayerAlpha);
g->drawImage (finishedLayerState.image, AffineTransform::translation ((float) layerBounds.getX(),
(float) layerBounds.getY()));
}
} }
//============================================================================== //==============================================================================


+ 3
- 3
modules/juce_graphics/geometry/juce_EdgeTable.h View File

@@ -57,13 +57,13 @@ public:
const AffineTransform& transform); const AffineTransform& transform);
/** Creates an edge table containing a rectangle. */ /** Creates an edge table containing a rectangle. */
EdgeTable (const Rectangle<int>& rectangleToAdd);
explicit EdgeTable (const Rectangle<int>& rectangleToAdd);
/** Creates an edge table containing a rectangle list. */ /** Creates an edge table containing a rectangle list. */
EdgeTable (const RectangleList& rectanglesToAdd);
explicit EdgeTable (const RectangleList& rectanglesToAdd);
/** Creates an edge table containing a rectangle. */ /** Creates an edge table containing a rectangle. */
EdgeTable (const Rectangle<float>& rectangleToAdd);
explicit EdgeTable (const Rectangle<float>& rectangleToAdd);
/** Creates a copy of another edge table. */ /** Creates a copy of another edge table. */
EdgeTable (const EdgeTable& other); EdgeTable (const EdgeTable& other);


+ 1
- 1
modules/juce_gui_basics/components/juce_Component.cpp View File

@@ -1162,7 +1162,7 @@ void Component::setBoundsToFit (int x, int y, int width, int height,
} }
if (newW > 0 && newH > 0) if (newW > 0 && newH > 0)
setBounds (justification.appliedToRectangle (Rectangle<int> (0, 0, newW, newH),
setBounds (justification.appliedToRectangle (Rectangle<int> (newW, newH),
Rectangle<int> (x, y, width, height))); Rectangle<int> (x, y, width, height)));
} }
} }


+ 24
- 0
modules/juce_gui_basics/native/juce_mac_MainMenu.mm View File

@@ -104,6 +104,30 @@ public:
void updateSubMenu (NSMenuItem* parentItem, const PopupMenu& menuToCopy, void updateSubMenu (NSMenuItem* parentItem, const PopupMenu& menuToCopy,
const String& name, const int menuId, const int tag) const String& name, const int menuId, const int tag)
{ {
#if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5
static bool is10_4 = (SystemStats::getOSXMinorVersionNumber() <= 4);
if (is10_4)
{
[parentItem setTag: tag];
NSMenu* menu = [parentItem submenu];
[menu setTitle: juceStringToNS (name)];
while ([menu numberOfItems] > 0)
[menu removeItemAtIndex: 0];
PopupMenu::MenuItemIterator iter (menuToCopy);
while (iter.next())
addMenuItem (iter, menu, menuId, tag);
[menu setAutoenablesItems: false];
[menu update];
return;
}
#endif
// Note: This method used to update the contents of the existing menu in-place, but that caused // Note: This method used to update the contents of the existing menu in-place, but that caused
// weird side-effects which messed-up keyboard focus when switching between windows. By creating // weird side-effects which messed-up keyboard focus when switching between windows. By creating
// a new menu and replacing the old one with it, that problem seems to be avoided.. // a new menu and replacing the old one with it, that problem seems to be avoided..


+ 1
- 1
modules/juce_gui_basics/widgets/juce_TextEditor.cpp View File

@@ -610,7 +610,7 @@ public:
Graphics::ScopedSaveState state (g); Graphics::ScopedSaveState state (g);
g.reduceClipRegion (Rectangle<int> (startX, baselineY, endX - startX, 1)); g.reduceClipRegion (Rectangle<int> (startX, baselineY, endX - startX, 1));
g.fillCheckerBoard (Rectangle<int> (0, 0, endX, baselineY + 1), 3, 1, colour, Colours::transparentBlack);
g.fillCheckerBoard (Rectangle<int> (endX, baselineY + 1), 3, 1, colour, Colours::transparentBlack);
} }
void drawSelectedText (Graphics& g, void drawSelectedText (Graphics& g,


+ 1
- 1
modules/juce_gui_extra/native/juce_ios_UIViewComponent.mm View File

@@ -87,7 +87,7 @@ public:
Rectangle<int> getViewBounds() const Rectangle<int> getViewBounds() const
{ {
CGRect r = [view frame]; CGRect r = [view frame];
return Rectangle<int> (0, 0, (int) r.size.width, (int) r.size.height);
return Rectangle<int> ((int) r.size.width, (int) r.size.height);
} }
UIView* const view; UIView* const view;


+ 1
- 1
modules/juce_gui_extra/native/juce_mac_NSViewComponent.mm View File

@@ -99,7 +99,7 @@ public:
Rectangle<int> getViewBounds() const Rectangle<int> getViewBounds() const
{ {
NSRect r = [view frame]; NSRect r = [view frame];
return Rectangle<int> (0, 0, (int) r.size.width, (int) r.size.height);
return Rectangle<int> ((int) r.size.width, (int) r.size.height);
} }
NSView* const view; NSView* const view;


Loading…
Cancel
Save