diff --git a/juce_amalgamated.cpp b/juce_amalgamated.cpp index ee2775bec0..097b49a7df 100644 --- a/juce_amalgamated.cpp +++ b/juce_amalgamated.cpp @@ -3603,7 +3603,7 @@ var::operator int() const case voidType: break; case intType: return value.intValue; case boolType: return value.boolValue ? 1 : 0; - case doubleType: return (int) value.doubleValue; + case doubleType: return static_cast (value.doubleValue); case stringType: return value.stringValue->getIntValue(); case objectType: break; default: jassertfalse; break; @@ -3683,9 +3683,9 @@ bool var::equals (const var& other) const throw() switch (type) { case voidType: return other.isVoid(); - case intType: return value.intValue == (int) other; - case boolType: return value.boolValue == (bool) other; - case doubleType: return value.doubleValue == (double) other; + case intType: return value.intValue == static_cast (other); + case boolType: return value.boolValue == static_cast (other); + case doubleType: return value.doubleValue == static_cast (other); case stringType: return (*(value.stringValue)) == other.toString(); case objectType: return value.objectValue == other.getObject(); case methodType: return value.methodValue == other.value.methodValue && other.isMethod(); @@ -41758,10 +41758,7 @@ Desktop::Desktop() throw() : mouseClickCounter (0), kioskModeComponent (0) { - const int maxNumMice = 1; - for (int i = maxNumMice; --i >= 0;) - mouseSources.add (new MouseInputSource (i, true)); - + createMouseInputSources(); refreshMonitorSizes(); } @@ -49443,7 +49440,9 @@ void Slider::restoreMouseIfHidden() if (mouseWasHidden) { mouseWasHidden = false; - Desktop::getInstance().getMainMouseSource().enableUnboundedMouseMovement (false); + + for (int i = Desktop::getInstance().getNumMouseSources(); --i >= 0;) + Desktop::getInstance().getMouseSource(i)->enableUnboundedMouseMovement (false); const double pos = (sliderBeingDragged == 2) ? getMaxValue() : ((sliderBeingDragged == 1) ? getMinValue() @@ -70382,11 +70381,53 @@ public: return 0; } - const Point getScreenPosition() const + const Point getScreenPosition() const throw() { return lastScreenPos + unboundedMouseOffset; } + void sendMouseEnter (Component* const comp, const Point& screenPos, const int64 time) + { + //DBG ("Mouse " + String (source.getIndex()) + " enter: " + comp->globalPositionToRelative (screenPos).toString() + " - Comp: " + String::toHexString ((int) comp)); + comp->internalMouseEnter (source, comp->globalPositionToRelative (screenPos), time); + } + + void sendMouseExit (Component* const comp, const Point& screenPos, const int64 time) + { + //DBG ("Mouse " + String (source.getIndex()) + " exit: " + comp->globalPositionToRelative (screenPos).toString() + " - Comp: " + String::toHexString ((int) comp)); + comp->internalMouseExit (source, comp->globalPositionToRelative (screenPos), time); + } + + void sendMouseMove (Component* const comp, const Point& screenPos, const int64 time) + { + //DBG ("Mouse " + String (source.getIndex()) + " move: " + comp->globalPositionToRelative (screenPos).toString() + " - Comp: " + String::toHexString ((int) comp)); + comp->internalMouseMove (source, comp->globalPositionToRelative (screenPos), time); + } + + void sendMouseDown (Component* const comp, const Point& screenPos, const int64 time) + { + //DBG ("Mouse " + String (source.getIndex()) + " down: " + comp->globalPositionToRelative (screenPos).toString() + " - Comp: " + String::toHexString ((int) comp)); + comp->internalMouseDown (source, comp->globalPositionToRelative (screenPos), time); + } + + void sendMouseDrag (Component* const comp, const Point& screenPos, const int64 time) + { + //DBG ("Mouse " + String (source.getIndex()) + " drag: " + comp->globalPositionToRelative (screenPos).toString() + " - Comp: " + String::toHexString ((int) comp)); + comp->internalMouseDrag (source, comp->globalPositionToRelative (screenPos), time); + } + + void sendMouseUp (Component* const comp, const Point& screenPos, const int64 time) + { + //DBG ("Mouse " + String (source.getIndex()) + " up: " + comp->globalPositionToRelative (screenPos).toString() + " - Comp: " + String::toHexString ((int) comp)); + comp->internalMouseUp (source, comp->globalPositionToRelative (screenPos), time, getCurrentModifiers()); + } + + void sendMouseWheel (Component* const comp, const Point& screenPos, const int64 time, float x, float y) + { + //DBG ("Mouse " + String (source.getIndex()) + " wheel: " + comp->globalPositionToRelative (screenPos).toString() + " - Comp: " + String::toHexString ((int) comp)); + comp->internalMouseWheel (source, comp->globalPositionToRelative (screenPos), time, x, y); + } + void setButtons (const Point& screenPos, const int64 time, const ModifierKeys& newButtonState) { if (buttonState != newButtonState) @@ -70403,8 +70444,7 @@ public: Component* const current = getComponentUnderMouse(); if (current != 0) - current->internalMouseUp (source, current->globalPositionToRelative (screenPos + unboundedMouseOffset), - time, getCurrentModifiers()); + sendMouseUp (current, screenPos + unboundedMouseOffset, time); enableUnboundedMouseMovement (false, false); } @@ -70420,8 +70460,7 @@ public: if (current != 0) { registerMouseDown (screenPos, time, current); - - current->internalMouseDown (source, current->globalPositionToRelative (screenPos), time); + sendMouseDown (current, screenPos, time); } } } @@ -70439,7 +70478,7 @@ public: if (current != 0) { setButtons (screenPos, time, ModifierKeys()); - current->internalMouseExit (source, current->globalPositionToRelative (screenPos), time); + sendMouseExit (current, screenPos, time); buttonState = originalButtonState; } @@ -70447,7 +70486,7 @@ public: current = getComponentUnderMouse(); if (current != 0) - current->internalMouseEnter (source, current->globalPositionToRelative (screenPos), time); + sendMouseEnter (current, screenPos, time); revealCursor (false); setButtons (screenPos, time, originalButtonState); @@ -70480,19 +70519,17 @@ public: if (current != 0) { - const Point pos (current->globalPositionToRelative (lastScreenPos)); - if (isDragging()) { registerMouseDrag (newScreenPos); - current->internalMouseDrag (source, pos + unboundedMouseOffset, time); + sendMouseDrag (current, newScreenPos + unboundedMouseOffset, time); if (isUnboundedMouseModeOn) handleUnboundedDrag (current); } else { - current->internalMouseMove (source, pos, time); + sendMouseMove (current, newScreenPos, time); } } @@ -70540,7 +70577,7 @@ public: { Component* current = getComponentUnderMouse(); if (current != 0) - current->internalMouseWheel (source, current->globalPositionToRelative (screenPos), time, x, y); + sendMouseWheel (current, screenPos, time, x, y); } } @@ -74355,7 +74392,8 @@ void MagnifierComponent::mouseExit (const MouseEvent& e) void MagnifierComponent::mouseWheelMove (const MouseEvent& e, float ix, float iy) { if (peer != 0) - peer->handleMouseWheel (Point (scaleInt (e.x), scaleInt (e.y)), e.eventTime.toMilliseconds(), + peer->handleMouseWheel (e.source.getIndex(), + Point (scaleInt (e.x), scaleInt (e.y)), e.eventTime.toMilliseconds(), ix * 256.0f, iy * 256.0f); else Component::mouseWheelMove (e, ix, iy); @@ -76373,14 +76411,20 @@ void ComponentPeer::updateCurrentModifiers() throw() ModifierKeys::updateCurrentModifiers(); } -void ComponentPeer::handleMouseEvent (const Point& positionWithinPeer, const ModifierKeys& newMods, const int64 time) +void ComponentPeer::handleMouseEvent (const int touchIndex, const Point& positionWithinPeer, const ModifierKeys& newMods, const int64 time) { - Desktop::getInstance().getMainMouseSource().handleEvent (this, positionWithinPeer, time, newMods); + MouseInputSource* const mouse = Desktop::getInstance().getMouseSource (touchIndex); + jassert (mouse != 0); // not enough sources! + + mouse->handleEvent (this, positionWithinPeer, time, newMods); } -void ComponentPeer::handleMouseWheel (const Point& positionWithinPeer, const int64 time, float x, float y) +void ComponentPeer::handleMouseWheel (const int touchIndex, const Point& positionWithinPeer, const int64 time, const float x, const float y) { - Desktop::getInstance().getMainMouseSource().handleWheel (this, positionWithinPeer, time, x, y); + MouseInputSource* const mouse = Desktop::getInstance().getMouseSource (touchIndex); + jassert (mouse != 0); // not enough sources! + + mouse->handleWheel (this, positionWithinPeer, time, x, y); } void ComponentPeer::handlePaint (LowLevelGraphicsContext& contextToPaintTo) @@ -214806,7 +214850,7 @@ public: if (fullScreen != shouldBeFullScreen) { fullScreen = shouldBeFullScreen; - const Component::SafePointer deletionChecker (component); + const Component::SafePointer deletionChecker (component); if (! fullScreen) { @@ -215474,7 +215518,7 @@ private: void doMouseEvent (const Point& position) { - handleMouseEvent (position, currentModifiers, getMouseEventTime()); + handleMouseEvent (0, position, currentModifiers, getMouseEventTime()); } void doMouseMove (const Point& position) @@ -215545,7 +215589,7 @@ private: const float amount = jlimit (-1000.0f, 1000.0f, 0.75f * HIWORD (wParam)); - handleMouseWheel (position, getMouseEventTime(), + handleMouseWheel (0, position, getMouseEventTime(), isVertical ? 0.0f : amount, isVertical ? amount : 0.0f); } @@ -216439,6 +216483,11 @@ bool AlertWindow::showNativeDialogBox (const String& title, : MB_OK)) == IDOK; } +void Desktop::createMouseInputSources() +{ + mouseSources.add (new MouseInputSource (0, true)); +} + const Point Desktop::getMousePosition() { POINT mousePos; @@ -218194,7 +218243,7 @@ namespace ActiveXHelpers case WM_LBUTTONUP: case WM_MBUTTONUP: case WM_RBUTTONUP: - peer->handleMouseEvent (mousePos, Win32ComponentPeer::currentModifiers, mouseEventTime); + peer->handleMouseEvent (0, mousePos, Win32ComponentPeer::currentModifiers, mouseEventTime); break; default: @@ -232601,7 +232650,7 @@ public: if (map == WheelUp || map == WheelDown) { - handleMouseWheel (Point (buttonPressEvent->x, buttonPressEvent->y), + handleMouseWheel (0, Point (buttonPressEvent->x, buttonPressEvent->y), getEventTime (buttonPressEvent->time), 0, map == WheelDown ? -84.0f : 84.0f); } if (map == LeftButton) @@ -232624,7 +232673,7 @@ public: { toFront (true); - handleMouseEvent (Point (buttonPressEvent->x, buttonPressEvent->y), currentModifiers, + handleMouseEvent (0, Point (buttonPressEvent->x, buttonPressEvent->y), currentModifiers, getEventTime (buttonPressEvent->time)); } @@ -232646,7 +232695,7 @@ public: else if (map == MiddleButton) currentModifiers = currentModifiers.withoutFlags (ModifierKeys::middleButtonModifier); - handleMouseEvent (Point (buttonRelEvent->x, buttonRelEvent->y), currentModifiers, + handleMouseEvent (0, Point (buttonRelEvent->x, buttonRelEvent->y), currentModifiers, getEventTime (buttonRelEvent->time)); clearLastMousePos(); @@ -232688,7 +232737,7 @@ public: } } - handleMouseEvent (mousePos - getScreenPosition(), currentModifiers, getEventTime (movedEvent->time)); + handleMouseEvent (0, mousePos - getScreenPosition(), currentModifiers, getEventTime (movedEvent->time)); } break; @@ -232702,7 +232751,7 @@ public: if (! currentModifiers.isAnyMouseButtonDown()) { updateKeyModifiers (enterEvent->state); - handleMouseEvent (Point (enterEvent->x, enterEvent->y), currentModifiers, getEventTime (enterEvent->time)); + handleMouseEvent (0, Point (enterEvent->x, enterEvent->y), currentModifiers, getEventTime (enterEvent->time)); } break; @@ -232719,7 +232768,7 @@ public: || leaveEvent->mode == NotifyUngrab) { updateKeyModifiers (leaveEvent->state); - handleMouseEvent (Point (leaveEvent->x, leaveEvent->y), currentModifiers, getEventTime (leaveEvent->time)); + handleMouseEvent (0, Point (leaveEvent->x, leaveEvent->y), currentModifiers, getEventTime (leaveEvent->time)); } break; @@ -234106,6 +234155,11 @@ void juce_updateMultiMonitorInfo (Array >& monitorCoords, const } } +void Desktop::createMouseInputSources() +{ + mouseSources.add (new MouseInputSource (0, true)); +} + bool Desktop::canUseSemiTransparentWindows() throw() { return false; @@ -239230,14 +239284,19 @@ bool DragAndDropContainer::performExternalDragDropOfFiles (const StringArray& fi if (files.size() == 0) return false; - // This method must be called in response to a component's mouseDrag event! - jassert (Desktop::getInstance().getMainMouseSource().isDragging()); + MouseInputSource* draggingSource = Desktop::getInstance().getDraggingMouseSource(0); + + if (draggingSource == 0) + { + jassertfalse // This method must be called in response to a component's mouseDown or mouseDrag event! + return false; + } - Component* sourceComp = Desktop::getInstance().getMainMouseSource().getComponentUnderMouse(); + Component* sourceComp = draggingSource->getComponentUnderMouse(); if (sourceComp == 0) { - jassertfalse // this method must be called in response to a component's mouseDrag event! + jassertfalse // This method must be called in response to a component's mouseDown or mouseDrag event! return false; } @@ -240760,6 +240819,8 @@ public: void grabFocus(); void textInputRequired (const Point& position); + void handleTouches (UIEvent* e, bool isDown, bool isUp, bool isCancel); + void repaint (int x, int y, int w, int h); void performAnyPendingRepaintsNow(); @@ -240769,6 +240830,14 @@ public: JuceUIView* view; bool isSharedWindow, fullScreen, insideDrawRect; static ModifierKeys currentModifiers; + + static int64 getMouseTime (UIEvent* e) + { + return (Time::currentTimeMillis() - Time::getMillisecondCounter()) + + (int64) ([e timestamp] * 1000.0); + } + + Array currentTouches; }; END_JUCE_NAMESPACE @@ -240812,97 +240881,31 @@ void ModifierKeys::updateCurrentModifiers() throw() currentModifiers = UIViewComponentPeer::currentModifiers; } -static int64 getMouseTime (UIEvent* e) -{ - return (Time::currentTimeMillis() - Time::getMillisecondCounter()) - + (int64) ([e timestamp] * 1000.0); -} - JUCE_NAMESPACE::Point juce_lastMousePos; - (void) touchesBegan: (NSSet*) touches withEvent: (UIEvent*) event { - if (owner == 0) - return; - - NSArray* const t = [[event touchesForView: self] allObjects]; - - switch ([t count]) - { - case 1: // One finger.. - { - CGPoint p = [[t objectAtIndex: 0] locationInView: self]; - const JUCE_NAMESPACE::Point pos ((int) p.x, (int) p.y); - juce_lastMousePos = pos + owner->getScreenPosition(); - - owner->handleMouseEvent (pos, JUCE_NAMESPACE::UIViewComponentPeer::currentModifiers, getMouseTime (event)); - - JUCE_NAMESPACE::UIViewComponentPeer::currentModifiers - = JUCE_NAMESPACE::UIViewComponentPeer::currentModifiers.withoutMouseButtons() - .withFlags (JUCE_NAMESPACE::ModifierKeys::leftButtonModifier); - - owner->handleMouseEvent (pos, JUCE_NAMESPACE::UIViewComponentPeer::currentModifiers, getMouseTime (event)); - } - - default: - //xxx multi-touch.. - break; - } + if (owner != 0) + owner->handleTouches (event, true, false, false); } - (void) touchesMoved: (NSSet*) touches withEvent: (UIEvent*) event { - if (owner == 0) - return; - - NSArray* const t = [[event touchesForView: self] allObjects]; - - switch ([t count]) - { - case 1: // One finger.. - { - CGPoint p = [[t objectAtIndex: 0] locationInView: self]; - const JUCE_NAMESPACE::Point pos ((int) p.x, (int) p.y); - juce_lastMousePos = pos + owner->getScreenPosition(); - - owner->handleMouseEvent (pos, JUCE_NAMESPACE::UIViewComponentPeer::currentModifiers, getMouseTime (event)); - } - - default: - //xxx multi-touch.. - break; - } + if (owner != 0) + owner->handleTouches (event, false, false, false); } - (void) touchesEnded: (NSSet*) touches withEvent: (UIEvent*) event { - if (owner == 0) - return; - - NSArray* const t = [[event touchesForView: self] allObjects]; - - switch ([t count]) - { - case 1: // One finger.. - { - CGPoint p = [[t objectAtIndex: 0] locationInView: self]; - const JUCE_NAMESPACE::Point pos ((int) p.x, (int) p.y); - juce_lastMousePos = pos + owner->getScreenPosition(); - - JUCE_NAMESPACE::UIViewComponentPeer::currentModifiers - = JUCE_NAMESPACE::UIViewComponentPeer::currentModifiers.withoutMouseButtons(); - - owner->handleMouseEvent (pos, JUCE_NAMESPACE::UIViewComponentPeer::currentModifiers, getMouseTime (event)); - } - - default: - //xxx multi-touch.. - break; - } + if (owner != 0) + owner->handleTouches (event, false, true, false); } - (void) touchesCancelled: (NSSet*) touches withEvent: (UIEvent*) event { + if (owner != 0) + owner->handleTouches (event, false, true, true); + [self touchesEnded: touches withEvent: event]; } @@ -241004,6 +241007,8 @@ UIViewComponentPeer::UIViewComponentPeer (Component* const component, view.hidden = ! component->isVisible(); window.hidden = ! component->isVisible(); + + view.multipleTouchEnabled = YES; } setTitle (component->getName()); @@ -241253,6 +241258,47 @@ void UIViewComponentPeer::setIcon (const Image& /*newIcon*/) // to do.. } +void UIViewComponentPeer::handleTouches (UIEvent* event, const bool isDown, const bool isUp, bool isCancel) +{ + NSArray* touches = [[event touchesForView: view] allObjects]; + + for (unsigned int i = 0; i < [touches count]; ++i) + { + UITouch* touch = [touches objectAtIndex: i]; + + CGPoint p = [touch locationInView: view]; + const Point pos ((int) p.x, (int) p.y); + juce_lastMousePos = pos + getScreenPosition(); + + const int64 time = getMouseTime (event); + + int touchIndex = currentTouches.indexOf (touch); + + if (touchIndex < 0) + { + touchIndex = currentTouches.size(); + currentTouches.add (touch); + } + + if (isDown) + { + currentModifiers = currentModifiers.withoutMouseButtons(); + handleMouseEvent (touchIndex, pos, currentModifiers, time); + currentModifiers = currentModifiers.withoutMouseButtons().withFlags (ModifierKeys::leftButtonModifier); + } + else if (isUp) + { + currentModifiers = currentModifiers.withoutMouseButtons(); + currentTouches.remove (touchIndex); + } + + if (isCancel) + currentTouches.clear(); + + handleMouseEvent (touchIndex, pos, currentModifiers, time); + } +} + static UIViewComponentPeer* currentlyFocusedPeer = 0; void UIViewComponentPeer::viewFocusGain() @@ -241401,6 +241447,12 @@ Image* juce_createIconForFile (const File& file) return 0; } +void Desktop::createMouseInputSources() +{ + for (int i = 0; i < 10; ++i) + mouseSources.add (new MouseInputSource (i, false)); +} + bool Desktop::canUseSemiTransparentWindows() throw() { return true; @@ -246367,7 +246419,7 @@ bool NSViewComponentPeer::redirectPerformKeyEquivalent (NSEvent* ev) void NSViewComponentPeer::sendMouseEvent (NSEvent* ev) { updateModifiers (ev); - handleMouseEvent (getMousePos (ev, view), currentModifiers, getMouseTime (ev)); + handleMouseEvent (0, getMousePos (ev, view), currentModifiers, getMouseTime (ev)); } void NSViewComponentPeer::redirectMouseDown (NSEvent* ev) @@ -246412,7 +246464,7 @@ void NSViewComponentPeer::redirectMouseWheel (NSEvent* ev) { updateModifiers (ev); - handleMouseWheel (getMousePos (ev, view), getMouseTime (ev), + handleMouseWheel (0, getMousePos (ev, view), getMouseTime (ev), [ev deltaX] * 10.0f, [ev deltaY] * 10.0f); } @@ -246585,6 +246637,11 @@ void NSViewComponentPeer::viewMovedToWindow() window = [view window]; } +void Desktop::createMouseInputSources() +{ + mouseSources.add (new MouseInputSource (0, true)); +} + void juce_setKioskComponent (Component* kioskModeComponent, bool enableOrDisable, bool allowMenusAndBars) { // Very annoyingly, this function has to use the old SetSystemUIMode function, @@ -248222,6 +248279,48 @@ void FileChooser::showPlatformDialog (Array& results, // compiled on its own). #if JUCE_INCLUDED_FILE && JUCE_QUICKTIME +END_JUCE_NAMESPACE + +#define NonInterceptingQTMovieView MakeObjCClassName(NonInterceptingQTMovieView) + +@interface NonInterceptingQTMovieView : QTMovieView +{ +} + +- (id) initWithFrame: (NSRect) frame; +- (BOOL) acceptsFirstMouse: (NSEvent*) theEvent; +- (NSView*) hitTest: (NSPoint) p; + +@end + +@implementation NonInterceptingQTMovieView + +- (id) initWithFrame: (NSRect) frame +{ + self = [super initWithFrame: frame]; + [self setNextResponder: [self superview]]; + return self; +} + +- (void) dealloc +{ + [super dealloc]; +} + +- (NSView*) hitTest: (NSPoint) point +{ + return [self isControllerVisible] ? [super hitTest: point] : nil; +} + +- (BOOL) acceptsFirstMouse: (NSEvent*) theEvent +{ + return YES; +} + +@end + +BEGIN_JUCE_NAMESPACE + #define theMovie ((QTMovie*) movie) QuickTimeMovieComponent::QuickTimeMovieComponent() @@ -248230,8 +248329,9 @@ QuickTimeMovieComponent::QuickTimeMovieComponent() setOpaque (true); setVisible (true); - QTMovieView* view = [[QTMovieView alloc] initWithFrame: NSMakeRect (0, 0, 100.0f, 100.0f)]; + QTMovieView* view = [[NonInterceptingQTMovieView alloc] initWithFrame: NSMakeRect (0, 0, 100.0f, 100.0f)]; setView (view); + [view release]; } QuickTimeMovieComponent::~QuickTimeMovieComponent() @@ -249366,7 +249466,7 @@ static bool isEventBlockedByModalComps (NSEvent* e) case NSRightMouseUp: case NSOtherMouseUp: case NSOtherMouseDragged: - if (Desktop::getInstance().getMainMouseSource().isDragging()) + if (Desktop::getInstance().getDraggingMouseSource(0) != 0) return false; break; diff --git a/juce_amalgamated.h b/juce_amalgamated.h index aac3030e83..cd5058ec35 100644 --- a/juce_amalgamated.h +++ b/juce_amalgamated.h @@ -43,7 +43,7 @@ #define JUCE_MAJOR_VERSION 1 #define JUCE_MINOR_VERSION 51 -#define JUCE_BUILDNUMBER 5 +#define JUCE_BUILDNUMBER 6 #define JUCE_VERSION ((JUCE_MAJOR_VERSION << 16) + (JUCE_MINOR_VERSION << 8) + JUCE_BUILDNUMBER) @@ -1508,7 +1508,7 @@ public: } HeapBlock (const size_t numElements) - : data ((ElementType*) ::juce_malloc (numElements * sizeof (ElementType))) + : data (reinterpret_cast (::juce_malloc (numElements * sizeof (ElementType)))) { } @@ -1542,13 +1542,13 @@ public: void malloc (const size_t newNumElements, const size_t elementSize = sizeof (ElementType)) { ::juce_free (data); - data = (ElementType*) ::juce_malloc (newNumElements * elementSize); + data = reinterpret_cast (::juce_malloc (newNumElements * elementSize)); } void calloc (const size_t newNumElements, const size_t elementSize = sizeof (ElementType)) { ::juce_free (data); - data = (ElementType*) ::juce_calloc (newNumElements * elementSize); + data = reinterpret_cast (::juce_calloc (newNumElements * elementSize)); } void allocate (const size_t newNumElements, const bool initialiseToZero) @@ -1556,17 +1556,17 @@ public: ::juce_free (data); if (initialiseToZero) - data = (ElementType*) ::juce_calloc (newNumElements * sizeof (ElementType)); + data = reinterpret_cast (::juce_calloc (newNumElements * sizeof (ElementType))); else - data = (ElementType*) ::juce_malloc (newNumElements * sizeof (ElementType)); + data = reinterpret_cast (::juce_malloc (newNumElements * sizeof (ElementType))); } void realloc (const size_t newNumElements, const size_t elementSize = sizeof (ElementType)) { if (data == 0) - data = (ElementType*) ::juce_malloc (newNumElements * elementSize); + data = reinterpret_cast (::juce_malloc (newNumElements * elementSize)); else - data = (ElementType*) ::juce_realloc (data, newNumElements * elementSize); + data = reinterpret_cast (::juce_realloc (data, newNumElements * elementSize)); } void free() @@ -2058,13 +2058,13 @@ public: int indexOf (const ElementType& elementToLookFor) const { const ScopedLockType lock (getLock()); - const ElementType* e = data.elements; + const ElementType* e = data.elements.getData(); const ElementType* const end = e + numUsed; while (e != end) { if (elementToLookFor == *e) - return (int) (e - data.elements); + return (int) (e - data.elements.getData()); ++e; } @@ -2075,7 +2075,7 @@ public: bool contains (const ElementType& elementToLookFor) const { const ScopedLockType lock (getLock()); - const ElementType* e = data.elements; + const ElementType* e = data.elements.getData(); const ElementType* const end = e + numUsed; while (e != end) @@ -2251,7 +2251,7 @@ public: void addSorted (ElementComparator& comparator, const ElementType& newElement) { const ScopedLockType lock (getLock()); - insert (findInsertIndexInSortedArray (comparator, (ElementType*) data.elements, newElement, 0, numUsed), newElement); + insert (findInsertIndexInSortedArray (comparator, data.elements.getData(), newElement, 0, numUsed), newElement); } template @@ -2324,7 +2324,7 @@ public: { if (valueToRemove == *e) { - remove ((int) (e - data.elements)); + remove ((int) (e - data.elements.getData())); break; } @@ -2479,7 +2479,7 @@ public: const ScopedLockType lock (getLock()); (void) comparator; // if you pass in an object with a static compareElements() method, this // avoids getting warning messages about the parameter being unused - sortArray (comparator, (ElementType*) data.elements, 0, size() - 1, retainOrderOfEquivalentItems); + sortArray (comparator, data.elements.getData(), 0, size() - 1, retainOrderOfEquivalentItems); } inline const TypeOfCriticalSectionToUse& getLock() const throw() { return data; } @@ -3478,13 +3478,13 @@ public: int indexOf (const ObjectClass* const objectToLookFor) const throw() { const ScopedLockType lock (getLock()); - ObjectClass* const* e = data.elements; + ObjectClass* const* e = data.elements.getData(); ObjectClass* const* const end = e + numUsed; while (e != end) { if (objectToLookFor == *e) - return (int) (e - data.elements); + return (int) (e - data.elements.getData()); ++e; } @@ -3495,7 +3495,7 @@ public: bool contains (const ObjectClass* const objectToLookFor) const throw() { const ScopedLockType lock (getLock()); - ObjectClass* const* e = data.elements; + ObjectClass* const* e = data.elements.getData(); ObjectClass* const* const end = e + numUsed; while (e != end) @@ -3587,7 +3587,7 @@ public: (void) comparator; // if you pass in an object with a static compareElements() method, this // avoids getting warning messages about the parameter being unused const ScopedLockType lock (getLock()); - insert (findInsertIndexInSortedArray (comparator, (ObjectClass**) data.elements, newObject, 0, numUsed), newObject); + insert (findInsertIndexInSortedArray (comparator, data.elements.getData(), newObject, 0, numUsed), newObject); } template @@ -3653,13 +3653,13 @@ public: const bool deleteObject = true) { const ScopedLockType lock (getLock()); - ObjectClass** e = data.elements; + ObjectClass** e = data.elements.getData(); for (int i = numUsed; --i >= 0;) { if (objectToRemove == *e) { - remove ((int) (e - data.elements), deleteObject); + remove ((int) (e - data.elements.getData()), deleteObject); break; } @@ -3792,7 +3792,7 @@ public: // avoids getting warning messages about the parameter being unused const ScopedLockType lock (getLock()); - sortArray (comparator, (ObjectClass**) data.elements, 0, size() - 1, retainOrderOfEquivalentItems); + sortArray (comparator, data.elements.getData(), 0, size() - 1, retainOrderOfEquivalentItems); } inline const TypeOfCriticalSectionToUse& getLock() const throw() { return data; } @@ -4905,7 +4905,7 @@ public: { const ScopedLockType lock (getLock()); return (((unsigned int) index) < (unsigned int) numUsed) ? data.elements [index] - : (ObjectClass*) 0; + : static_cast (0); } inline const ReferenceCountedObjectPtr getUnchecked (const int index) const throw() @@ -4919,26 +4919,26 @@ public: { const ScopedLockType lock (getLock()); return numUsed > 0 ? data.elements [0] - : (ObjectClass*) 0; + : static_cast (0); } inline const ReferenceCountedObjectPtr getLast() const throw() { const ScopedLockType lock (getLock()); return numUsed > 0 ? data.elements [numUsed - 1] - : (ObjectClass*) 0; + : static_cast (0); } int indexOf (const ObjectClass* const objectToLookFor) const throw() { const ScopedLockType lock (getLock()); - ObjectClass** e = data.elements; + ObjectClass** e = data.elements.getData(); ObjectClass** const end = e + numUsed; while (e != end) { if (objectToLookFor == *e) - return (int) (e - data.elements); + return (int) (e - data.elements.getData()); ++e; } @@ -4949,7 +4949,7 @@ public: bool contains (const ObjectClass* const objectToLookFor) const throw() { const ScopedLockType lock (getLock()); - ObjectClass** e = data.elements; + ObjectClass** e = data.elements.getData(); ObjectClass** const end = e + numUsed; while (e != end) @@ -5068,7 +5068,7 @@ public: ObjectClass* newObject) throw() { const ScopedLockType lock (getLock()); - insert (findInsertIndexInSortedArray (comparator, (ObjectClass**) data.elements, newObject, 0, numUsed), newObject); + insert (findInsertIndexInSortedArray (comparator, data.elements.getData(), newObject, 0, numUsed), newObject); } template @@ -5076,7 +5076,7 @@ public: ObjectClass* newObject) throw() { const ScopedLockType lock (getLock()); - const int index = findInsertIndexInSortedArray (comparator, (ObjectClass**) data.elements, newObject, 0, numUsed); + const int index = findInsertIndexInSortedArray (comparator, data.elements.getData(), newObject, 0, numUsed); if (index > 0 && comparator.compareElements (newObject, data.elements [index - 1]) == 0) set (index - 1, newObject); // replace an existing object that matches @@ -5241,7 +5241,7 @@ public: // avoids getting warning messages about the parameter being unused const ScopedLockType lock (getLock()); - sortArray (comparator, (ObjectClass**) data.elements, 0, size() - 1, retainOrderOfEquivalentItems); + sortArray (comparator, data.elements.getData(), 0, size() - 1, retainOrderOfEquivalentItems); } void minimiseStorageOverheads() throw() @@ -9208,6 +9208,8 @@ public: void applyTransform (const AffineTransform& transform) throw() { transform.transformPoint (x, y); } + const String toString() const { return String (x) + ", " + String (y); } + juce_UseDebuggingNewOperator private: @@ -12957,6 +12959,8 @@ private: Component* kioskModeComponent; Rectangle kioskComponentOriginalBounds; + void createMouseInputSources(); + void timerCallback(); void sendMouseMove(); void resetTimer() throw(); @@ -26939,8 +26943,8 @@ public: virtual void performAnyPendingRepaintsNow() = 0; - void handleMouseEvent (const Point& positionWithinPeer, const ModifierKeys& newMods, const int64 time); - void handleMouseWheel (const Point& positionWithinPeer, const int64 time, float x, float y); + void handleMouseEvent (int touchIndex, const Point& positionWithinPeer, const ModifierKeys& newMods, const int64 time); + void handleMouseWheel (int touchIndex, const Point& positionWithinPeer, const int64 time, float x, float y); void handleUserClosingWindow(); diff --git a/src/containers/juce_Array.h b/src/containers/juce_Array.h index 3af3c48380..99b2826258 100644 --- a/src/containers/juce_Array.h +++ b/src/containers/juce_Array.h @@ -282,13 +282,13 @@ public: int indexOf (const ElementType& elementToLookFor) const { const ScopedLockType lock (getLock()); - const ElementType* e = data.elements; + const ElementType* e = data.elements.getData(); const ElementType* const end = e + numUsed; while (e != end) { if (elementToLookFor == *e) - return (int) (e - data.elements); + return (int) (e - data.elements.getData()); ++e; } @@ -304,7 +304,7 @@ public: bool contains (const ElementType& elementToLookFor) const { const ScopedLockType lock (getLock()); - const ElementType* e = data.elements; + const ElementType* e = data.elements.getData(); const ElementType* const end = e + numUsed; while (e != end) @@ -579,7 +579,7 @@ public: void addSorted (ElementComparator& comparator, const ElementType& newElement) { const ScopedLockType lock (getLock()); - insert (findInsertIndexInSortedArray (comparator, (ElementType*) data.elements, newElement, 0, numUsed), newElement); + insert (findInsertIndexInSortedArray (comparator, data.elements.getData(), newElement, 0, numUsed), newElement); } /** Finds the index of an element in the array, assuming that the array is sorted. @@ -683,7 +683,7 @@ public: { if (valueToRemove == *e) { - remove ((int) (e - data.elements)); + remove ((int) (e - data.elements.getData())); break; } @@ -929,7 +929,7 @@ public: const ScopedLockType lock (getLock()); (void) comparator; // if you pass in an object with a static compareElements() method, this // avoids getting warning messages about the parameter being unused - sortArray (comparator, (ElementType*) data.elements, 0, size() - 1, retainOrderOfEquivalentItems); + sortArray (comparator, data.elements.getData(), 0, size() - 1, retainOrderOfEquivalentItems); } //============================================================================== diff --git a/src/containers/juce_HeapBlock.h b/src/containers/juce_HeapBlock.h index a48635effc..a0e1800e30 100644 --- a/src/containers/juce_HeapBlock.h +++ b/src/containers/juce_HeapBlock.h @@ -90,7 +90,7 @@ public: If you want an array of zero values, you can use the calloc() method instead. */ HeapBlock (const size_t numElements) - : data ((ElementType*) ::juce_malloc (numElements * sizeof (ElementType))) + : data (reinterpret_cast (::juce_malloc (numElements * sizeof (ElementType)))) { } @@ -180,7 +180,7 @@ public: void malloc (const size_t newNumElements, const size_t elementSize = sizeof (ElementType)) { ::juce_free (data); - data = (ElementType*) ::juce_malloc (newNumElements * elementSize); + data = reinterpret_cast (::juce_malloc (newNumElements * elementSize)); } /** Allocates a specified amount of memory and clears it. @@ -189,7 +189,7 @@ public: void calloc (const size_t newNumElements, const size_t elementSize = sizeof (ElementType)) { ::juce_free (data); - data = (ElementType*) ::juce_calloc (newNumElements * elementSize); + data = reinterpret_cast (::juce_calloc (newNumElements * elementSize)); } /** Allocates a specified amount of memory and optionally clears it. @@ -201,9 +201,9 @@ public: ::juce_free (data); if (initialiseToZero) - data = (ElementType*) ::juce_calloc (newNumElements * sizeof (ElementType)); + data = reinterpret_cast (::juce_calloc (newNumElements * sizeof (ElementType))); else - data = (ElementType*) ::juce_malloc (newNumElements * sizeof (ElementType)); + data = reinterpret_cast (::juce_malloc (newNumElements * sizeof (ElementType))); } /** Re-allocates a specified amount of memory. @@ -214,9 +214,9 @@ public: void realloc (const size_t newNumElements, const size_t elementSize = sizeof (ElementType)) { if (data == 0) - data = (ElementType*) ::juce_malloc (newNumElements * elementSize); + data = reinterpret_cast (::juce_malloc (newNumElements * elementSize)); else - data = (ElementType*) ::juce_realloc (data, newNumElements * elementSize); + data = reinterpret_cast (::juce_realloc (data, newNumElements * elementSize)); } /** Frees any currently-allocated data. diff --git a/src/containers/juce_OwnedArray.h b/src/containers/juce_OwnedArray.h index ae5c34e702..8a75981106 100644 --- a/src/containers/juce_OwnedArray.h +++ b/src/containers/juce_OwnedArray.h @@ -159,13 +159,13 @@ public: int indexOf (const ObjectClass* const objectToLookFor) const throw() { const ScopedLockType lock (getLock()); - ObjectClass* const* e = data.elements; + ObjectClass* const* e = data.elements.getData(); ObjectClass* const* const end = e + numUsed; while (e != end) { if (objectToLookFor == *e) - return (int) (e - data.elements); + return (int) (e - data.elements.getData()); ++e; } @@ -181,7 +181,7 @@ public: bool contains (const ObjectClass* const objectToLookFor) const throw() { const ScopedLockType lock (getLock()); - ObjectClass* const* e = data.elements; + ObjectClass* const* e = data.elements.getData(); ObjectClass* const* const end = e + numUsed; while (e != end) @@ -333,7 +333,7 @@ public: (void) comparator; // if you pass in an object with a static compareElements() method, this // avoids getting warning messages about the parameter being unused const ScopedLockType lock (getLock()); - insert (findInsertIndexInSortedArray (comparator, (ObjectClass**) data.elements, newObject, 0, numUsed), newObject); + insert (findInsertIndexInSortedArray (comparator, data.elements.getData(), newObject, 0, numUsed), newObject); } /** Finds the index of an object in the array, assuming that the array is sorted. @@ -430,13 +430,13 @@ public: const bool deleteObject = true) { const ScopedLockType lock (getLock()); - ObjectClass** e = data.elements; + ObjectClass** e = data.elements.getData(); for (int i = numUsed; --i >= 0;) { if (objectToRemove == *e) { - remove ((int) (e - data.elements), deleteObject); + remove ((int) (e - data.elements.getData()), deleteObject); break; } @@ -650,7 +650,7 @@ public: // avoids getting warning messages about the parameter being unused const ScopedLockType lock (getLock()); - sortArray (comparator, (ObjectClass**) data.elements, 0, size() - 1, retainOrderOfEquivalentItems); + sortArray (comparator, data.elements.getData(), 0, size() - 1, retainOrderOfEquivalentItems); } //============================================================================== diff --git a/src/containers/juce_ReferenceCountedArray.h b/src/containers/juce_ReferenceCountedArray.h index 90046023f4..eacd8e3730 100644 --- a/src/containers/juce_ReferenceCountedArray.h +++ b/src/containers/juce_ReferenceCountedArray.h @@ -130,7 +130,7 @@ public: { const ScopedLockType lock (getLock()); return (((unsigned int) index) < (unsigned int) numUsed) ? data.elements [index] - : (ObjectClass*) 0; + : static_cast (0); } /** Returns a pointer to the object at this index in the array, without checking whether the index is in-range. @@ -154,7 +154,7 @@ public: { const ScopedLockType lock (getLock()); return numUsed > 0 ? data.elements [0] - : (ObjectClass*) 0; + : static_cast (0); } /** Returns a pointer to the last object in the array. @@ -166,7 +166,7 @@ public: { const ScopedLockType lock (getLock()); return numUsed > 0 ? data.elements [numUsed - 1] - : (ObjectClass*) 0; + : static_cast (0); } //============================================================================== @@ -178,13 +178,13 @@ public: int indexOf (const ObjectClass* const objectToLookFor) const throw() { const ScopedLockType lock (getLock()); - ObjectClass** e = data.elements; + ObjectClass** e = data.elements.getData(); ObjectClass** const end = e + numUsed; while (e != end) { if (objectToLookFor == *e) - return (int) (e - data.elements); + return (int) (e - data.elements.getData()); ++e; } @@ -200,7 +200,7 @@ public: bool contains (const ObjectClass* const objectToLookFor) const throw() { const ScopedLockType lock (getLock()); - ObjectClass** e = data.elements; + ObjectClass** e = data.elements.getData(); ObjectClass** const end = e + numUsed; while (e != end) @@ -378,7 +378,7 @@ public: ObjectClass* newObject) throw() { const ScopedLockType lock (getLock()); - insert (findInsertIndexInSortedArray (comparator, (ObjectClass**) data.elements, newObject, 0, numUsed), newObject); + insert (findInsertIndexInSortedArray (comparator, data.elements.getData(), newObject, 0, numUsed), newObject); } /** Inserts or replaces an object in the array, assuming it is sorted. @@ -391,7 +391,7 @@ public: ObjectClass* newObject) throw() { const ScopedLockType lock (getLock()); - const int index = findInsertIndexInSortedArray (comparator, (ObjectClass**) data.elements, newObject, 0, numUsed); + const int index = findInsertIndexInSortedArray (comparator, data.elements.getData(), newObject, 0, numUsed); if (index > 0 && comparator.compareElements (newObject, data.elements [index - 1]) == 0) set (index - 1, newObject); // replace an existing object that matches @@ -661,7 +661,7 @@ public: // avoids getting warning messages about the parameter being unused const ScopedLockType lock (getLock()); - sortArray (comparator, (ObjectClass**) data.elements, 0, size() - 1, retainOrderOfEquivalentItems); + sortArray (comparator, data.elements.getData(), 0, size() - 1, retainOrderOfEquivalentItems); } //============================================================================== diff --git a/src/containers/juce_Variant.cpp b/src/containers/juce_Variant.cpp index a01454b18e..d83b61ab32 100644 --- a/src/containers/juce_Variant.cpp +++ b/src/containers/juce_Variant.cpp @@ -134,7 +134,7 @@ var::operator int() const case voidType: break; case intType: return value.intValue; case boolType: return value.boolValue ? 1 : 0; - case doubleType: return (int) value.doubleValue; + case doubleType: return static_cast (value.doubleValue); case stringType: return value.stringValue->getIntValue(); case objectType: break; default: jassertfalse; break; @@ -215,9 +215,9 @@ bool var::equals (const var& other) const throw() switch (type) { case voidType: return other.isVoid(); - case intType: return value.intValue == (int) other; - case boolType: return value.boolValue == (bool) other; - case doubleType: return value.doubleValue == (double) other; + case intType: return value.intValue == static_cast (other); + case boolType: return value.boolValue == static_cast (other); + case doubleType: return value.doubleValue == static_cast (other); case stringType: return (*(value.stringValue)) == other.toString(); case objectType: return value.objectValue == other.getObject(); case methodType: return value.methodValue == other.value.methodValue && other.isMethod(); diff --git a/src/core/juce_StandardHeader.h b/src/core/juce_StandardHeader.h index a8cf6e420e..bc8787dbaf 100644 --- a/src/core/juce_StandardHeader.h +++ b/src/core/juce_StandardHeader.h @@ -33,7 +33,7 @@ */ #define JUCE_MAJOR_VERSION 1 #define JUCE_MINOR_VERSION 51 -#define JUCE_BUILDNUMBER 5 +#define JUCE_BUILDNUMBER 6 /** Current Juce version number. diff --git a/src/gui/components/controls/juce_Slider.cpp b/src/gui/components/controls/juce_Slider.cpp index 4d8adf1348..78b591495a 100644 --- a/src/gui/components/controls/juce_Slider.cpp +++ b/src/gui/components/controls/juce_Slider.cpp @@ -1143,7 +1143,9 @@ void Slider::restoreMouseIfHidden() if (mouseWasHidden) { mouseWasHidden = false; - Desktop::getInstance().getMainMouseSource().enableUnboundedMouseMovement (false); + + for (int i = Desktop::getInstance().getNumMouseSources(); --i >= 0;) + Desktop::getInstance().getMouseSource(i)->enableUnboundedMouseMovement (false); const double pos = (sliderBeingDragged == 2) ? getMaxValue() : ((sliderBeingDragged == 1) ? getMinValue() diff --git a/src/gui/components/juce_Desktop.cpp b/src/gui/components/juce_Desktop.cpp index 419cb3e844..8363d1ff92 100644 --- a/src/gui/components/juce_Desktop.cpp +++ b/src/gui/components/juce_Desktop.cpp @@ -40,10 +40,7 @@ Desktop::Desktop() throw() : mouseClickCounter (0), kioskModeComponent (0) { - const int maxNumMice = 1; - for (int i = maxNumMice; --i >= 0;) - mouseSources.add (new MouseInputSource (i, true)); - + createMouseInputSources(); refreshMonitorSizes(); } diff --git a/src/gui/components/juce_Desktop.h b/src/gui/components/juce_Desktop.h index dfac048f1d..553976a5eb 100644 --- a/src/gui/components/juce_Desktop.h +++ b/src/gui/components/juce_Desktop.h @@ -302,6 +302,8 @@ private: Component* kioskModeComponent; Rectangle kioskComponentOriginalBounds; + void createMouseInputSources(); + void timerCallback(); void sendMouseMove(); void resetTimer() throw(); diff --git a/src/gui/components/mouse/juce_MouseInputSource.cpp b/src/gui/components/mouse/juce_MouseInputSource.cpp index 6c4a6b762e..9006526767 100644 --- a/src/gui/components/mouse/juce_MouseInputSource.cpp +++ b/src/gui/components/mouse/juce_MouseInputSource.cpp @@ -92,11 +92,54 @@ public: return 0; } - const Point getScreenPosition() const + const Point getScreenPosition() const throw() { return lastScreenPos + unboundedMouseOffset; } + //============================================================================== + void sendMouseEnter (Component* const comp, const Point& screenPos, const int64 time) + { + //DBG ("Mouse " + String (source.getIndex()) + " enter: " + comp->globalPositionToRelative (screenPos).toString() + " - Comp: " + String::toHexString ((int) comp)); + comp->internalMouseEnter (source, comp->globalPositionToRelative (screenPos), time); + } + + void sendMouseExit (Component* const comp, const Point& screenPos, const int64 time) + { + //DBG ("Mouse " + String (source.getIndex()) + " exit: " + comp->globalPositionToRelative (screenPos).toString() + " - Comp: " + String::toHexString ((int) comp)); + comp->internalMouseExit (source, comp->globalPositionToRelative (screenPos), time); + } + + void sendMouseMove (Component* const comp, const Point& screenPos, const int64 time) + { + //DBG ("Mouse " + String (source.getIndex()) + " move: " + comp->globalPositionToRelative (screenPos).toString() + " - Comp: " + String::toHexString ((int) comp)); + comp->internalMouseMove (source, comp->globalPositionToRelative (screenPos), time); + } + + void sendMouseDown (Component* const comp, const Point& screenPos, const int64 time) + { + //DBG ("Mouse " + String (source.getIndex()) + " down: " + comp->globalPositionToRelative (screenPos).toString() + " - Comp: " + String::toHexString ((int) comp)); + comp->internalMouseDown (source, comp->globalPositionToRelative (screenPos), time); + } + + void sendMouseDrag (Component* const comp, const Point& screenPos, const int64 time) + { + //DBG ("Mouse " + String (source.getIndex()) + " drag: " + comp->globalPositionToRelative (screenPos).toString() + " - Comp: " + String::toHexString ((int) comp)); + comp->internalMouseDrag (source, comp->globalPositionToRelative (screenPos), time); + } + + void sendMouseUp (Component* const comp, const Point& screenPos, const int64 time) + { + //DBG ("Mouse " + String (source.getIndex()) + " up: " + comp->globalPositionToRelative (screenPos).toString() + " - Comp: " + String::toHexString ((int) comp)); + comp->internalMouseUp (source, comp->globalPositionToRelative (screenPos), time, getCurrentModifiers()); + } + + void sendMouseWheel (Component* const comp, const Point& screenPos, const int64 time, float x, float y) + { + //DBG ("Mouse " + String (source.getIndex()) + " wheel: " + comp->globalPositionToRelative (screenPos).toString() + " - Comp: " + String::toHexString ((int) comp)); + comp->internalMouseWheel (source, comp->globalPositionToRelative (screenPos), time, x, y); + } + //============================================================================== void setButtons (const Point& screenPos, const int64 time, const ModifierKeys& newButtonState) { @@ -114,8 +157,7 @@ public: Component* const current = getComponentUnderMouse(); if (current != 0) - current->internalMouseUp (source, current->globalPositionToRelative (screenPos + unboundedMouseOffset), - time, getCurrentModifiers()); + sendMouseUp (current, screenPos + unboundedMouseOffset, time); enableUnboundedMouseMovement (false, false); } @@ -131,8 +173,7 @@ public: if (current != 0) { registerMouseDown (screenPos, time, current); - - current->internalMouseDown (source, current->globalPositionToRelative (screenPos), time); + sendMouseDown (current, screenPos, time); } } } @@ -150,7 +191,7 @@ public: if (current != 0) { setButtons (screenPos, time, ModifierKeys()); - current->internalMouseExit (source, current->globalPositionToRelative (screenPos), time); + sendMouseExit (current, screenPos, time); buttonState = originalButtonState; } @@ -158,7 +199,7 @@ public: current = getComponentUnderMouse(); if (current != 0) - current->internalMouseEnter (source, current->globalPositionToRelative (screenPos), time); + sendMouseEnter (current, screenPos, time); revealCursor (false); setButtons (screenPos, time, originalButtonState); @@ -191,19 +232,17 @@ public: if (current != 0) { - const Point pos (current->globalPositionToRelative (lastScreenPos)); - if (isDragging()) { registerMouseDrag (newScreenPos); - current->internalMouseDrag (source, pos + unboundedMouseOffset, time); + sendMouseDrag (current, newScreenPos + unboundedMouseOffset, time); if (isUnboundedMouseModeOn) handleUnboundedDrag (current); } else { - current->internalMouseMove (source, pos, time); + sendMouseMove (current, newScreenPos, time); } } @@ -252,7 +291,7 @@ public: { Component* current = getComponentUnderMouse(); if (current != 0) - current->internalMouseWheel (source, current->globalPositionToRelative (screenPos), time, x, y); + sendMouseWheel (current, screenPos, time, x, y); } } diff --git a/src/gui/components/special/juce_MagnifierComponent.cpp b/src/gui/components/special/juce_MagnifierComponent.cpp index 7bc4dd9d44..52d52284b7 100644 --- a/src/gui/components/special/juce_MagnifierComponent.cpp +++ b/src/gui/components/special/juce_MagnifierComponent.cpp @@ -327,7 +327,8 @@ void MagnifierComponent::mouseExit (const MouseEvent& e) void MagnifierComponent::mouseWheelMove (const MouseEvent& e, float ix, float iy) { if (peer != 0) - peer->handleMouseWheel (Point (scaleInt (e.x), scaleInt (e.y)), e.eventTime.toMilliseconds(), + peer->handleMouseWheel (e.source.getIndex(), + Point (scaleInt (e.x), scaleInt (e.y)), e.eventTime.toMilliseconds(), ix * 256.0f, iy * 256.0f); else Component::mouseWheelMove (e, ix, iy); diff --git a/src/gui/components/windows/juce_ComponentPeer.cpp b/src/gui/components/windows/juce_ComponentPeer.cpp index b35aad0bd8..12dcc2c14e 100644 --- a/src/gui/components/windows/juce_ComponentPeer.cpp +++ b/src/gui/components/windows/juce_ComponentPeer.cpp @@ -101,14 +101,20 @@ void ComponentPeer::updateCurrentModifiers() throw() } //============================================================================== -void ComponentPeer::handleMouseEvent (const Point& positionWithinPeer, const ModifierKeys& newMods, const int64 time) +void ComponentPeer::handleMouseEvent (const int touchIndex, const Point& positionWithinPeer, const ModifierKeys& newMods, const int64 time) { - Desktop::getInstance().getMainMouseSource().handleEvent (this, positionWithinPeer, time, newMods); + MouseInputSource* const mouse = Desktop::getInstance().getMouseSource (touchIndex); + jassert (mouse != 0); // not enough sources! + + mouse->handleEvent (this, positionWithinPeer, time, newMods); } -void ComponentPeer::handleMouseWheel (const Point& positionWithinPeer, const int64 time, float x, float y) +void ComponentPeer::handleMouseWheel (const int touchIndex, const Point& positionWithinPeer, const int64 time, const float x, const float y) { - Desktop::getInstance().getMainMouseSource().handleWheel (this, positionWithinPeer, time, x, y); + MouseInputSource* const mouse = Desktop::getInstance().getMouseSource (touchIndex); + jassert (mouse != 0); // not enough sources! + + mouse->handleWheel (this, positionWithinPeer, time, x, y); } //============================================================================== diff --git a/src/gui/components/windows/juce_ComponentPeer.h b/src/gui/components/windows/juce_ComponentPeer.h index 2059b1ee0a..89aa636e4b 100644 --- a/src/gui/components/windows/juce_ComponentPeer.h +++ b/src/gui/components/windows/juce_ComponentPeer.h @@ -293,8 +293,8 @@ public: virtual void performAnyPendingRepaintsNow() = 0; //============================================================================== - void handleMouseEvent (const Point& positionWithinPeer, const ModifierKeys& newMods, const int64 time); - void handleMouseWheel (const Point& positionWithinPeer, const int64 time, float x, float y); + void handleMouseEvent (int touchIndex, const Point& positionWithinPeer, const ModifierKeys& newMods, const int64 time); + void handleMouseWheel (int touchIndex, const Point& positionWithinPeer, const int64 time, float x, float y); void handleUserClosingWindow(); diff --git a/src/gui/graphics/geometry/juce_Point.h b/src/gui/graphics/geometry/juce_Point.h index b9ff8256b2..089e7b86ea 100644 --- a/src/gui/graphics/geometry/juce_Point.h +++ b/src/gui/graphics/geometry/juce_Point.h @@ -101,6 +101,9 @@ public: */ void applyTransform (const AffineTransform& transform) throw() { transform.transformPoint (x, y); } + /** Returns the point as a string in the form "x, y". */ + const String toString() const { return String (x) + ", " + String (y); } + //============================================================================== juce_UseDebuggingNewOperator diff --git a/src/native/linux/juce_linux_Windowing.cpp b/src/native/linux/juce_linux_Windowing.cpp index 3a17202bbd..ed98d81ad7 100644 --- a/src/native/linux/juce_linux_Windowing.cpp +++ b/src/native/linux/juce_linux_Windowing.cpp @@ -1150,7 +1150,7 @@ public: if (map == WheelUp || map == WheelDown) { - handleMouseWheel (Point (buttonPressEvent->x, buttonPressEvent->y), + handleMouseWheel (0, Point (buttonPressEvent->x, buttonPressEvent->y), getEventTime (buttonPressEvent->time), 0, map == WheelDown ? -84.0f : 84.0f); } if (map == LeftButton) @@ -1173,7 +1173,7 @@ public: { toFront (true); - handleMouseEvent (Point (buttonPressEvent->x, buttonPressEvent->y), currentModifiers, + handleMouseEvent (0, Point (buttonPressEvent->x, buttonPressEvent->y), currentModifiers, getEventTime (buttonPressEvent->time)); } @@ -1195,7 +1195,7 @@ public: else if (map == MiddleButton) currentModifiers = currentModifiers.withoutFlags (ModifierKeys::middleButtonModifier); - handleMouseEvent (Point (buttonRelEvent->x, buttonRelEvent->y), currentModifiers, + handleMouseEvent (0, Point (buttonRelEvent->x, buttonRelEvent->y), currentModifiers, getEventTime (buttonRelEvent->time)); clearLastMousePos(); @@ -1237,7 +1237,7 @@ public: } } - handleMouseEvent (mousePos - getScreenPosition(), currentModifiers, getEventTime (movedEvent->time)); + handleMouseEvent (0, mousePos - getScreenPosition(), currentModifiers, getEventTime (movedEvent->time)); } break; @@ -1251,7 +1251,7 @@ public: if (! currentModifiers.isAnyMouseButtonDown()) { updateKeyModifiers (enterEvent->state); - handleMouseEvent (Point (enterEvent->x, enterEvent->y), currentModifiers, getEventTime (enterEvent->time)); + handleMouseEvent (0, Point (enterEvent->x, enterEvent->y), currentModifiers, getEventTime (enterEvent->time)); } break; @@ -1268,7 +1268,7 @@ public: || leaveEvent->mode == NotifyUngrab) { updateKeyModifiers (leaveEvent->state); - handleMouseEvent (Point (leaveEvent->x, leaveEvent->y), currentModifiers, getEventTime (leaveEvent->time)); + handleMouseEvent (0, Point (leaveEvent->x, leaveEvent->y), currentModifiers, getEventTime (leaveEvent->time)); } break; @@ -2667,6 +2667,11 @@ void juce_updateMultiMonitorInfo (Array >& monitorCoords, const } //============================================================================== +void Desktop::createMouseInputSources() +{ + mouseSources.add (new MouseInputSource (0, true)); +} + bool Desktop::canUseSemiTransparentWindows() throw() { return false; diff --git a/src/native/mac/juce_iphone_UIViewComponentPeer.mm b/src/native/mac/juce_iphone_UIViewComponentPeer.mm index 466e1dcb17..1e5a1c1cc0 100644 --- a/src/native/mac/juce_iphone_UIViewComponentPeer.mm +++ b/src/native/mac/juce_iphone_UIViewComponentPeer.mm @@ -123,6 +123,8 @@ public: void grabFocus(); void textInputRequired (const Point& position); + void handleTouches (UIEvent* e, bool isDown, bool isUp, bool isCancel); + //============================================================================== void repaint (int x, int y, int w, int h); void performAnyPendingRepaintsNow(); @@ -134,6 +136,14 @@ public: JuceUIView* view; bool isSharedWindow, fullScreen, insideDrawRect; static ModifierKeys currentModifiers; + + static int64 getMouseTime (UIEvent* e) + { + return (Time::currentTimeMillis() - Time::getMillisecondCounter()) + + (int64) ([e timestamp] * 1000.0); + } + + Array currentTouches; }; //============================================================================== @@ -180,98 +190,32 @@ void ModifierKeys::updateCurrentModifiers() throw() currentModifiers = UIViewComponentPeer::currentModifiers; } -static int64 getMouseTime (UIEvent* e) -{ - return (Time::currentTimeMillis() - Time::getMillisecondCounter()) - + (int64) ([e timestamp] * 1000.0); -} - JUCE_NAMESPACE::Point juce_lastMousePos; //============================================================================== - (void) touchesBegan: (NSSet*) touches withEvent: (UIEvent*) event { - if (owner == 0) - return; - - NSArray* const t = [[event touchesForView: self] allObjects]; - - switch ([t count]) - { - case 1: // One finger.. - { - CGPoint p = [[t objectAtIndex: 0] locationInView: self]; - const JUCE_NAMESPACE::Point pos ((int) p.x, (int) p.y); - juce_lastMousePos = pos + owner->getScreenPosition(); - - owner->handleMouseEvent (pos, JUCE_NAMESPACE::UIViewComponentPeer::currentModifiers, getMouseTime (event)); - - JUCE_NAMESPACE::UIViewComponentPeer::currentModifiers - = JUCE_NAMESPACE::UIViewComponentPeer::currentModifiers.withoutMouseButtons() - .withFlags (JUCE_NAMESPACE::ModifierKeys::leftButtonModifier); - - owner->handleMouseEvent (pos, JUCE_NAMESPACE::UIViewComponentPeer::currentModifiers, getMouseTime (event)); - } - - default: - //xxx multi-touch.. - break; - } + if (owner != 0) + owner->handleTouches (event, true, false, false); } - (void) touchesMoved: (NSSet*) touches withEvent: (UIEvent*) event { - if (owner == 0) - return; - - NSArray* const t = [[event touchesForView: self] allObjects]; - - switch ([t count]) - { - case 1: // One finger.. - { - CGPoint p = [[t objectAtIndex: 0] locationInView: self]; - const JUCE_NAMESPACE::Point pos ((int) p.x, (int) p.y); - juce_lastMousePos = pos + owner->getScreenPosition(); - - owner->handleMouseEvent (pos, JUCE_NAMESPACE::UIViewComponentPeer::currentModifiers, getMouseTime (event)); - } - - default: - //xxx multi-touch.. - break; - } + if (owner != 0) + owner->handleTouches (event, false, false, false); } - (void) touchesEnded: (NSSet*) touches withEvent: (UIEvent*) event { - if (owner == 0) - return; - - NSArray* const t = [[event touchesForView: self] allObjects]; - - switch ([t count]) - { - case 1: // One finger.. - { - CGPoint p = [[t objectAtIndex: 0] locationInView: self]; - const JUCE_NAMESPACE::Point pos ((int) p.x, (int) p.y); - juce_lastMousePos = pos + owner->getScreenPosition(); - - JUCE_NAMESPACE::UIViewComponentPeer::currentModifiers - = JUCE_NAMESPACE::UIViewComponentPeer::currentModifiers.withoutMouseButtons(); - - owner->handleMouseEvent (pos, JUCE_NAMESPACE::UIViewComponentPeer::currentModifiers, getMouseTime (event)); - } - - default: - //xxx multi-touch.. - break; - } + if (owner != 0) + owner->handleTouches (event, false, true, false); } - (void) touchesCancelled: (NSSet*) touches withEvent: (UIEvent*) event { + if (owner != 0) + owner->handleTouches (event, false, true, true); + [self touchesEnded: touches withEvent: event]; } @@ -378,6 +322,8 @@ UIViewComponentPeer::UIViewComponentPeer (Component* const component, view.hidden = ! component->isVisible(); window.hidden = ! component->isVisible(); + + view.multipleTouchEnabled = YES; } setTitle (component->getName()); @@ -628,6 +574,48 @@ void UIViewComponentPeer::setIcon (const Image& /*newIcon*/) // to do.. } +//============================================================================== +void UIViewComponentPeer::handleTouches (UIEvent* event, const bool isDown, const bool isUp, bool isCancel) +{ + NSArray* touches = [[event touchesForView: view] allObjects]; + + for (unsigned int i = 0; i < [touches count]; ++i) + { + UITouch* touch = [touches objectAtIndex: i]; + + CGPoint p = [touch locationInView: view]; + const Point pos ((int) p.x, (int) p.y); + juce_lastMousePos = pos + getScreenPosition(); + + const int64 time = getMouseTime (event); + + int touchIndex = currentTouches.indexOf (touch); + + if (touchIndex < 0) + { + touchIndex = currentTouches.size(); + currentTouches.add (touch); + } + + if (isDown) + { + currentModifiers = currentModifiers.withoutMouseButtons(); + handleMouseEvent (touchIndex, pos, currentModifiers, time); + currentModifiers = currentModifiers.withoutMouseButtons().withFlags (ModifierKeys::leftButtonModifier); + } + else if (isUp) + { + currentModifiers = currentModifiers.withoutMouseButtons(); + currentTouches.remove (touchIndex); + } + + if (isCancel) + currentTouches.clear(); + + handleMouseEvent (touchIndex, pos, currentModifiers, time); + } +} + //============================================================================== static UIViewComponentPeer* currentlyFocusedPeer = 0; @@ -783,6 +771,12 @@ Image* juce_createIconForFile (const File& file) } //============================================================================== +void Desktop::createMouseInputSources() +{ + for (int i = 0; i < 10; ++i) + mouseSources.add (new MouseInputSource (i, false)); +} + bool Desktop::canUseSemiTransparentWindows() throw() { return true; diff --git a/src/native/mac/juce_mac_MessageManager.mm b/src/native/mac/juce_mac_MessageManager.mm index f138016615..a808e80a36 100644 --- a/src/native/mac/juce_mac_MessageManager.mm +++ b/src/native/mac/juce_mac_MessageManager.mm @@ -354,7 +354,7 @@ static bool isEventBlockedByModalComps (NSEvent* e) case NSRightMouseUp: case NSOtherMouseUp: case NSOtherMouseDragged: - if (Desktop::getInstance().getMainMouseSource().isDragging()) + if (Desktop::getInstance().getDraggingMouseSource(0) != 0) return false; break; diff --git a/src/native/mac/juce_mac_MiscUtilities.mm b/src/native/mac/juce_mac_MiscUtilities.mm index adb8ae811e..abab8e33ba 100644 --- a/src/native/mac/juce_mac_MiscUtilities.mm +++ b/src/native/mac/juce_mac_MiscUtilities.mm @@ -90,14 +90,19 @@ bool DragAndDropContainer::performExternalDragDropOfFiles (const StringArray& fi if (files.size() == 0) return false; - // This method must be called in response to a component's mouseDrag event! - jassert (Desktop::getInstance().getMainMouseSource().isDragging()); + MouseInputSource* draggingSource = Desktop::getInstance().getDraggingMouseSource(0); - Component* sourceComp = Desktop::getInstance().getMainMouseSource().getComponentUnderMouse(); + if (draggingSource == 0) + { + jassertfalse // This method must be called in response to a component's mouseDown or mouseDrag event! + return false; + } + + Component* sourceComp = draggingSource->getComponentUnderMouse(); if (sourceComp == 0) { - jassertfalse // this method must be called in response to a component's mouseDrag event! + jassertfalse // This method must be called in response to a component's mouseDown or mouseDrag event! return false; } diff --git a/src/native/mac/juce_mac_NSViewComponentPeer.mm b/src/native/mac/juce_mac_NSViewComponentPeer.mm index b4c79f72ba..5308795251 100644 --- a/src/native/mac/juce_mac_NSViewComponentPeer.mm +++ b/src/native/mac/juce_mac_NSViewComponentPeer.mm @@ -1355,7 +1355,7 @@ bool NSViewComponentPeer::redirectPerformKeyEquivalent (NSEvent* ev) void NSViewComponentPeer::sendMouseEvent (NSEvent* ev) { updateModifiers (ev); - handleMouseEvent (getMousePos (ev, view), currentModifiers, getMouseTime (ev)); + handleMouseEvent (0, getMousePos (ev, view), currentModifiers, getMouseTime (ev)); } void NSViewComponentPeer::redirectMouseDown (NSEvent* ev) @@ -1400,7 +1400,7 @@ void NSViewComponentPeer::redirectMouseWheel (NSEvent* ev) { updateModifiers (ev); - handleMouseWheel (getMousePos (ev, view), getMouseTime (ev), + handleMouseWheel (0, getMousePos (ev, view), getMouseTime (ev), [ev deltaX] * 10.0f, [ev deltaY] * 10.0f); } @@ -1574,6 +1574,12 @@ void NSViewComponentPeer::viewMovedToWindow() window = [view window]; } +//============================================================================== +void Desktop::createMouseInputSources() +{ + mouseSources.add (new MouseInputSource (0, true)); +} + //============================================================================== void juce_setKioskComponent (Component* kioskModeComponent, bool enableOrDisable, bool allowMenusAndBars) { diff --git a/src/native/mac/juce_mac_QuickTimeMovieComponent.mm b/src/native/mac/juce_mac_QuickTimeMovieComponent.mm index 1f39d339c8..a6087bd2eb 100644 --- a/src/native/mac/juce_mac_QuickTimeMovieComponent.mm +++ b/src/native/mac/juce_mac_QuickTimeMovieComponent.mm @@ -27,6 +27,50 @@ // compiled on its own). #if JUCE_INCLUDED_FILE && JUCE_QUICKTIME +END_JUCE_NAMESPACE + +//============================================================================== +#define NonInterceptingQTMovieView MakeObjCClassName(NonInterceptingQTMovieView) + +@interface NonInterceptingQTMovieView : QTMovieView +{ +} + +- (id) initWithFrame: (NSRect) frame; +- (BOOL) acceptsFirstMouse: (NSEvent*) theEvent; +- (NSView*) hitTest: (NSPoint) p; + +@end + +@implementation NonInterceptingQTMovieView + +- (id) initWithFrame: (NSRect) frame +{ + self = [super initWithFrame: frame]; + [self setNextResponder: [self superview]]; + return self; +} + +- (void) dealloc +{ + [super dealloc]; +} + +- (NSView*) hitTest: (NSPoint) point +{ + return [self isControllerVisible] ? [super hitTest: point] : nil; +} + +- (BOOL) acceptsFirstMouse: (NSEvent*) theEvent +{ + return YES; +} + +@end + +BEGIN_JUCE_NAMESPACE + +//============================================================================== #define theMovie ((QTMovie*) movie) //============================================================================== @@ -36,8 +80,9 @@ QuickTimeMovieComponent::QuickTimeMovieComponent() setOpaque (true); setVisible (true); - QTMovieView* view = [[QTMovieView alloc] initWithFrame: NSMakeRect (0, 0, 100.0f, 100.0f)]; + QTMovieView* view = [[NonInterceptingQTMovieView alloc] initWithFrame: NSMakeRect (0, 0, 100.0f, 100.0f)]; setView (view); + [view release]; } QuickTimeMovieComponent::~QuickTimeMovieComponent() diff --git a/src/native/windows/juce_win32_ActiveXComponent.cpp b/src/native/windows/juce_win32_ActiveXComponent.cpp index 61ad53c2ab..0b99e12a23 100644 --- a/src/native/windows/juce_win32_ActiveXComponent.cpp +++ b/src/native/windows/juce_win32_ActiveXComponent.cpp @@ -282,7 +282,7 @@ namespace ActiveXHelpers case WM_LBUTTONUP: case WM_MBUTTONUP: case WM_RBUTTONUP: - peer->handleMouseEvent (mousePos, Win32ComponentPeer::currentModifiers, mouseEventTime); + peer->handleMouseEvent (0, mousePos, Win32ComponentPeer::currentModifiers, mouseEventTime); break; default: diff --git a/src/native/windows/juce_win32_Windowing.cpp b/src/native/windows/juce_win32_Windowing.cpp index 50274008e6..3f966b7aab 100644 --- a/src/native/windows/juce_win32_Windowing.cpp +++ b/src/native/windows/juce_win32_Windowing.cpp @@ -563,7 +563,7 @@ public: if (fullScreen != shouldBeFullScreen) { fullScreen = shouldBeFullScreen; - const Component::SafePointer deletionChecker (component); + const Component::SafePointer deletionChecker (component); if (! fullScreen) { @@ -1243,7 +1243,7 @@ private: //============================================================================== void doMouseEvent (const Point& position) { - handleMouseEvent (position, currentModifiers, getMouseEventTime()); + handleMouseEvent (0, position, currentModifiers, getMouseEventTime()); } void doMouseMove (const Point& position) @@ -1314,7 +1314,7 @@ private: const float amount = jlimit (-1000.0f, 1000.0f, 0.75f * HIWORD (wParam)); - handleMouseWheel (position, getMouseEventTime(), + handleMouseWheel (0, position, getMouseEventTime(), isVertical ? 0.0f : amount, isVertical ? amount : 0.0f); } @@ -2227,6 +2227,11 @@ bool AlertWindow::showNativeDialogBox (const String& title, //============================================================================== +void Desktop::createMouseInputSources() +{ + mouseSources.add (new MouseInputSource (0, true)); +} + const Point Desktop::getMousePosition() { POINT mousePos;