Browse Source

Removed some unused android code. Refactored some messaging code.

tags/2021-05-28
jules 13 years ago
parent
commit
bdd778332d
21 changed files with 189 additions and 1076 deletions
  1. +12
    -18
      modules/juce_audio_processors/processors/juce_AudioProcessorGraph.cpp
  2. +1
    -0
      modules/juce_audio_processors/processors/juce_AudioProcessorGraph.h
  3. +1
    -1
      modules/juce_audio_utils/gui/juce_AudioDeviceSelectorComponent.cpp
  4. +1
    -1
      modules/juce_core/json/juce_JSON.cpp
  5. +18
    -9
      modules/juce_core/maths/juce_Expression.cpp
  6. +0
    -4
      modules/juce_core/native/juce_android_JNIHelpers.h
  7. +18
    -17
      modules/juce_events/broadcasters/juce_ActionBroadcaster.cpp
  8. +4
    -10
      modules/juce_events/broadcasters/juce_ActionBroadcaster.h
  9. +36
    -34
      modules/juce_events/interprocess/juce_InterprocessConnection.cpp
  10. +3
    -6
      modules/juce_events/interprocess/juce_InterprocessConnection.h
  11. +2
    -2
      modules/juce_events/messages/juce_ApplicationBase.h
  12. +13
    -8
      modules/juce_events/timers/juce_Timer.cpp
  13. +0
    -870
      modules/juce_graphics/native/juce_android_GraphicsContext.cpp
  14. +12
    -26
      modules/juce_gui_basics/commands/juce_ApplicationCommandTarget.cpp
  15. +6
    -5
      modules/juce_gui_basics/commands/juce_ApplicationCommandTarget.h
  16. +3
    -4
      modules/juce_gui_basics/filebrowser/juce_FileListComponent.cpp
  17. +18
    -12
      modules/juce_gui_basics/mouse/juce_DragAndDropContainer.cpp
  18. +27
    -37
      modules/juce_gui_basics/native/juce_android_Windowing.cpp
  19. +9
    -4
      modules/juce_gui_basics/widgets/juce_ToolbarItemComponent.cpp
  20. +1
    -1
      modules/juce_gui_basics/widgets/juce_TreeView.cpp
  21. +4
    -7
      modules/juce_gui_basics/windows/juce_ComponentPeer.cpp

+ 12
- 18
modules/juce_audio_processors/processors/juce_AudioProcessorGraph.cpp View File

