VST3: fetch midi mappings all at once, use it for note/sound-off
[carla.git] / source / modules / juce_gui_basics / misc / juce_BubbleComponent.cpp
blob009657d66f42ab84085e5a6e577496456d9a05d1
1 /*
2 ==============================================================================
4 This file is part of the JUCE library.
5 Copyright (c) 2022 - Raw Material Software Limited
7 JUCE is an open source library subject to commercial or open-source
8 licensing.
10 By using JUCE, you agree to the terms of both the JUCE 7 End-User License
11 Agreement and JUCE Privacy Policy.
13 End User License Agreement: www.juce.com/juce-7-licence
14 Privacy Policy: www.juce.com/juce-privacy-policy
16 Or: You may also use this code under the terms of the GPL v3 (see
17 www.gnu.org/licenses).
19 JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
20 EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
21 DISCLAIMED.
23 ==============================================================================
26 namespace juce
29 BubbleComponent::BubbleComponent()
30 : allowablePlacements (above | below | left | right)
32 setInterceptsMouseClicks (false, false);
34 shadow.setShadowProperties (DropShadow (Colours::black.withAlpha (0.35f), 5, Point<int>()));
35 setComponentEffect (&shadow);
38 BubbleComponent::~BubbleComponent() {}
40 //==============================================================================
41 void BubbleComponent::paint (Graphics& g)
43 getLookAndFeel().drawBubble (g, *this, arrowTip.toFloat(), content.toFloat());
45 g.reduceClipRegion (content);
46 g.setOrigin (content.getPosition());
48 paintContent (g, content.getWidth(), content.getHeight());
51 void BubbleComponent::setAllowedPlacement (const int newPlacement)
53 allowablePlacements = newPlacement;
56 //==============================================================================
57 void BubbleComponent::setPosition (Component* componentToPointTo, int distanceFromTarget, int arrowLength)
59 jassert (componentToPointTo != nullptr);
61 Rectangle<int> target;
63 if (Component* p = getParentComponent())
64 target = p->getLocalArea (componentToPointTo, componentToPointTo->getLocalBounds());
65 else
66 target = componentToPointTo->getScreenBounds().transformedBy (getTransform().inverted());
68 setPosition (target, distanceFromTarget, arrowLength);
71 void BubbleComponent::setPosition (Point<int> arrowTipPos, int arrowLength)
73 setPosition (Rectangle<int> (arrowTipPos.x, arrowTipPos.y, 1, 1), arrowLength, arrowLength);
76 void BubbleComponent::setPosition (Rectangle<int> rectangleToPointTo,
77 int distanceFromTarget, int arrowLength)
80 int contentW = 150, contentH = 30;
81 getContentSize (contentW, contentH);
82 content.setBounds (distanceFromTarget, distanceFromTarget, contentW, contentH);
85 const int totalW = content.getWidth() + distanceFromTarget * 2;
86 const int totalH = content.getHeight() + distanceFromTarget * 2;
88 auto availableSpace = (getParentComponent() != nullptr ? getParentComponent()->getLocalBounds()
89 : getParentMonitorArea().transformedBy (getTransform().inverted()));
91 int spaceAbove = ((allowablePlacements & above) != 0) ? jmax (0, rectangleToPointTo.getY() - availableSpace.getY()) : -1;
92 int spaceBelow = ((allowablePlacements & below) != 0) ? jmax (0, availableSpace.getBottom() - rectangleToPointTo.getBottom()) : -1;
93 int spaceLeft = ((allowablePlacements & left) != 0) ? jmax (0, rectangleToPointTo.getX() - availableSpace.getX()) : -1;
94 int spaceRight = ((allowablePlacements & right) != 0) ? jmax (0, availableSpace.getRight() - rectangleToPointTo.getRight()) : -1;
96 // look at whether the component is elongated, and if so, try to position next to its longer dimension.
97 if (rectangleToPointTo.getWidth() > rectangleToPointTo.getHeight() * 2
98 && (spaceAbove > totalH + 20 || spaceBelow > totalH + 20))
100 spaceLeft = spaceRight = 0;
102 else if (rectangleToPointTo.getWidth() < rectangleToPointTo.getHeight() / 2
103 && (spaceLeft > totalW + 20 || spaceRight > totalW + 20))
105 spaceAbove = spaceBelow = 0;
108 int targetX, targetY;
110 if (jmax (spaceAbove, spaceBelow) >= jmax (spaceLeft, spaceRight))
112 targetX = rectangleToPointTo.getCentre().x;
113 arrowTip.x = totalW / 2;
115 if (spaceAbove >= spaceBelow)
117 // above
118 targetY = rectangleToPointTo.getY();
119 arrowTip.y = content.getBottom() + arrowLength;
121 else
123 // below
124 targetY = rectangleToPointTo.getBottom();
125 arrowTip.y = content.getY() - arrowLength;
128 else
130 targetY = rectangleToPointTo.getCentre().y;
131 arrowTip.y = totalH / 2;
133 if (spaceLeft > spaceRight)
135 // on the left
136 targetX = rectangleToPointTo.getX();
137 arrowTip.x = content.getRight() + arrowLength;
139 else
141 // on the right
142 targetX = rectangleToPointTo.getRight();
143 arrowTip.x = content.getX() - arrowLength;
147 setBounds (targetX - arrowTip.x, targetY - arrowTip.y, totalW, totalH);
150 } // namespace juce