mirror of
https://github.com/juce-framework/JUCE.git
synced 2026-01-10 23:44:24 +00:00
Removed some unused android code. Refactored some messaging code.
This commit is contained in:
parent
e905f52014
commit
bdd778332d
21 changed files with 192 additions and 1079 deletions
|
|
@ -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();
|
||||
|
||||
|
|
|
|||
|
|
@ -97,6 +97,7 @@ public:
|
|||
|
||||
Node (uint32 nodeId, AudioProcessor*) noexcept;
|
||||
|
||||
void setParentGraph (AudioProcessorGraph*) const;
|
||||
void prepare (double sampleRate, int blockSize, AudioProcessorGraph*);
|
||||
void unprepare();
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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!
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -37,6 +37,7 @@ InterprocessConnection::~InterprocessConnection()
|
|||
{
|
||||
callbackConnectionState = false;
|
||||
disconnect();
|
||||
masterReference.clear();
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -188,44 +189,28 @@ 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_)
|
||||
{}
|
||||
|
||||
void messageCallback()
|
||||
{
|
||||
InterprocessConnection* const ipc = owner;
|
||||
if (ipc != nullptr)
|
||||
{
|
||||
if (connectionMade)
|
||||
ipc->connectionMade();
|
||||
else
|
||||
ipc->connectionLost();
|
||||
}
|
||||
}
|
||||
|
||||
WeakReference<InterprocessConnection> owner;
|
||||
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)
|
||||
{
|
||||
if (m->connectionMade)
|
||||
connectionMade();
|
||||
else
|
||||
connectionLost();
|
||||
}
|
||||
else
|
||||
{
|
||||
const DataDeliveryMessage* d = dynamic_cast <const DataDeliveryMessage*> (&message);
|
||||
|
||||
if (d != nullptr)
|
||||
messageReceived (d->data);
|
||||
}
|
||||
}
|
||||
|
||||
void InterprocessConnection::connectionMadeInt()
|
||||
{
|
||||
if (! callbackConnectionState)
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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&);
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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(),
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
jint* dest = env->GetIntArrayElements ((jintArray) buffer.get(), 0);
|
||||
|
||||
if (dest != 0)
|
||||
{
|
||||
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)
|
||||
{
|
||||
buffer.clear();
|
||||
sizeAllocated = sizeNeeded;
|
||||
buffer = GlobalRef (env->NewIntArray (sizeNeeded));
|
||||
}
|
||||
Image temp (new PreallocatedImage (clip.getWidth(), clip.getHeight(),
|
||||
dest, ! component->isOpaque()));
|
||||
|
||||
jint* dest = env->GetIntArrayElements ((jintArray) buffer.get(), 0);
|
||||
|
||||
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->CallVoidMethod (canvas, CanvasMinimal.drawBitmap, (jintArray) buffer.get(), 0, clip.getWidth(),
|
||||
(jfloat) clip.getX(), (jfloat) clip.getY(),
|
||||
clip.getWidth(), clip.getHeight(), true, (jobject) 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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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…
Add table
Add a link
Reference in a new issue