@@ -897,12 +897,7 @@ void AudioProcessorGraph::Node::prepare (const double sampleRate, const int bloc
if (! isPrepared)
{
isPrepared = true;
AudioProcessorGraph::AudioGraphIOProcessor* const ioProc
= dynamic_cast <AudioProcessorGraph::AudioGraphIOProcessor*> (static_cast<AudioProcessor*> (processor));
if (ioProc != nullptr)
ioProc->setParentGraph (graph);
setParentGraph (graph);
processor->setPlayConfigDetails (processor->getNumInputChannels(),
processor->getNumOutputChannels(),
@@ -921,6 +916,15 @@ void AudioProcessorGraph::Node::unprepare()
}
}
void AudioProcessorGraph::Node::setParentGraph (AudioProcessorGraph* const graph) const
{
AudioProcessorGraph::AudioGraphIOProcessor* const ioProc
= dynamic_cast <AudioProcessorGraph::AudioGraphIOProcessor*> (processor.get());
if (ioProc != nullptr)
ioProc->setParentGraph (graph);
}
//==============================================================================
AudioProcessorGraph::AudioProcessorGraph()
: lastNodeId (0),
@@ -983,12 +987,7 @@ AudioProcessorGraph::Node* AudioProcessorGraph::addNode (AudioProcessor* const n
nodes.add (n);
triggerAsyncUpdate();
AudioProcessorGraph::AudioGraphIOProcessor* const ioProc
= dynamic_cast <AudioProcessorGraph::AudioGraphIOProcessor*> (static_cast<AudioProcessor*> (n->processor));
if (ioProc != nullptr)
ioProc->setParentGraph (this);
n->setParentGraph (this);
return n;
}
@@ -1000,12 +999,7 @@ bool AudioProcessorGraph::removeNode (const uint32 nodeId)
{
if (nodes.getUnchecked(i)->nodeId == nodeId)
{
AudioProcessorGraph::AudioGraphIOProcessor* const ioProc
= dynamic_cast <AudioProcessorGraph::AudioGraphIOProcessor*> (static_cast<AudioProcessor*> (nodes.getUnchecked(i)->processor));
if (ioProc != nullptr)
ioProc->setParentGraph (nullptr);
nodes.getUnchecked(i)->setParentGraph (nullptr);
nodes.remove (i);
triggerAsyncUpdate();


+ 1
- 0
modules/juce_audio_processors/processors/juce_AudioProcessorGraph.h View File

@@ -97,6 +97,7 @@ public:
Node (uint32 nodeId, AudioProcessor*) noexcept;
void setParentGraph (AudioProcessorGraph*) const;
void prepare (double sampleRate, int blockSize, AudioProcessorGraph*);
void unprepare();


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

@@ -497,7 +497,7 @@ private:
{
if (box != nullptr)
{
AudioIODevice* const currentDevice = dynamic_cast <AudioIODevice*> (setup.manager->getCurrentAudioDevice());
AudioIODevice* const currentDevice = setup.manager->getCurrentAudioDevice();
const int index = type->getIndexOfDevice (currentDevice, isInput);


+ 1
- 1
modules/juce_core/json/juce_JSON.cpp View File

@@ -329,7 +329,7 @@ public:
}
else if (v.isObject())
{
DynamicObject* object = dynamic_cast<DynamicObject*> (v.getObject());
DynamicObject* const object = v.getDynamicObject();
jassert (object != nullptr); // Only DynamicObjects can be converted to JSON!


+ 18
- 9
modules/juce_core/maths/juce_Expression.cpp View File

@@ -574,25 +574,34 @@ struct Expression::Helpers
static Constant* findTermToAdjust (Term* const term, const bool mustBeFlagged)
{
jassert (term != nullptr);
if (term->getType() == constantType)
{
Constant* const c = dynamic_cast<Constant*> (term);
if (c != nullptr && (c->isResolutionTarget || ! mustBeFlagged))
Constant* const c = static_cast<Constant*> (term);
if (c->isResolutionTarget || ! mustBeFlagged)
return c;
}
if (dynamic_cast<Function*> (term) != nullptr)
if (term->getType() == functionType)
return nullptr;
int i;
const int numIns = term->getNumInputs();
for (i = 0; i < numIns; ++i)
for (int i = 0; i < numIns; ++i)
{
Constant* const c = dynamic_cast<Constant*> (term->getInput (i));
if (c != nullptr && (c->isResolutionTarget || ! mustBeFlagged))
return c;
Term* const input = term->getInput (i);
if (input->getType() == constantType)
{
Constant* const c = static_cast<Constant*> (input);
if (c->isResolutionTarget || ! mustBeFlagged)
return c;
}
}
for (i = 0; i < numIns; ++i)
for (int i = 0; i < numIns; ++i)
{
Constant* const c = findTermToAdjust (term->getInput (i), mustBeFlagged);
if (c != nullptr)


+ 0
- 4
modules/juce_core/native/juce_android_JNIHelpers.h View File

@@ -26,10 +26,6 @@
#ifndef __JUCE_ANDROID_JNIHELPERS_JUCEHEADER__
#define __JUCE_ANDROID_JNIHELPERS_JUCEHEADER__
#ifndef USE_ANDROID_CANVAS
#define USE_ANDROID_CANVAS 0
#endif
#if ! (defined (JUCE_ANDROID_ACTIVITY_CLASSNAME) && defined (JUCE_ANDROID_ACTIVITY_CLASSPATH))
#error "The JUCE_ANDROID_ACTIVITY_CLASSNAME and JUCE_ANDROID_ACTIVITY_CLASSPATH macros must be set!"
#endif


+ 18
- 17
modules/juce_events/broadcasters/juce_ActionBroadcaster.cpp View File

@@ -23,45 +23,46 @@
==============================================================================
*/
class ActionMessage : public Message
class ActionBroadcaster::ActionMessage : public MessageManager::MessageBase
{
public:
ActionMessage (const String& messageText, ActionListener* const listener_) noexcept
: message (messageText),
ActionMessage (const ActionBroadcaster* const broadcaster_,
const String& messageText,
ActionListener* const listener_) noexcept
: broadcaster (const_cast <ActionBroadcaster*> (broadcaster_)),
message (messageText),
listener (listener_)
{}
void messageCallback()
{
const ActionBroadcaster* const b = broadcaster;
if (b != nullptr && b->actionListeners.contains (listener))
listener->actionListenerCallback (message);
}
private:
WeakReference<ActionBroadcaster> broadcaster;
const String message;
ActionListener* const listener;
private:
JUCE_DECLARE_NON_COPYABLE (ActionMessage);
};
ActionBroadcaster::CallbackReceiver::CallbackReceiver() {}
void ActionBroadcaster::CallbackReceiver::handleMessage (const Message& message)
{
const ActionMessage& am = static_cast <const ActionMessage&> (message);
if (owner->actionListeners.contains (am.listener))
am.listener->actionListenerCallback (am.message);
}
//==============================================================================
ActionBroadcaster::ActionBroadcaster()
{
// are you trying to create this object before or after juce has been intialised??
jassert (MessageManager::getInstanceWithoutCreating() != nullptr);
callback.owner = this;
}
ActionBroadcaster::~ActionBroadcaster()
{
// all event-based objects must be deleted BEFORE juce is shut down!
jassert (MessageManager::getInstanceWithoutCreating() != nullptr);
masterReference.clear();
}
void ActionBroadcaster::addActionListener (ActionListener* const listener)
@@ -89,5 +90,5 @@ void ActionBroadcaster::sendActionMessage (const String& message) const
const ScopedLock sl (actionListenerLock);
for (int i = actionListeners.size(); --i >= 0;)
callback.postMessage (new ActionMessage (message, actionListeners.getUnchecked(i)));
(new ActionMessage (this, message, actionListeners.getUnchecked(i)))->post();
}

+ 4
- 10
modules/juce_events/broadcasters/juce_ActionBroadcaster.h View File

@@ -27,7 +27,6 @@
#define __JUCE_ACTIONBROADCASTER_JUCEHEADER__
#include "juce_ActionListener.h"
#include "../messages/juce_MessageListener.h"
//==============================================================================
@@ -71,17 +70,12 @@ public:
private:
//==============================================================================
class CallbackReceiver : public MessageListener
{
public:
CallbackReceiver();
void handleMessage (const Message&);
friend class WeakReference<ActionBroadcaster>;
WeakReference<ActionBroadcaster>::Master masterReference;
ActionBroadcaster* owner;
};
class ActionMessage;
friend class ActionMessage;
friend class CallbackReceiver;
CallbackReceiver callback;
SortedSet <ActionListener*> actionListeners;
CriticalSection actionListenerLock;


+ 36
- 34
modules/juce_events/interprocess/juce_InterprocessConnection.cpp View File

@@ -37,6 +37,7 @@ InterprocessConnection::~InterprocessConnection()
{
callbackConnectionState = false;
disconnect();
masterReference.clear();
}
@@ -188,43 +189,27 @@ void InterprocessConnection::initialiseWithPipe (NamedPipe* const pipe_)
}
//==============================================================================
struct ConnectionStateMessage : public Message
struct ConnectionStateMessage : public MessageManager::MessageBase
{
ConnectionStateMessage (bool connectionMade_) noexcept
: connectionMade (connectionMade_)
ConnectionStateMessage (InterprocessConnection* owner_, bool connectionMade_) noexcept
: owner (owner_), connectionMade (connectionMade_)
{}
bool connectionMade;
};
struct DataDeliveryMessage : public Message
{
DataDeliveryMessage (const MemoryBlock& data_)
: data (data_)
{}
MemoryBlock data;
};
void InterprocessConnection::handleMessage (const Message& message)
{
const ConnectionStateMessage* m = dynamic_cast <const ConnectionStateMessage*> (&message);
if (m != nullptr)
void messageCallback()
{
if (m->connectionMade)
connectionMade();
else
connectionLost();
InterprocessConnection* const ipc = owner;
if (ipc != nullptr)
{
if (connectionMade)
ipc->connectionMade();
else
ipc->connectionLost();
}
}
else
{
const DataDeliveryMessage* d = dynamic_cast <const DataDeliveryMessage*> (&message);
if (d != nullptr)
messageReceived (d->data);
}
}
WeakReference<InterprocessConnection> owner;
bool connectionMade;
};
void InterprocessConnection::connectionMadeInt()
{
@@ -233,7 +218,7 @@ void InterprocessConnection::connectionMadeInt()
callbackConnectionState = true;
if (useMessageThread)
postMessage (new ConnectionStateMessage (true));
(new ConnectionStateMessage (this, true))->post();
else
connectionMade();
}
@@ -246,18 +231,35 @@ void InterprocessConnection::connectionLostInt()
callbackConnectionState = false;
if (useMessageThread)
postMessage (new ConnectionStateMessage (false));
(new ConnectionStateMessage (this, false))->post();
else
connectionLost();
}
}
struct DataDeliveryMessage : public Message
{
DataDeliveryMessage (InterprocessConnection* owner_, const MemoryBlock& data_)
: owner (owner_), data (data_)
{}
void messageCallback()
{
InterprocessConnection* const ipc = owner;
if (ipc != nullptr)
ipc->messageReceived (data);
}
WeakReference<InterprocessConnection> owner;
MemoryBlock data;
};
void InterprocessConnection::deliverDataInt (const MemoryBlock& data)
{
jassert (callbackConnectionState);
if (useMessageThread)
postMessage (new DataDeliveryMessage (data));
(new DataDeliveryMessage (this, data))->post();
else
messageReceived (data);
}


+ 3
- 6
modules/juce_events/interprocess/juce_InterprocessConnection.h View File

@@ -26,7 +26,6 @@
#ifndef __JUCE_INTERPROCESSCONNECTION_JUCEHEADER__
#define __JUCE_INTERPROCESSCONNECTION_JUCEHEADER__
#include "../messages/juce_MessageListener.h"
class InterprocessConnectionServer;
class MemoryBlock;
@@ -49,8 +48,7 @@ class MemoryBlock;
@see InterprocessConnectionServer, Socket, NamedPipe
*/
class JUCE_API InterprocessConnection : public Thread,
private MessageListener
class JUCE_API InterprocessConnection : public Thread
{
public:
//==============================================================================
@@ -181,6 +179,8 @@ public:
private:
//==============================================================================
WeakReference<InterprocessConnection>::Master masterReference;
friend class WeakReference<InterprocessConnection>;
CriticalSection pipeAndSocketLock;
ScopedPointer <StreamingSocket> socket;
ScopedPointer <NamedPipe> pipe;
@@ -189,12 +189,9 @@ private:
const uint32 magicMessageHeader;
int pipeReceiveMessageTimeout;
//==============================================================================
friend class InterprocessConnectionServer;
void initialiseWithSocket (StreamingSocket*);
void initialiseWithPipe (NamedPipe*);
void handleMessage (const Message&);
void connectionMadeInt();
void connectionLostInt();
void deliverDataInt (const MemoryBlock&);


+ 2
- 2
modules/juce_events/messages/juce_ApplicationBase.h View File

@@ -133,14 +133,14 @@ public:
passed-in will be valid. If the exception is of unknown type, this pointer
will be null.
*/
virtual void unhandledException (const std::exception* e,
virtual void unhandledException (const std::exception*,
const String& sourceFilename,
int lineNumber) = 0;
//==============================================================================
/** Returns true if this executable is running as an app (as opposed to being a plugin
or other kind of shared library. */
static inline bool isStandaloneApp() noexcept { return createInstance != 0; }
static inline bool isStandaloneApp() noexcept { return createInstance != nullptr; }
//==============================================================================
#ifndef DOXYGEN


+ 13
- 8
modules/juce_events/timers/juce_Timer.cpp View File

@@ -24,7 +24,6 @@
*/
class Timer::TimerThread : private Thread,
private MessageListener,
private DeletedAtShutdown,
private AsyncUpdater
{
@@ -51,7 +50,7 @@ public:
void run()
{
uint32 lastTime = Time::getMillisecondCounter();
Message::Ptr messageToSend (new Message());
MessageManager::MessageBase::Ptr messageToSend (new CallTimersMessage());
while (! threadShouldExit())
{
@@ -78,7 +77,7 @@ public:
*/
if (callbackNeeded.compareAndSetBool (1, 0))
{
postMessage (messageToSend);
messageToSend->post();
/* Sometimes our message can get discarded by the OS (e.g. when running as an RTAS
when the app has a modal loop), so this is how long to wait before assuming the
@@ -137,11 +136,6 @@ public:
callbackNeeded.set (0);
}
void handleMessage (const Message&)
{
callTimers();
}
void callTimersSynchronously()
{
if (! isThreadRunning())
@@ -192,6 +186,17 @@ private:
Timer* volatile firstTimer;
Atomic <int> callbackNeeded;
struct CallTimersMessage : public MessageManager::MessageBase
{
CallTimersMessage() {}
void messageCallback()
{
if (instance != nullptr)
instance->callTimers();
}
};
//==============================================================================
void addTimer (Timer* const t) noexcept
{


+ 0
- 870
modules/juce_graphics/native/juce_android_GraphicsContext.cpp View File

@@ -55,877 +55,7 @@ namespace GraphicsHelpers
}
}
#if USE_ANDROID_CANVAS
//==============================================================================
#define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD) \
METHOD (constructor, "<init>", "(Landroid/graphics/Bitmap;)V") \
METHOD (drawRect, "drawRect", "(FFFFLandroid/graphics/Paint;)V") \
METHOD (translate, "translate", "(FF)V") \
METHOD (clipPath, "clipPath", "(Landroid/graphics/Path;)Z") \
METHOD (clipRect, "clipRect", "(FFFF)Z") \
METHOD (clipRegion, "clipRegion", "(Landroid/graphics/Region;)Z") \
METHOD (concat, "concat", "(Landroid/graphics/Matrix;)V") \
METHOD (drawBitmap, "drawBitmap", "(Landroid/graphics/Bitmap;Landroid/graphics/Matrix;Landroid/graphics/Paint;)V") \
METHOD (drawBitmapAt, "drawBitmap", "(Landroid/graphics/Bitmap;FFLandroid/graphics/Paint;)V") \
METHOD (drawMemoryBitmap, "drawBitmap", "([IIIFFIIZLandroid/graphics/Paint;)V") \
METHOD (drawLine, "drawLine", "(FFFFLandroid/graphics/Paint;)V") \
METHOD (drawPath, "drawPath", "(Landroid/graphics/Path;Landroid/graphics/Paint;)V") \
METHOD (drawText, "drawText", "(Ljava/lang/String;FFLandroid/graphics/Paint;)V") \
METHOD (getClipBounds, "getClipBounds", "(Landroid/graphics/Rect;)Z") \
METHOD (getClipBounds2, "getClipBounds", "()Landroid/graphics/Rect;") \
METHOD (getMatrix, "getMatrix", "()Landroid/graphics/Matrix;") \
METHOD (save, "save", "()I") \
METHOD (restore, "restore", "()V") \
METHOD (saveLayerAlpha, "saveLayerAlpha", "(FFFFII)I")
DECLARE_JNI_CLASS (Canvas, "android/graphics/Canvas");
#undef JNI_CLASS_MEMBERS
//==============================================================================
#define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD) \
METHOD (constructor, "<init>", "()V") \
METHOD (moveTo, "moveTo", "(FF)V") \
METHOD (lineTo, "lineTo", "(FF)V") \
METHOD (quadTo, "quadTo", "(FFFF)V") \
METHOD (cubicTo, "cubicTo", "(FFFFFF)V") \
METHOD (closePath, "close", "()V") \
METHOD (computeBounds, "computeBounds", "(Landroid/graphics/RectF;Z)V") \
DECLARE_JNI_CLASS (PathClass, "android/graphics/Path");
#undef JNI_CLASS_MEMBERS
//==============================================================================
#define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD) \
METHOD (constructor, "<init>", "()V"); \
METHOD (regionUnion, "union", "(Landroid/graphics/Rect;)Z"); \
DECLARE_JNI_CLASS (RegionClass, "android/graphics/Region");
#undef JNI_CLASS_MEMBERS
//==============================================================================
#define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD) \
STATICMETHOD (createBitmap, "createBitmap", "(IILandroid/graphics/Bitmap$Config;)Landroid/graphics/Bitmap;") \
METHOD (bitmapCopy, "copy", "(Landroid/graphics/Bitmap$Config;Z)Landroid/graphics/Bitmap;") \
METHOD (getPixels, "getPixels", "([IIIIIII)V") \
METHOD (setPixels, "setPixels", "([IIIIIII)V") \
METHOD (recycle, "recycle", "()V") \
DECLARE_JNI_CLASS (BitmapClass, "android/graphics/Bitmap");
#undef JNI_CLASS_MEMBERS
//==============================================================================
#define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD) \
STATICFIELD (ARGB_8888, "ARGB_8888", "Landroid/graphics/Bitmap$Config;") \
STATICFIELD (ALPHA_8, "ALPHA_8", "Landroid/graphics/Bitmap$Config;") \
DECLARE_JNI_CLASS (BitmapConfig, "android/graphics/Bitmap$Config");
#undef JNI_CLASS_MEMBERS
//==============================================================================
#define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD) \
METHOD (constructor, "<init>", "(Landroid/graphics/Bitmap;Landroid/graphics/Shader$TileMode;Landroid/graphics/Shader$TileMode;)V")
DECLARE_JNI_CLASS (BitmapShader, "android/graphics/BitmapShader");
#undef JNI_CLASS_MEMBERS
//==============================================================================
#define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD) \
METHOD (setLocalMatrix, "setLocalMatrix", "(Landroid/graphics/Matrix;)V")
DECLARE_JNI_CLASS (ShaderClass, "android/graphics/Shader");
#undef JNI_CLASS_MEMBERS
//==============================================================================
#define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD) \
STATICFIELD (CLAMP, "CLAMP", "Landroid/graphics/Shader$TileMode;")
DECLARE_JNI_CLASS (ShaderTileMode, "android/graphics/Shader$TileMode");
#undef JNI_CLASS_MEMBERS
//==============================================================================
#define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD) \
METHOD (constructor, "<init>", "(FFFF[I[FLandroid/graphics/Shader$TileMode;)V") \
DECLARE_JNI_CLASS (LinearGradientClass, "android/graphics/LinearGradient");
#undef JNI_CLASS_MEMBERS
//==============================================================================
#define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD) \
METHOD (constructor, "<init>", "(FFF[I[FLandroid/graphics/Shader$TileMode;)V") \
DECLARE_JNI_CLASS (RadialGradientClass, "android/graphics/RadialGradient");
#undef JNI_CLASS_MEMBERS
//==============================================================================
class AndroidImage : public ImagePixelData
{
public:
AndroidImage (const int width_, const int height_, const bool clearImage)
: ImagePixelData (Image::ARGB, width_, height_),
bitmap (createBitmap (width_, height_, false))
{
}
AndroidImage (const int width_, const int height_, const GlobalRef& bitmap_)
: ImagePixelData (Image::ARGB, width_, height_),
bitmap (bitmap_)
{
}
~AndroidImage()
{
if (bitmap != 0)
bitmap.callVoidMethod (BitmapClass.recycle);
}
LowLevelGraphicsContext* createLowLevelContext();
void initialiseBitmapData (Image::BitmapData& bm, int x, int y, Image::BitmapData::ReadWriteMode mode)
{
bm.lineStride = width * sizeof (jint);
bm.pixelStride = sizeof (jint);
bm.pixelFormat = Image::ARGB;
bm.dataReleaser = new CopyHandler (*this, bm, x, y, mode);
}
ImagePixelData* clone()
{
JNIEnv* env = getEnv();
jobject mode = env->GetStaticObjectField (BitmapConfig, BitmapConfig.ARGB_8888);
GlobalRef newCopy (bitmap.callObjectMethod (BitmapClass.bitmapCopy, mode, true));
env->DeleteLocalRef (mode);
return new AndroidImage (width, height, newCopy);
}
ImageType* createType() const { return new NativeImageType(); }
static jobject createBitmap (int width, int height, bool asSingleChannel)
{
JNIEnv* env = getEnv();
jobject mode = env->GetStaticObjectField (BitmapConfig, asSingleChannel ? BitmapConfig.ALPHA_8
: BitmapConfig.ARGB_8888);
jobject result = env->CallStaticObjectMethod (BitmapClass, BitmapClass.createBitmap, width, height, mode);
env->DeleteLocalRef (mode);
return result;
}
//==============================================================================
GlobalRef bitmap;
private:
class CopyHandler : public Image::BitmapData::BitmapDataReleaser
{
public:
CopyHandler (AndroidImage& owner_, Image::BitmapData& bitmapData_,
const int x_, const int y_, const Image::BitmapData::ReadWriteMode mode_)
: owner (owner_), bitmapData (bitmapData_), mode (mode_), x (x_), y (y_)
{
JNIEnv* env = getEnv();
intArray = env->NewIntArray (bitmapData.width * bitmapData.height);
if (mode != Image::BitmapData::writeOnly)
owner_.bitmap.callVoidMethod (BitmapClass.getPixels, intArray, 0, bitmapData.width, x_, y_,
bitmapData.width, bitmapData.height);
bitmapData.data = (uint8*) env->GetIntArrayElements (intArray, 0);
if (mode != Image::BitmapData::writeOnly)
{
for (int yy = 0; yy < bitmapData.height; ++yy)
{
PixelARGB* p = (PixelARGB*) bitmapData.getLinePointer (yy);
for (int xx = 0; xx < bitmapData.width; ++xx)
p[xx].premultiply();
}
}
}
~CopyHandler()
{
JNIEnv* env = getEnv();
if (mode != Image::BitmapData::readOnly)
{
for (int yy = 0; yy < bitmapData.height; ++yy)
{
PixelARGB* p = (PixelARGB*) bitmapData.getLinePointer (yy);
for (int xx = 0; xx < bitmapData.width; ++xx)
p[xx].unpremultiply();
}
}
env->ReleaseIntArrayElements (intArray, (jint*) bitmapData.data, 0);
if (mode != Image::BitmapData::readOnly)
owner.bitmap.callVoidMethod (BitmapClass.setPixels, intArray, 0, bitmapData.width, x, y,
bitmapData.width, bitmapData.height);
env->DeleteLocalRef (intArray);
}
private:
AndroidImage& owner;
Image::BitmapData& bitmapData;
jintArray intArray;
const Image::BitmapData::ReadWriteMode mode;
const int x, y;
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (CopyHandler);
};
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (AndroidImage);
};
#endif
ImagePixelData* NativeImageType::create (Image::PixelFormat format, int width, int height, bool clearImage) const
{
#if USE_ANDROID_CANVAS
if (pixelFormat != Image::SingleChannel)
return new AndroidImage (width, height, clearImage);
#endif
return SoftwareImageType().create (format, width, height, clearImage);
}
#if USE_ANDROID_CANVAS
//==============================================================================
class AndroidLowLevelGraphicsContext : public LowLevelGraphicsContext
{
public:
AndroidLowLevelGraphicsContext (jobject canvas_)
: originalCanvas (canvas_),
currentState (new SavedState (canvas_))
{
setFill (Colours::black);
}
~AndroidLowLevelGraphicsContext()
{
while (stateStack.size() > 0)
restoreState();
currentState->flattenImageClippingLayer (originalCanvas);
}
bool isVectorDevice() const { return false; }
//==============================================================================
void setOrigin (int x, int y)
{
getCanvas().callVoidMethod (Canvas.translate, (float) x, (float) y);
}
void addTransform (const AffineTransform& transform)
{
getCanvas().callVoidMethod (Canvas.concat, createMatrixRef (getEnv(), transform).get());
}
float getScaleFactor()
{
return 1.0f;
}
bool clipToRectangle (const Rectangle<int>& r)
{
return getCanvas().callBooleanMethod (Canvas.clipRect, (float) r.getX(), (float) r.getY(), (float) r.getRight(), (float) r.getBottom());
}
bool clipToRectangleList (const RectangleList& clipRegion)
{
RectangleList excluded (getClipBounds());
excluded.subtract (clipRegion);
const int numRects = excluded.getNumRectangles();
for (int i = 0; i < numRects; ++i)
excludeClipRectangle (excluded.getRectangle(i));
}
void excludeClipRectangle (const Rectangle<int>& r)
{
android.activity.callVoidMethod (JuceAppActivity.excludeClipRegion, getCanvas().get(),
(float) r.getX(), (float) r.getY(), (float) r.getRight(), (float) r.getBottom());
}
void clipToPath (const Path& path, const AffineTransform& transform)
{
(void) getCanvas().callBooleanMethod (Canvas.clipPath, createPath (getEnv(), path, transform).get());
}
void clipToImageAlpha (const Image& sourceImage, const AffineTransform& transform)
{
// XXX couldn't get image clipping to work...
JNIEnv* env = getEnv();
{
Path p;
p.addRectangle (sourceImage.getBounds().toFloat());
clipToPath (p, transform);
}
Rectangle<int> bounds (getClipBounds());
jobject temporaryLayerBitmap = AndroidImage::createBitmap (bounds.getWidth(), bounds.getHeight(), false);
jobject temporaryCanvas = env->NewObject (Canvas, Canvas.constructor, temporaryLayerBitmap);
setFill (Colours::red);
env->CallVoidMethod (temporaryCanvas, Canvas.drawRect,
(jfloat) 20, (jfloat) 20, (jfloat) 300, (jfloat) 200,
getCurrentPaint());
env->CallVoidMethod (temporaryCanvas, Canvas.translate,
(jfloat) -bounds.getX(), (jfloat) -bounds.getY());
Image maskImage (Image::SingleChannel, bounds.getWidth(), bounds.getHeight(), true);
{
Graphics g (maskImage);
g.setOrigin (-bounds.getWidth(), -bounds.getHeight());
g.drawImageTransformed (sourceImage, transform);
}
SavedState* const top = stateStack.getLast();
currentState->clipToImage (top != nullptr ? top->canvas.get() : originalCanvas,
temporaryCanvas, temporaryLayerBitmap, maskImage,
bounds.getX(), bounds.getY());
}
bool clipRegionIntersects (const Rectangle<int>& r)
{
return getClipBounds().intersects (r);
}
Rectangle<int> getClipBounds() const
{
JNIEnv* env = getEnv();
jobject rect = getCanvas().callObjectMethod (Canvas.getClipBounds2);
const int left = env->GetIntField (rect, RectClass.left);
const int top = env->GetIntField (rect, RectClass.top);
const int right = env->GetIntField (rect, RectClass.right);
const int bottom = env->GetIntField (rect, RectClass.bottom);
env->DeleteLocalRef (rect);
return Rectangle<int>::leftTopRightBottom (left, top, right, bottom);
}
bool isClipEmpty() const
{
LocalRef<jobject> tempRect (getEnv()->NewObject (RectClass, RectClass.constructor, 0, 0, 0, 0));
return ! getCanvas().callBooleanMethod (Canvas.getClipBounds, tempRect.get());
}
//==============================================================================
void setFill (const FillType& fillType)
{
currentState->setFillType (fillType);
}
void setOpacity (float newOpacity)
{
currentState->setAlpha (newOpacity);
}
void setInterpolationQuality (Graphics::ResamplingQuality quality)
{
currentState->setInterpolationQuality (quality);
}
//==============================================================================
void fillRect (const Rectangle<int>& r, bool replaceExistingContents)
{
getCanvas().callVoidMethod (Canvas.drawRect,
(float) r.getX(), (float) r.getY(), (float) r.getRight(), (float) r.getBottom(),
getCurrentPaint());
}
void fillPath (const Path& path, const AffineTransform& transform)
{
getCanvas().callVoidMethod (Canvas.drawPath, createPath (getEnv(), path, transform).get(),
getCurrentPaint());
}
void drawImage (const Image& sourceImage, const AffineTransform& transform)
{
AndroidImage* androidImage = dynamic_cast <AndroidImage*> (sourceImage.getPixelData());
if (androidImage != 0)
{
JNIEnv* env = getEnv();
getCanvas().callVoidMethod (Canvas.drawBitmap, androidImage->bitmap.get(),
createMatrixRef (env, transform).get(), getImagePaint());
}
else
{
if (transform.isOnlyTranslation())
{
JNIEnv* env = getEnv();
Image::BitmapData bm (sourceImage, Image::BitmapData::readOnly);
jintArray imageData = env->NewIntArray (bm.width * bm.height);
jint* dest = env->GetIntArrayElements (imageData, 0);
if (dest != 0)
{
const uint8* srcLine = bm.getLinePointer (0);
jint* dstLine = dest;
for (int y = 0; y < bm.height; ++y)
{
switch (bm.pixelFormat)
{
case Image::ARGB: copyPixels (dstLine, (PixelARGB*) srcLine, bm.width, bm.pixelStride); break;
case Image::RGB: copyPixels (dstLine, (PixelRGB*) srcLine, bm.width, bm.pixelStride); break;
case Image::SingleChannel: copyPixels (dstLine, (PixelAlpha*) srcLine, bm.width, bm.pixelStride); break;
default: jassertfalse; break;
}
srcLine += bm.lineStride;
dstLine += bm.width;
}
env->ReleaseIntArrayElements (imageData, dest, 0);
getCanvas().callVoidMethod (Canvas.drawMemoryBitmap, imageData, 0, bm.width,
transform.getTranslationX(), transform.getTranslationY(),
bm.width, bm.height, true, getImagePaint());
env->DeleteLocalRef (imageData);
}
}
else
{
saveState();
addTransform (transform);
drawImage (sourceImage, AffineTransform::identity);
restoreState();
}
}
}
void drawLine (const Line <float>& line)
{
getCanvas().callVoidMethod (Canvas.drawLine, line.getStartX(), line.getStartY(),
line.getEndX(), line.getEndY(), getCurrentPaint());
}
void drawVerticalLine (int x, float top, float bottom)
{
getCanvas().callVoidMethod (Canvas.drawRect, (float) x, top, x + 1.0f, bottom, getCurrentPaint());
}
void drawHorizontalLine (int y, float left, float right)
{
getCanvas().callVoidMethod (Canvas.drawRect, left, (float) y, right, y + 1.0f, getCurrentPaint());
}
void setFont (const Font& newFont)
{
if (currentState->font != newFont)
{
currentState->font = newFont;
currentState->typefaceNeedsUpdate = true;
}
}
const Font& getFont()
{
return currentState->font;
}
void drawGlyph (int glyphNumber, const AffineTransform& transform)
{
if (transform.isOnlyTranslation())
{
getCanvas().callVoidMethod (Canvas.drawText, javaStringFromChar ((juce_wchar) glyphNumber).get(),
transform.getTranslationX(), transform.getTranslationY(),
currentState->getPaintForTypeface());
}
else
{
saveState();
addTransform (transform);
drawGlyph (glyphNumber, AffineTransform::identity);
restoreState();
}
}
//==============================================================================
void saveState()
{
(void) getCanvas().callIntMethod (Canvas.save);
stateStack.add (new SavedState (*currentState));
}
void restoreState()
{
SavedState* const top = stateStack.getLast();
if (top != 0)
{
currentState->flattenImageClippingLayer (top->canvas);
currentState = top;
stateStack.removeLast (1, false);
}
else
{
jassertfalse; // trying to pop with an empty stack!
}
getCanvas().callVoidMethod (Canvas.restore);
}
void beginTransparencyLayer (float opacity)
{
Rectangle<int> clip (getClipBounds());
(void) getCanvas().callIntMethod (Canvas.saveLayerAlpha,
(float) clip.getX(),
(float) clip.getY(),
(float) clip.getRight(),
(float) clip.getBottom(),
jlimit (0, 255, roundToInt (opacity * 255.0f)),
31 /*ALL_SAVE_FLAG*/);
stateStack.add (new SavedState (*currentState));
}
void endTransparencyLayer()
{
restoreState();
}
//==============================================================================
class SavedState
{
public:
SavedState (jobject canvas_)
: canvas (canvas_), font (1.0f), quality (Graphics::highResamplingQuality),
fillNeedsUpdate (true), typefaceNeedsUpdate (true)
{
}
SavedState (const SavedState& other)
: canvas (other.canvas), fillType (other.fillType), font (other.font),
quality (other.quality), fillNeedsUpdate (true), typefaceNeedsUpdate (true)
{
}
void setFillType (const FillType& newType)
{
fillNeedsUpdate = true;
fillType = newType;
}
void setAlpha (float alpha)
{
fillNeedsUpdate = true;
fillType.colour = fillType.colour.withAlpha (alpha);
}
void setInterpolationQuality (Graphics::ResamplingQuality quality_)
{
if (quality != quality_)
{
quality = quality_;
fillNeedsUpdate = true;
paint.clear();
}
}
jobject getPaint()
{
if (fillNeedsUpdate)
{
JNIEnv* env = getEnv();
if (paint.get() == 0)
paint = GlobalRef (GraphicsHelpers::createPaint (quality));
if (fillType.isColour())
{
env->DeleteLocalRef (paint.callObjectMethod (Paint.setShader, (jobject) 0));
paint.callVoidMethod (Paint.setColor, colourToInt (fillType.colour));
}
else if (fillType.isGradient())
{
const ColourGradient& g = *fillType.gradient;
const Point<float> p1 (g.point1);
const Point<float> p2 (g.point2);
const int numColours = g.getNumColours();
jintArray coloursArray = env->NewIntArray (numColours);
jfloatArray positionsArray = env->NewFloatArray (numColours);
{
HeapBlock<int> colours (numColours);
HeapBlock<float> positions (numColours);
for (int i = 0; i < numColours; ++i)
{
colours[i] = colourToInt (g.getColour (i));
positions[i] = (float) g.getColourPosition(i);
}
env->SetIntArrayRegion (coloursArray, 0, numColours, colours.getData());
env->SetFloatArrayRegion (positionsArray, 0, numColours, positions.getData());
}
jobject tileMode = env->GetStaticObjectField (ShaderTileMode, ShaderTileMode.CLAMP);
jobject shader;
if (fillType.gradient->isRadial)
{
shader = env->NewObject (RadialGradientClass,
RadialGradientClass.constructor,
p1.getX(), p1.getY(),
p1.getDistanceFrom (p2),
coloursArray, positionsArray,
tileMode);
}
else
{
shader = env->NewObject (LinearGradientClass,
LinearGradientClass.constructor,
p1.getX(), p1.getY(), p2.getX(), p2.getY(),
coloursArray, positionsArray,
tileMode);
}
env->DeleteLocalRef (tileMode);
env->DeleteLocalRef (coloursArray);
env->DeleteLocalRef (positionsArray);
env->CallVoidMethod (shader, ShaderClass.setLocalMatrix, createMatrixRef (env, fillType.transform).get());
env->DeleteLocalRef (paint.callObjectMethod (Paint.setShader, shader));
env->DeleteLocalRef (shader);
}
else
{
// TODO xxx
}
}
return paint.get();
}
jobject getPaintForTypeface()
{
jobject p = getPaint();
if (typefaceNeedsUpdate)
{
typefaceNeedsUpdate = false;
const Typeface::Ptr t (font.getTypeface());
AndroidTypeface* atf = dynamic_cast <AndroidTypeface*> (t.getObject());
if (atf != 0)
{
paint.callObjectMethod (Paint.setTypeface, atf->typeface.get());
paint.callVoidMethod (Paint.setTextSize, font.getHeight());
const float hScale = font.getHorizontalScale();
if (hScale < 0.99f || hScale > 1.01f)
paint.callVoidMethod (Paint.setTextScaleX, hScale);
}
fillNeedsUpdate = true;
paint.callVoidMethod (Paint.setAlpha, (jint) fillType.colour.getAlpha());
}
return p;
}
jobject getImagePaint()
{
jobject p = getPaint();
paint.callVoidMethod (Paint.setAlpha, (jint) fillType.colour.getAlpha());
fillNeedsUpdate = true;
return p;
}
void flattenImageClippingLayer (jobject previousCanvas)
{
// XXX couldn't get image clipping to work...
if (temporaryLayerBitmap != 0)
{
JNIEnv* env = getEnv();
jobject tileMode = env->GetStaticObjectField (ShaderTileMode, ShaderTileMode.CLAMP);
jobject shader = env->NewObject (BitmapShader, BitmapShader.constructor,
temporaryLayerBitmap.get(), tileMode, tileMode);
env->DeleteLocalRef (tileMode);
jobject compositingPaint = GraphicsHelpers::createPaint (quality);
env->CallObjectMethod (compositingPaint, Paint.setShader, shader);
env->DeleteLocalRef (shader);
LocalRef<jobject> maskBitmap (createAlphaBitmap (env, maskImage));
maskImage = Image::null;
env->CallVoidMethod (previousCanvas, Canvas.drawBitmapAt,
maskBitmap.get(), (jfloat) maskLayerX, (jfloat) maskLayerY, compositingPaint);
env->DeleteLocalRef (compositingPaint);
canvas = GlobalRef (previousCanvas);
env->CallVoidMethod (temporaryLayerBitmap.get(), BitmapClass.recycle);
env->CallVoidMethod (maskBitmap.get(), BitmapClass.recycle);
temporaryLayerBitmap.clear();
}
}
void clipToImage (jobject previousCanvas,
jobject temporaryCanvas, jobject temporaryLayerBitmap_,
const Image& maskImage_,
int maskLayerX_, int maskLayerY_)
{
// XXX couldn't get image clipping to work...
flattenImageClippingLayer (previousCanvas);
maskLayerX = maskLayerX_;
maskLayerY = maskLayerY_;
canvas = GlobalRef (temporaryCanvas);
temporaryLayerBitmap = GlobalRef (temporaryLayerBitmap_);
maskImage = maskImage_;
}
static jobject createAlphaBitmap (JNIEnv* env, const Image& image)
{
Image::BitmapData bm (image, Image::BitmapData::readOnly);
jobject bitmap = AndroidImage::createBitmap (bm.width, bm.height, true);
jintArray intArray = env->NewIntArray (bm.width * bm.height);
jint* const dest = env->GetIntArrayElements (intArray, 0);
for (int yy = 0; yy < bm.height; ++yy)
{
PixelAlpha* src = (PixelAlpha*) bm.getLinePointer (yy);
jint* destLine = dest + yy * bm.width;
for (int xx = 0; xx < bm.width; ++xx)
{
destLine[xx] = src->getAlpha();
src = addBytesToPointer (src, bm.pixelStride);
}
}
env->ReleaseIntArrayElements (intArray, (jint*) dest, 0);
env->CallVoidMethod (bitmap, BitmapClass.setPixels, intArray, 0, bm.width, 0, 0, bm.width, bm.height);
env->DeleteLocalRef (intArray);
return bitmap;
}
GlobalRef canvas, temporaryLayerBitmap;
FillType fillType;
Font font;
GlobalRef paint;
bool fillNeedsUpdate, typefaceNeedsUpdate;
Graphics::ResamplingQuality quality;
Image maskImage;
int maskLayerX, maskLayerY;
};
private:
//==============================================================================
GlobalRef originalCanvas;
ScopedPointer <SavedState> currentState;
OwnedArray <SavedState> stateStack;
GlobalRef& getCanvas() const noexcept { return currentState->canvas; }
jobject getCurrentPaint() const { return currentState->getPaint(); }
jobject getImagePaint() const { return currentState->getImagePaint(); }
static LocalRef<jobject> createPath (JNIEnv* env, const Path& path)
{
jobject p = env->NewObject (PathClass, PathClass.constructor);
Path::Iterator i (path);
while (i.next())
{
switch (i.elementType)
{
case Path::Iterator::startNewSubPath: env->CallVoidMethod (p, PathClass.moveTo, i.x1, i.y1); break;
case Path::Iterator::lineTo: env->CallVoidMethod (p, PathClass.lineTo, i.x1, i.y1); break;
case Path::Iterator::quadraticTo: env->CallVoidMethod (p, PathClass.quadTo, i.x1, i.y1, i.x2, i.y2); break;
case Path::Iterator::cubicTo: env->CallVoidMethod (p, PathClass.cubicTo, i.x1, i.y1, i.x2, i.y2, i.x3, i.y3); break;
case Path::Iterator::closePath: env->CallVoidMethod (p, PathClass.closePath); break;
default: jassertfalse; break;
}
}
return LocalRef<jobject> (p);
}
static LocalRef<jobject> createPath (JNIEnv* env, const Path& path, const AffineTransform& transform)
{
if (transform.isIdentity())
return createPath (env, path);
Path tempPath (path);
tempPath.applyTransform (transform);
return createPath (env, tempPath);
}
static LocalRef<jobject> createMatrixRef (JNIEnv* env, const AffineTransform& t)
{
return LocalRef<jobject> (GraphicsHelpers::createMatrix (env, t));
}
static LocalRef<jobject> createRect (JNIEnv* env, const Rectangle<int>& r)
{
return LocalRef<jobject> (env->NewObject (RectClass, RectClass.constructor,
r.getX(), r.getY(), r.getRight(), r.getBottom()));
}
static LocalRef<jobject> createRegion (JNIEnv* env, const RectangleList& list)
{
jobject region = env->NewObject (RegionClass, RegionClass.constructor);
const int numRects = list.getNumRectangles();
for (int i = 0; i < numRects; ++i)
env->CallBooleanMethod (region, RegionClass.regionUnion, createRect (env, list.getRectangle(i)).get());
return LocalRef<jobject> (region);
}
static int colourToInt (const Colour& col) noexcept
{
return col.getARGB();
}
template <class PixelType>
static void copyPixels (jint* const dest, const PixelType* src, const int width, const int pixelStride) noexcept
{
for (int x = 0; x < width; ++x)
{
dest[x] = src->getUnpremultipliedARGB();
src = addBytesToPointer (src, pixelStride);
}
}
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (AndroidLowLevelGraphicsContext);
};
LowLevelGraphicsContext* AndroidImage::createLowLevelContext()
{
jobject canvas = getEnv()->NewObject (Canvas, Canvas.constructor, bitmap.get());
return new AndroidLowLevelGraphicsContext (canvas);
}
#endif

+ 12
- 26
modules/juce_gui_basics/commands/juce_ApplicationCommandTarget.cpp View File

@@ -23,37 +23,26 @@
==============================================================================
*/
class ApplicationCommandTarget::MessageTarget : public MessageListener
class ApplicationCommandTarget::CommandMessage : public MessageManager::MessageBase
{
public:
MessageTarget (ApplicationCommandTarget& owner_)
: owner (owner_)
CommandMessage (ApplicationCommandTarget* const owner_, const InvocationInfo& info_)
: owner (owner_), info (info_)
{
}
void handleMessage (const Message& message)
void messageCallback()
{
jassert (dynamic_cast <const InvokedMessage*> (&message) != nullptr);
owner.tryToInvoke (dynamic_cast <const InvokedMessage&> (message).info, false);
ApplicationCommandTarget* const target = owner;
if (target != nullptr)
target->tryToInvoke (info, false);
}
struct InvokedMessage : public Message
{
InvokedMessage (const InvocationInfo& info_)
: info (info_)
{}
const InvocationInfo info;
private:
JUCE_DECLARE_NON_COPYABLE (InvokedMessage);
};
private:
ApplicationCommandTarget& owner;
WeakReference<ApplicationCommandTarget> owner;
const InvocationInfo info;
JUCE_DECLARE_NON_COPYABLE (MessageTarget);
JUCE_DECLARE_NON_COPYABLE (CommandMessage);
};
//==============================================================================
@@ -63,7 +52,7 @@ ApplicationCommandTarget::ApplicationCommandTarget()
ApplicationCommandTarget::~ApplicationCommandTarget()
{
messageInvoker = nullptr;
masterReference.clear();
}
//==============================================================================
@@ -73,10 +62,7 @@ bool ApplicationCommandTarget::tryToInvoke (const InvocationInfo& info, const bo
{
if (async)
{
if (messageInvoker == nullptr)
messageInvoker = new MessageTarget (*this);
messageInvoker->postMessage (new MessageTarget::InvokedMessage (info));
(new CommandMessage (this, info))->post();
return true;
}
else


+ 6
- 5
modules/juce_gui_basics/commands/juce_ApplicationCommandTarget.h View File

@@ -234,12 +234,13 @@ public:
private:
//==============================================================================
class MessageTarget;
friend class MessageTarget;
friend class ScopedPointer<MessageTarget>;
ScopedPointer<MessageTarget> messageInvoker;
WeakReference<ApplicationCommandTarget>::Master masterReference;
friend class WeakReference<ApplicationCommandTarget>;
bool tryToInvoke (const InvocationInfo& info, bool async);
class CommandMessage;
friend class CommandMessage;
bool tryToInvoke (const InvocationInfo&, bool async);
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ApplicationCommandTarget);
};


+ 3
- 4
modules/juce_gui_basics/filebrowser/juce_FileListComponent.cpp View File

@@ -228,13 +228,12 @@ void FileListComponent::paintListBoxItem (int, Graphics&, int, int, bool)
Component* FileListComponent::refreshComponentForRow (int row, bool isSelected, Component* existingComponentToUpdate)
{
FileListItemComponent* comp = dynamic_cast <FileListItemComponent*> (existingComponentToUpdate);
jassert (existingComponentToUpdate == nullptr || dynamic_cast <FileListItemComponent*> (existingComponentToUpdate) != nullptr);
FileListItemComponent* comp = static_cast <FileListItemComponent*> (existingComponentToUpdate);
if (comp == nullptr)
{
delete existingComponentToUpdate;
comp = new FileListItemComponent (*this, fileList.getTimeSliceThread());
}
DirectoryContentsList::FileInfo fileInfo;
comp->update (fileList.getDirectory(),


+ 18
- 12
modules/juce_gui_basics/mouse/juce_DragAndDropContainer.cpp View File

@@ -100,7 +100,8 @@ public:
{
const bool wasVisible = isVisible();
setVisible (false);
finalTarget = findTarget (e.getScreenPosition(), details.localPosition);
Component* unused;
finalTarget = findTarget (e.getScreenPosition(), details.localPosition, unused);
if (wasVisible) // fade the component and remove it - it'll be deleted later by the timer callback
dismissWithAnimation (finalTarget == nullptr);
@@ -131,8 +132,8 @@ public:
setNewScreenPos (screenPos);
DragAndDropTarget* const newTarget = findTarget (screenPos, details.localPosition);
Component* newTargetComp = dynamic_cast <Component*> (newTarget);
Component* newTargetComp;
DragAndDropTarget* const newTarget = findTarget (screenPos, details.localPosition, newTargetComp);
setVisible (newTarget == nullptr || newTarget->shouldDrawDragImageWhenOver());
@@ -185,7 +186,8 @@ private:
return dynamic_cast <DragAndDropTarget*> (currentlyOverComp.get());
}
DragAndDropTarget* findTarget (const Point<int>& screenPos, Point<int>& relativePos) const
DragAndDropTarget* findTarget (const Point<int>& screenPos, Point<int>& relativePos,
Component*& resultComponent) const
{
Component* hit = getParentComponent();
@@ -205,12 +207,14 @@ private:
if (ddt != nullptr && ddt->isInterestedInDragSource (details))
{
relativePos = hit->getLocalPoint (nullptr, screenPos);
resultComponent = hit;
return ddt;
}
hit = hit->getParentComponent();
}
resultComponent = nullptr;
return nullptr;
}
@@ -304,14 +308,6 @@ void DragAndDropContainer::startDragging (const var& sourceDescription,
if (dragImageComponent == nullptr)
{
Component* const thisComp = dynamic_cast <Component*> (this);
if (thisComp == nullptr)
{
jassertfalse; // Your DragAndDropContainer needs to be a Component!
return;
}
MouseInputSource* draggingSource = Desktop::getInstance().getDraggingMouseSource (0);
if (draggingSource == nullptr || ! draggingSource->isDragging())
@@ -382,7 +378,17 @@ void DragAndDropContainer::startDragging (const var& sourceDescription,
| ComponentPeer::windowIgnoresKeyPresses);
}
else
{
Component* const thisComp = dynamic_cast <Component*> (this);
if (thisComp == nullptr)
{
jassertfalse; // Your DragAndDropContainer needs to be a Component!
return;
}
thisComp->addChildComponent (dragImageComponent);
}
static_cast <DragImageComponent*> (dragImageComponent.get())->updateLocation (false, lastMouseDown);
dragImageComponent->setVisible (true);


+ 27
- 37
modules/juce_gui_basics/native/juce_android_Windowing.cpp View File

@@ -375,53 +375,43 @@ public:
//==============================================================================
void handlePaintCallback (JNIEnv* env, jobject canvas)
{
#if USE_ANDROID_CANVAS
if (usingAndroidGraphics)
jobject rect = env->CallObjectMethod (canvas, CanvasMinimal.getClipBounds);
const int left = env->GetIntField (rect, RectClass.left);
const int top = env->GetIntField (rect, RectClass.top);
const int right = env->GetIntField (rect, RectClass.right);
const int bottom = env->GetIntField (rect, RectClass.bottom);
env->DeleteLocalRef (rect);
const Rectangle<int> clip (left, top, right - left, bottom - top);
const int sizeNeeded = clip.getWidth() * clip.getHeight();
if (sizeAllocated < sizeNeeded)
{
AndroidLowLevelGraphicsContext g (canvas);
handlePaint (g);
buffer.clear();
sizeAllocated = sizeNeeded;
buffer = GlobalRef (env->NewIntArray (sizeNeeded));
}
else
#endif
{
jobject rect = env->CallObjectMethod (canvas, CanvasMinimal.getClipBounds);
const int left = env->GetIntField (rect, RectClass.left);
const int top = env->GetIntField (rect, RectClass.top);
const int right = env->GetIntField (rect, RectClass.right);
const int bottom = env->GetIntField (rect, RectClass.bottom);
env->DeleteLocalRef (rect);
const Rectangle<int> clip (left, top, right - left, bottom - top);
jint* dest = env->GetIntArrayElements ((jintArray) buffer.get(), 0);
const int sizeNeeded = clip.getWidth() * clip.getHeight();
if (sizeAllocated < sizeNeeded)
if (dest != 0)
{
{
buffer.clear();
sizeAllocated = sizeNeeded;
buffer = GlobalRef (env->NewIntArray (sizeNeeded));
}
jint* dest = env->GetIntArrayElements ((jintArray) buffer.get(), 0);
Image temp (new PreallocatedImage (clip.getWidth(), clip.getHeight(),
dest, ! component->isOpaque()));
if (dest != 0)
{
{
Image temp (new PreallocatedImage (clip.getWidth(), clip.getHeight(),
dest, ! component->isOpaque()));
{
LowLevelGraphicsSoftwareRenderer g (temp);
g.setOrigin (-clip.getX(), -clip.getY());
handlePaint (g);
}
LowLevelGraphicsSoftwareRenderer g (temp);
g.setOrigin (-clip.getX(), -clip.getY());
handlePaint (g);
}
}
env->ReleaseIntArrayElements ((jintArray) buffer.get(), dest, 0);
env->ReleaseIntArrayElements ((jintArray) buffer.get(), dest, 0);
env->CallVoidMethod (canvas, CanvasMinimal.drawBitmap, (jintArray) buffer.get(), 0, clip.getWidth(),
(jfloat) clip.getX(), (jfloat) clip.getY(),
clip.getWidth(), clip.getHeight(), true, (jobject) 0);
}
env->CallVoidMethod (canvas, CanvasMinimal.drawBitmap, (jintArray) buffer.get(), 0, clip.getWidth(),
(jfloat) clip.getX(), (jfloat) clip.getY(),
clip.getWidth(), clip.getHeight(), true, (jobject) 0);
}
}


+ 9
- 4
modules/juce_gui_basics/widgets/juce_ToolbarItemComponent.cpp View File

@@ -45,7 +45,7 @@ public:
void paint (Graphics& g)
{
ToolbarItemComponent* const tc = dynamic_cast <ToolbarItemComponent*> (getParentComponent());
ToolbarItemComponent* const tc = getToolbarItemComponent();
if (isMouseOverOrDragging()
&& tc != nullptr
@@ -60,7 +60,7 @@ public:
void mouseDown (const MouseEvent& e)
{
isDragging = false;
ToolbarItemComponent* const tc = dynamic_cast <ToolbarItemComponent*> (getParentComponent());
ToolbarItemComponent* const tc = getToolbarItemComponent();
if (tc != nullptr)
{
@@ -80,7 +80,7 @@ public:
{
dnd->startDragging (Toolbar::toolbarDragDescriptor, getParentComponent(), Image::null, true);
ToolbarItemComponent* const tc = dynamic_cast <ToolbarItemComponent*> (getParentComponent());
ToolbarItemComponent* const tc = getToolbarItemComponent();
if (tc != nullptr)
{
@@ -96,7 +96,7 @@ public:
void mouseUp (const MouseEvent&)
{
isDragging = false;
ToolbarItemComponent* const tc = dynamic_cast <ToolbarItemComponent*> (getParentComponent());
ToolbarItemComponent* const tc = getToolbarItemComponent();
if (tc != nullptr)
{
@@ -120,6 +120,11 @@ private:
//==============================================================================
bool isDragging;
ToolbarItemComponent* getToolbarItemComponent() const noexcept
{
return dynamic_cast <ToolbarItemComponent*> (getParentComponent());
}
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ItemDragAndDropOverlayComponent);
};


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

@@ -441,7 +441,7 @@ public:
bool keyPressed (const KeyPress& key)
{
TreeView* const tree = dynamic_cast <TreeView*> (getParentComponent());
Component* const tree = getParentComponent();
return (tree != nullptr && tree->keyPressed (key))
|| Viewport::keyPressed (key);


+ 4
- 7
modules/juce_gui_basics/windows/juce_ComponentPeer.cpp View File

@@ -434,7 +434,7 @@ bool ComponentPeer::handleFileDragMove (const StringArray& files, const Point<in
updateCurrentModifiers();
FileDragAndDropTarget* lastTarget
= dynamic_cast<FileDragAndDropTarget*> (static_cast<Component*> (dragAndDropTargetComponent));
= dynamic_cast<FileDragAndDropTarget*> (dragAndDropTargetComponent.get());
FileDragAndDropTarget* newTarget = nullptr;
@@ -468,8 +468,7 @@ bool ComponentPeer::handleFileDragMove (const StringArray& files, const Point<in
if (newTarget == nullptr)
return false;
Component* const targetComp = dynamic_cast <Component*> (newTarget);
const Point<int> pos (targetComp->getLocalPoint (component, position));
const Point<int> pos (dragAndDropTargetComponent->getLocalPoint (component, position));
newTarget->fileDragMove (files, pos.getX(), pos.getY());
return true;
}
@@ -515,16 +514,14 @@ bool ComponentPeer::handleFileDragDrop (const StringArray& files, const Point<in
if (dragAndDropTargetComponent != nullptr)
{
FileDragAndDropTarget* const target
= dynamic_cast<FileDragAndDropTarget*> (static_cast<Component*> (dragAndDropTargetComponent));
Component* const targetComp = dragAndDropTargetComponent;
FileDragAndDropTarget* const target = dynamic_cast<FileDragAndDropTarget*> (targetComp);
dragAndDropTargetComponent = nullptr;
lastDragAndDropCompUnderMouse = nullptr;
if (target != nullptr)
{
Component* const targetComp = dynamic_cast <Component*> (target);
if (targetComp->isCurrentlyBlockedByAnotherModalComponent())
{
targetComp->internalModalInputAttempt();


Loading…
Cancel
Save