void MidiKeyboardComponent::timerCallback() { if (shouldCheckState) { shouldCheckState = false; for (int i = rangeStart; i <= rangeEnd; ++i) { if (keysCurrentlyDrawnDown[i] != state.isNoteOnForChannels (midiInChannelMask, i)) { keysCurrentlyDrawnDown.setBit (i, state.isNoteOnForChannels (midiInChannelMask, i)); repaintNote (i); } } } if (shouldCheckMousePos) { Desktop& desktop = Desktop::getInstance(); for (int i = desktop.getNumMouseSources(); --i >= 0;) { MouseInputSource* source = desktop.getMouseSource (i); jassert (source != nullptr); updateNoteUnderMouse (getLocalPoint (nullptr, source->getScreenPosition()), source->isDragging(), source->getIndex()); } } }
void TooltipWindow::timerCallback() { Desktop& desktop = Desktop::getInstance(); const MouseInputSource mouseSource (desktop.getMainMouseSource()); const unsigned int now = Time::getApproximateMillisecondCounter(); Component* const newComp = mouseSource.isMouse() ? mouseSource.getComponentUnderMouse() : nullptr; const String newTip (getTipFor (newComp)); const bool tipChanged = (newTip != lastTipUnderMouse || newComp != lastComponentUnderMouse); lastComponentUnderMouse = newComp; lastTipUnderMouse = newTip; const int clickCount = desktop.getMouseButtonClickCounter(); const int wheelCount = desktop.getMouseWheelMoveCounter(); const bool mouseWasClicked = (clickCount > mouseClicks || wheelCount > mouseWheelMoves); mouseClicks = clickCount; mouseWheelMoves = wheelCount; const Point<float> mousePos (mouseSource.getScreenPosition()); const bool mouseMovedQuickly = mousePos.getDistanceFrom (lastMousePos) > 12; lastMousePos = mousePos; if (tipChanged || mouseWasClicked || mouseMovedQuickly) lastCompChangeTime = now; if (isVisible() || now < lastHideTime + 500) { // if a tip is currently visible (or has just disappeared), update to a new one // immediately if needed.. if (newComp == nullptr || mouseWasClicked || newTip.isEmpty()) { if (isVisible()) { lastHideTime = now; hideTip(); } } else if (tipChanged) { displayTip (mousePos.roundToInt(), newTip); } } else { // if there isn't currently a tip, but one is needed, only let it // appear after a timeout.. if (newTip.isNotEmpty() && newTip != tipShowing && now > lastCompChangeTime + (unsigned int) millisecondsBeforeTipAppears) { displayTip (mousePos.roundToInt(), newTip); } } }
void DragAndDropContainer::startDragging (const var& sourceDescription, Component* sourceComponent, const Image& dragImage_, const bool allowDraggingToExternalWindows, const Point<int>* imageOffsetFromMouse) { Image dragImage (dragImage_); 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()) { jassertfalse; // You must call startDragging() from within a mouseDown or mouseDrag callback! return; } const Point<int> lastMouseDown (Desktop::getLastMouseDownPosition()); Point<int> imageOffset; if (dragImage.isNull()) { dragImage = sourceComponent->createComponentSnapshot (sourceComponent->getLocalBounds()) .convertedToFormat (Image::ARGB); dragImage.multiplyAllAlphas (0.6f); const int lo = 150; const int hi = 400; Point<int> relPos (sourceComponent->getLocalPoint (nullptr, lastMouseDown)); Point<int> clipped (dragImage.getBounds().getConstrainedPoint (relPos)); for (int y = dragImage.getHeight(); --y >= 0;) { const double dy = (y - clipped.getY()) * (y - clipped.getY()); for (int x = dragImage.getWidth(); --x >= 0;) { const int dx = x - clipped.getX(); const int distance = roundToInt (std::sqrt (dx * dx + dy)); if (distance > lo) { const float alpha = (distance > hi) ? 0 : (hi - distance) / (float) (hi - lo) + Random::getSystemRandom().nextFloat() * 0.008f; dragImage.multiplyAlphaAt (x, y, alpha); } } } imageOffset = -clipped; } else { if (imageOffsetFromMouse == nullptr) imageOffset = -dragImage.getBounds().getCentre(); else imageOffset = -(dragImage.getBounds().getConstrainedPoint (-*imageOffsetFromMouse)); } dragImageComponent = new DragImageComponent (dragImage, sourceDescription, sourceComponent, draggingSource->getComponentUnderMouse(), this, imageOffset); currentDragDesc = sourceDescription; if (allowDraggingToExternalWindows) { if (! Desktop::canUseSemiTransparentWindows()) dragImageComponent->setOpaque (true); dragImageComponent->addToDesktop (ComponentPeer::windowIgnoresMouseClicks | ComponentPeer::windowIsTemporary | ComponentPeer::windowIgnoresKeyPresses); } else thisComp->addChildComponent (dragImageComponent); static_cast <DragImageComponent*> (static_cast <Component*> (dragImageComponent))->updateLocation (false, lastMouseDown); dragImageComponent->setVisible (true); #if JUCE_WINDOWS // Under heavy load, the layered window's paint callback can often be lost by the OS, // so forcing a repaint at least once makes sure that the window becomes visible.. ComponentPeer* const peer = dragImageComponent->getPeer(); if (peer != nullptr) peer->performAnyPendingRepaintsNow(); #endif } }