mirror of
https://github.com/juce-framework/JUCE.git
synced 2026-01-18 00:54:19 +00:00
Added the ability to apply affine transforms to components - Component::setTransform(). Added a slider to the widgets demo to show this in action. Changed Component::reallyContains() to take a rectangle instead of raw coordinates.
This commit is contained in:
parent
75ff0c5e7e
commit
2c2a11dee9
15 changed files with 533 additions and 242 deletions
|
|
@ -1088,7 +1088,8 @@ public:
|
|||
|
||||
//==============================================================================
|
||||
class WidgetsDemo : public Component,
|
||||
public ButtonListener
|
||||
public ButtonListener,
|
||||
public SliderListener
|
||||
{
|
||||
public:
|
||||
//==============================================================================
|
||||
|
|
@ -1111,9 +1112,17 @@ public:
|
|||
//==============================================================================
|
||||
addAndMakeVisible (&enableButton);
|
||||
enableButton.setBounds (230, 10, 180, 24);
|
||||
enableButton.setTooltip ("toggle button");
|
||||
enableButton.setTooltip ("Enables/disables all the components");
|
||||
enableButton.setToggleState (true, false);
|
||||
enableButton.addButtonListener (this);
|
||||
|
||||
addAndMakeVisible (&transformSlider);
|
||||
transformSlider.setSliderStyle (Slider::LinearBar);
|
||||
transformSlider.setTextValueSuffix (" degrees rotation");
|
||||
transformSlider.setRange (-180.0, 180.0, 0.1);
|
||||
transformSlider.setBounds (440, 10, 180, 24);
|
||||
transformSlider.setTooltip ("Applies a transform to the components");
|
||||
transformSlider.addListener (this);
|
||||
}
|
||||
|
||||
~WidgetsDemo()
|
||||
|
|
@ -1397,9 +1406,17 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
void sliderValueChanged (Slider*)
|
||||
{
|
||||
// When you move the roation slider, we'll apply a rotaion transform to the whole tabs component..
|
||||
tabs.setTransform (AffineTransform::rotation ((float) (transformSlider.getValue() / (180.0 / double_Pi)),
|
||||
getWidth() * 0.5f, getHeight() * 0.5f));
|
||||
}
|
||||
|
||||
private:
|
||||
TextButton menuButton;
|
||||
ToggleButton enableButton;
|
||||
Slider transformSlider;
|
||||
DemoTabbedComponent tabs;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -39782,7 +39782,7 @@ END_JUCE_NAMESPACE
|
|||
/*** Start of inlined file: juce_Component.cpp ***/
|
||||
BEGIN_JUCE_NAMESPACE
|
||||
|
||||
#define checkMessageManagerIsLocked jassert (MessageManager::getInstance()->currentThreadHasLockedMessageManager());
|
||||
#define CHECK_MESSAGE_MANAGER_IS_LOCKED jassert (MessageManager::getInstance()->currentThreadHasLockedMessageManager());
|
||||
|
||||
Component* Component::currentlyFocusedComponent = 0;
|
||||
|
||||
|
|
@ -39982,22 +39982,34 @@ public:
|
|||
|
||||
static const Point<int> convertFromParentSpace (const Component& comp, const Point<int>& pointInParentSpace)
|
||||
{
|
||||
return pointInParentSpace - comp.getPosition();
|
||||
if (comp.affineTransform_ == 0)
|
||||
return pointInParentSpace - comp.getPosition();
|
||||
|
||||
return pointInParentSpace.toFloat().transformedBy (comp.affineTransform_->inverted()).toInt() - comp.getPosition();
|
||||
}
|
||||
|
||||
static const Rectangle<int> convertFromParentSpace (const Component& comp, const Rectangle<int>& areaInParentSpace)
|
||||
{
|
||||
return areaInParentSpace - comp.getPosition();
|
||||
if (comp.affineTransform_ == 0)
|
||||
return areaInParentSpace - comp.getPosition();
|
||||
|
||||
return areaInParentSpace.toFloat().transformed (comp.affineTransform_->inverted()).getSmallestIntegerContainer() - comp.getPosition();
|
||||
}
|
||||
|
||||
static const Point<int> convertToParentSpace (const Component& comp, const Point<int>& pointInLocalSpace)
|
||||
{
|
||||
return pointInLocalSpace + comp.getPosition();
|
||||
if (comp.affineTransform_ == 0)
|
||||
return pointInLocalSpace + comp.getPosition();
|
||||
|
||||
return (pointInLocalSpace + comp.getPosition()).toFloat().transformedBy (*comp.affineTransform_).toInt();
|
||||
}
|
||||
|
||||
static const Rectangle<int> convertToParentSpace (const Component& comp, const Rectangle<int>& areaInLocalSpace)
|
||||
{
|
||||
return areaInLocalSpace + comp.getPosition();
|
||||
if (comp.affineTransform_ == 0)
|
||||
return areaInLocalSpace + comp.getPosition();
|
||||
|
||||
return (areaInLocalSpace + comp.getPosition()).toFloat().transformed (*comp.affineTransform_).getSmallestIntegerContainer();
|
||||
}
|
||||
|
||||
template <typename Type>
|
||||
|
|
@ -40070,8 +40082,7 @@ public:
|
|||
{
|
||||
const Component& child = *comp.childComponentList_.getUnchecked(i);
|
||||
|
||||
//xxx if (child.isVisible() && ! child.isTransformed())
|
||||
if (child.isVisible())
|
||||
if (child.isVisible() && ! child.isTransformed())
|
||||
{
|
||||
const Rectangle<int> newClip (clipRect.getIntersection (child.bounds_));
|
||||
|
||||
|
|
@ -40195,7 +40206,7 @@ void Component::setName (const String& name)
|
|||
{
|
||||
// if component methods are being called from threads other than the message
|
||||
// thread, you'll need to use a MessageManagerLock object to make sure it's thread-safe.
|
||||
checkMessageManagerIsLocked
|
||||
CHECK_MESSAGE_MANAGER_IS_LOCKED
|
||||
|
||||
if (componentName_ != name)
|
||||
{
|
||||
|
|
@ -40221,7 +40232,7 @@ void Component::setVisible (bool shouldBeVisible)
|
|||
{
|
||||
// if component methods are being called from threads other than the message
|
||||
// thread, you'll need to use a MessageManagerLock object to make sure it's thread-safe.
|
||||
checkMessageManagerIsLocked
|
||||
CHECK_MESSAGE_MANAGER_IS_LOCKED
|
||||
|
||||
SafePointer<Component> safePointer (this);
|
||||
|
||||
|
|
@ -40309,7 +40320,7 @@ void Component::addToDesktop (int styleWanted, void* nativeWindowToAttachTo)
|
|||
{
|
||||
// if component methods are being called from threads other than the message
|
||||
// thread, you'll need to use a MessageManagerLock object to make sure it's thread-safe.
|
||||
checkMessageManagerIsLocked
|
||||
CHECK_MESSAGE_MANAGER_IS_LOCKED
|
||||
|
||||
if (isOpaque())
|
||||
styleWanted &= ~ComponentPeer::windowIsSemiTransparent;
|
||||
|
|
@ -40397,7 +40408,7 @@ void Component::removeFromDesktop()
|
|||
{
|
||||
// if component methods are being called from threads other than the message
|
||||
// thread, you'll need to use a MessageManagerLock object to make sure it's thread-safe.
|
||||
checkMessageManagerIsLocked
|
||||
CHECK_MESSAGE_MANAGER_IS_LOCKED
|
||||
|
||||
if (flags.hasHeavyweightPeerFlag)
|
||||
{
|
||||
|
|
@ -40472,7 +40483,7 @@ void Component::toFront (const bool setAsForeground)
|
|||
{
|
||||
// if component methods are being called from threads other than the message
|
||||
// thread, you'll need to use a MessageManagerLock object to make sure it's thread-safe.
|
||||
checkMessageManagerIsLocked
|
||||
CHECK_MESSAGE_MANAGER_IS_LOCKED
|
||||
|
||||
if (flags.hasHeavyweightPeerFlag)
|
||||
{
|
||||
|
|
@ -40711,7 +40722,7 @@ void Component::setBounds (const int x, const int y, int w, int h)
|
|||
{
|
||||
// if component methods are being called from threads other than the message
|
||||
// thread, you'll need to use a MessageManagerLock object to make sure it's thread-safe.
|
||||
checkMessageManagerIsLocked
|
||||
CHECK_MESSAGE_MANAGER_IS_LOCKED
|
||||
|
||||
if (w < 0) w = 0;
|
||||
if (h < 0) h = 0;
|
||||
|
|
@ -40899,6 +40910,41 @@ void Component::setBoundsToFit (int x, int y, int width, int height,
|
|||
}
|
||||
}
|
||||
|
||||
bool Component::isTransformed() const throw()
|
||||
{
|
||||
return affineTransform_ != 0;
|
||||
}
|
||||
|
||||
void Component::setTransform (const AffineTransform& newTransform)
|
||||
{
|
||||
if (newTransform.isIdentity())
|
||||
{
|
||||
if (affineTransform_ != 0)
|
||||
{
|
||||
repaint();
|
||||
affineTransform_ = 0;
|
||||
repaint();
|
||||
}
|
||||
}
|
||||
else if (affineTransform_ == 0)
|
||||
{
|
||||
repaint();
|
||||
affineTransform_ = new AffineTransform (newTransform);
|
||||
repaint();
|
||||
}
|
||||
else if (*affineTransform_ != newTransform)
|
||||
{
|
||||
repaint();
|
||||
*affineTransform_ = newTransform;
|
||||
repaint();
|
||||
}
|
||||
}
|
||||
|
||||
const AffineTransform Component::getTransform() const
|
||||
{
|
||||
return affineTransform_ != 0 ? *affineTransform_ : AffineTransform::identity;
|
||||
}
|
||||
|
||||
bool Component::hitTest (int x, int y)
|
||||
{
|
||||
if (! flags.ignoresMouseClicksFlag)
|
||||
|
|
@ -40953,15 +40999,13 @@ bool Component::contains (const Point<int>& point)
|
|||
return false;
|
||||
}
|
||||
|
||||
bool Component::reallyContains (const int x, const int y, const bool returnTrueIfWithinAChild)
|
||||
bool Component::reallyContains (const Point<int>& point, const bool returnTrueIfWithinAChild)
|
||||
{
|
||||
const Point<int> p (x, y);
|
||||
|
||||
if (! contains (p))
|
||||
if (! contains (point))
|
||||
return false;
|
||||
|
||||
Component* const top = getTopLevelComponent();
|
||||
const Component* const compAtPosition = top->getComponentAt (top->getLocalPoint (this, p));
|
||||
const Component* const compAtPosition = top->getComponentAt (top->getLocalPoint (this, point));
|
||||
|
||||
return (compAtPosition == this) || (returnTrueIfWithinAChild && isParentOf (compAtPosition));
|
||||
}
|
||||
|
|
@ -40994,7 +41038,7 @@ void Component::addChildComponent (Component* const child, int zOrder)
|
|||
{
|
||||
// if component methods are being called from threads other than the message
|
||||
// thread, you'll need to use a MessageManagerLock object to make sure it's thread-safe.
|
||||
checkMessageManagerIsLocked
|
||||
CHECK_MESSAGE_MANAGER_IS_LOCKED
|
||||
|
||||
if (child != 0 && child->parentComponent_ != this)
|
||||
{
|
||||
|
|
@ -41047,7 +41091,7 @@ Component* Component::removeChildComponent (const int index)
|
|||
{
|
||||
// if component methods are being called from threads other than the message
|
||||
// thread, you'll need to use a MessageManagerLock object to make sure it's thread-safe.
|
||||
checkMessageManagerIsLocked
|
||||
CHECK_MESSAGE_MANAGER_IS_LOCKED
|
||||
|
||||
Component* const child = childComponentList_ [index];
|
||||
|
||||
|
|
@ -41215,7 +41259,7 @@ void Component::enterModalState (const bool takeKeyboardFocus_, ModalComponentMa
|
|||
{
|
||||
// if component methods are being called from threads other than the message
|
||||
// thread, you'll need to use a MessageManagerLock object to make sure it's thread-safe.
|
||||
checkMessageManagerIsLocked
|
||||
CHECK_MESSAGE_MANAGER_IS_LOCKED
|
||||
|
||||
// Check for an attempt to make a component modal when it already is!
|
||||
// This can cause nasty problems..
|
||||
|
|
@ -41385,7 +41429,7 @@ void Component::internalRepaint (int x, int y, int w, int h)
|
|||
{
|
||||
// if component methods are being called from threads other than the message
|
||||
// thread, you'll need to use a MessageManagerLock object to make sure it's thread-safe.
|
||||
checkMessageManagerIsLocked
|
||||
CHECK_MESSAGE_MANAGER_IS_LOCKED
|
||||
|
||||
if (x < 0)
|
||||
{
|
||||
|
|
@ -41412,7 +41456,17 @@ void Component::internalRepaint (int x, int y, int w, int h)
|
|||
if (parentComponent_ != 0)
|
||||
{
|
||||
if (parentComponent_->flags.visibleFlag)
|
||||
parentComponent_->internalRepaint (x + getX(), y + getY(), w, h);
|
||||
{
|
||||
if (affineTransform_ == 0)
|
||||
{
|
||||
parentComponent_->internalRepaint (x + getX(), y + getY(), w, h);
|
||||
}
|
||||
else
|
||||
{
|
||||
const Rectangle<int> r (ComponentHelpers::convertToParentSpace (*this, Rectangle<int> (x, y, w, h)));
|
||||
parentComponent_->internalRepaint (r.getX(), r.getY(), r.getWidth(), r.getHeight());
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (flags.hasHeavyweightPeerFlag)
|
||||
{
|
||||
|
|
@ -41447,6 +41501,15 @@ void Component::paintComponent (Graphics& g)
|
|||
}
|
||||
}
|
||||
|
||||
void Component::paintTransformedChild (Graphics& g)
|
||||
{
|
||||
if (affineTransform_ != 0)
|
||||
g.addTransform (*affineTransform_);
|
||||
|
||||
g.setOrigin (getX(), getY());
|
||||
paintEntireComponent (g, false);
|
||||
}
|
||||
|
||||
void Component::paintComponentAndChildren (Graphics& g)
|
||||
{
|
||||
const Rectangle<int> clipBounds (g.getClipBounds());
|
||||
|
|
@ -41476,8 +41539,7 @@ void Component::paintComponentAndChildren (Graphics& g)
|
|||
|
||||
if (child->flags.dontClipGraphicsFlag)
|
||||
{
|
||||
g.setOrigin (child->getX(), child->getY());
|
||||
child->paintEntireComponent (g, false);
|
||||
child->paintTransformedChild (g);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -41497,10 +41559,7 @@ void Component::paintComponentAndChildren (Graphics& g)
|
|||
}
|
||||
|
||||
if (nothingClipped || ! g.isClipEmpty())
|
||||
{
|
||||
g.setOrigin (child->getX(), child->getY());
|
||||
child->paintEntireComponent (g, false);
|
||||
}
|
||||
child->paintTransformedChild (g);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -41860,7 +41919,7 @@ void Component::addMouseListener (MouseListener* const newListener,
|
|||
{
|
||||
// if component methods are being called from threads other than the message
|
||||
// thread, you'll need to use a MessageManagerLock object to make sure it's thread-safe.
|
||||
checkMessageManagerIsLocked
|
||||
CHECK_MESSAGE_MANAGER_IS_LOCKED
|
||||
|
||||
// If you register a component as a mouselistener for itself, it'll receive all the events
|
||||
// twice - once via the direct callback that all components get anyway, and then again as a listener!
|
||||
|
|
@ -41876,7 +41935,7 @@ void Component::removeMouseListener (MouseListener* const listenerToRemove)
|
|||
{
|
||||
// if component methods are being called from threads other than the message
|
||||
// thread, you'll need to use a MessageManagerLock object to make sure it's thread-safe.
|
||||
checkMessageManagerIsLocked
|
||||
CHECK_MESSAGE_MANAGER_IS_LOCKED
|
||||
|
||||
if (mouseListeners_ != 0)
|
||||
mouseListeners_->removeListener (listenerToRemove);
|
||||
|
|
@ -42131,7 +42190,7 @@ void Component::internalMouseDrag (MouseInputSource& source, const Point<int>& r
|
|||
{
|
||||
Desktop& desktop = Desktop::getInstance();
|
||||
|
||||
flags.mouseOverFlag = reallyContains (relativePos.getX(), relativePos.getY(), false);
|
||||
flags.mouseOverFlag = reallyContains (relativePos, false);
|
||||
|
||||
BailOutChecker checker (this);
|
||||
|
||||
|
|
@ -42499,7 +42558,7 @@ void Component::grabKeyboardFocus()
|
|||
{
|
||||
// if component methods are being called from threads other than the message
|
||||
// thread, you'll need to use a MessageManagerLock object to make sure it's thread-safe.
|
||||
checkMessageManagerIsLocked
|
||||
CHECK_MESSAGE_MANAGER_IS_LOCKED
|
||||
|
||||
grabFocusInternal (focusChangedDirectly);
|
||||
}
|
||||
|
|
@ -42508,7 +42567,7 @@ void Component::moveKeyboardFocusToSibling (const bool moveToNext)
|
|||
{
|
||||
// if component methods are being called from threads other than the message
|
||||
// thread, you'll need to use a MessageManagerLock object to make sure it's thread-safe.
|
||||
checkMessageManagerIsLocked
|
||||
CHECK_MESSAGE_MANAGER_IS_LOCKED
|
||||
|
||||
if (parentComponent_ != 0)
|
||||
{
|
||||
|
|
@ -42563,20 +42622,9 @@ void Component::giveAwayFocus()
|
|||
componentLosingFocus->internalFocusLoss (focusChangedDirectly);
|
||||
}
|
||||
|
||||
bool Component::isMouseOver() const throw()
|
||||
{
|
||||
return flags.mouseOverFlag;
|
||||
}
|
||||
|
||||
bool Component::isMouseButtonDown() const throw()
|
||||
{
|
||||
return flags.mouseDownFlag;
|
||||
}
|
||||
|
||||
bool Component::isMouseOverOrDragging() const throw()
|
||||
{
|
||||
return flags.mouseOverFlag || flags.mouseDownFlag;
|
||||
}
|
||||
bool Component::isMouseOver() const throw() { return flags.mouseOverFlag; }
|
||||
bool Component::isMouseButtonDown() const throw() { return flags.mouseDownFlag; }
|
||||
bool Component::isMouseOverOrDragging() const throw() { return flags.mouseOverFlag || flags.mouseDownFlag; }
|
||||
|
||||
bool JUCE_CALLTYPE Component::isMouseButtonDownAnywhere() throw()
|
||||
{
|
||||
|
|
@ -42590,8 +42638,7 @@ const Point<int> Component::getMouseXYRelative() const
|
|||
|
||||
const Rectangle<int> Component::getParentMonitorArea() const
|
||||
{
|
||||
return Desktop::getInstance()
|
||||
.getMonitorAreaContaining (localPointToGlobal (getLocalBounds().getCentre()));
|
||||
return Desktop::getInstance().getMonitorAreaContaining (getScreenBounds().getCentre());
|
||||
}
|
||||
|
||||
void Component::addKeyListener (KeyListener* const newListener)
|
||||
|
|
@ -43515,34 +43562,29 @@ void Button::turnOffOtherButtonsInGroup (const bool sendChangeNotification)
|
|||
|
||||
void Button::enablementChanged()
|
||||
{
|
||||
updateState (0);
|
||||
updateState();
|
||||
repaint();
|
||||
}
|
||||
|
||||
Button::ButtonState Button::updateState (const MouseEvent* const e)
|
||||
Button::ButtonState Button::updateState()
|
||||
{
|
||||
ButtonState state = buttonNormal;
|
||||
return updateState (reallyContains (getMouseXYRelative(), true), isMouseButtonDown());
|
||||
}
|
||||
|
||||
Button::ButtonState Button::updateState (const bool over, const bool down)
|
||||
{
|
||||
ButtonState newState = buttonNormal;
|
||||
|
||||
if (isEnabled() && isVisible() && ! isCurrentlyBlockedByAnotherModalComponent())
|
||||
{
|
||||
Point<int> mousePos;
|
||||
|
||||
if (e == 0)
|
||||
mousePos = getMouseXYRelative();
|
||||
else
|
||||
mousePos = e->getEventRelativeTo (this).getPosition();
|
||||
|
||||
const bool over = reallyContains (mousePos.getX(), mousePos.getY(), true);
|
||||
const bool down = isMouseButtonDown();
|
||||
|
||||
if ((down && (over || (triggerOnMouseDown && buttonState == buttonDown))) || isKeyDown)
|
||||
state = buttonDown;
|
||||
newState = buttonDown;
|
||||
else if (over)
|
||||
state = buttonOver;
|
||||
newState = buttonOver;
|
||||
}
|
||||
|
||||
setState (state);
|
||||
return state;
|
||||
setState (newState);
|
||||
return newState;
|
||||
}
|
||||
|
||||
void Button::setState (const ButtonState newState)
|
||||
|
|
@ -43687,19 +43729,19 @@ void Button::paint (Graphics& g)
|
|||
paintButton (g, isOver(), isDown());
|
||||
}
|
||||
|
||||
void Button::mouseEnter (const MouseEvent& e)
|
||||
void Button::mouseEnter (const MouseEvent&)
|
||||
{
|
||||
updateState (&e);
|
||||
updateState (true, false);
|
||||
}
|
||||
|
||||
void Button::mouseExit (const MouseEvent& e)
|
||||
void Button::mouseExit (const MouseEvent&)
|
||||
{
|
||||
updateState (&e);
|
||||
updateState (false, false);
|
||||
}
|
||||
|
||||
void Button::mouseDown (const MouseEvent& e)
|
||||
{
|
||||
updateState (&e);
|
||||
updateState (true, true);
|
||||
|
||||
if (isDown())
|
||||
{
|
||||
|
|
@ -43714,7 +43756,7 @@ void Button::mouseDown (const MouseEvent& e)
|
|||
void Button::mouseUp (const MouseEvent& e)
|
||||
{
|
||||
const bool wasDown = isDown();
|
||||
updateState (&e);
|
||||
updateState (isMouseOver(), false);
|
||||
|
||||
if (wasDown && isOver() && ! triggerOnMouseDown)
|
||||
internalClickCallback (e.mods);
|
||||
|
|
@ -43723,7 +43765,7 @@ void Button::mouseUp (const MouseEvent& e)
|
|||
void Button::mouseDrag (const MouseEvent& e)
|
||||
{
|
||||
const ButtonState oldState = buttonState;
|
||||
updateState (&e);
|
||||
updateState (isMouseOver(), true);
|
||||
|
||||
if (autoRepeatDelay >= 0 && buttonState != oldState && isDown())
|
||||
getRepeatTimer().startTimer (autoRepeatSpeed);
|
||||
|
|
@ -43731,13 +43773,13 @@ void Button::mouseDrag (const MouseEvent& e)
|
|||
|
||||
void Button::focusGained (FocusChangeType)
|
||||
{
|
||||
updateState (0);
|
||||
updateState();
|
||||
repaint();
|
||||
}
|
||||
|
||||
void Button::focusLost (FocusChangeType)
|
||||
{
|
||||
updateState (0);
|
||||
updateState();
|
||||
repaint();
|
||||
}
|
||||
|
||||
|
|
@ -43750,7 +43792,7 @@ void Button::setVisible (bool shouldBeVisible)
|
|||
if (! shouldBeVisible)
|
||||
needsToRelease = false;
|
||||
|
||||
updateState (0);
|
||||
updateState();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -43878,7 +43920,7 @@ bool Button::keyStateChanged (const bool, Component*)
|
|||
if (autoRepeatDelay >= 0 && (isKeyDown && ! wasDown))
|
||||
getRepeatTimer().startTimer (autoRepeatDelay);
|
||||
|
||||
updateState (0);
|
||||
updateState();
|
||||
|
||||
if (isEnabled() && wasDown && ! isKeyDown)
|
||||
{
|
||||
|
|
@ -43922,10 +43964,10 @@ void Button::repeatTimerCallback()
|
|||
if (needsRepainting)
|
||||
{
|
||||
getRepeatTimer().stopTimer();
|
||||
updateState (0);
|
||||
updateState();
|
||||
needsRepainting = false;
|
||||
}
|
||||
else if (autoRepeatSpeed > 0 && (isKeyDown || (updateState (0) == buttonDown)))
|
||||
else if (autoRepeatSpeed > 0 && (isKeyDown || (updateState() == buttonDown)))
|
||||
{
|
||||
int repeatSpeed = autoRepeatSpeed;
|
||||
|
||||
|
|
@ -48020,7 +48062,7 @@ void ComboBox::mouseUp (const MouseEvent& e2)
|
|||
|
||||
const MouseEvent e (e2.getEventRelativeTo (this));
|
||||
|
||||
if (reallyContains (e.x, e.y, true)
|
||||
if (reallyContains (e.getPosition(), true)
|
||||
&& (e2.eventComponent == this || ! label->isEditable()))
|
||||
{
|
||||
showPopup();
|
||||
|
|
@ -49804,6 +49846,10 @@ void Slider::lookAndFeelChanged()
|
|||
|
||||
valueBox->setTooltip (getTooltip());
|
||||
}
|
||||
else
|
||||
{
|
||||
valueBox = 0;
|
||||
}
|
||||
|
||||
if (style == IncDecButtons)
|
||||
{
|
||||
|
|
@ -51750,7 +51796,7 @@ int TableHeaderComponent::getResizeDraggerAt (const int mouseX) const
|
|||
|
||||
void TableHeaderComponent::updateColumnUnderMouse (int x, int y)
|
||||
{
|
||||
const int newCol = (reallyContains (x, y, true) && getResizeDraggerAt (x) == 0)
|
||||
const int newCol = (reallyContains (Point<int> (x, y), true) && getResizeDraggerAt (x) == 0)
|
||||
? getColumnIdAtX (x) : 0;
|
||||
|
||||
if (newCol != columnIdUnderMouse)
|
||||
|
|
@ -68454,7 +68500,7 @@ int MenuBarComponent::getItemAt (const int x, const int y)
|
|||
{
|
||||
for (int i = 0; i < xPositions.size(); ++i)
|
||||
if (x >= xPositions[i] && x < xPositions[i + 1])
|
||||
return reallyContains (x, y, true) ? i : -1;
|
||||
return reallyContains (Point<int> (x, y), true) ? i : -1;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
|
@ -69243,7 +69289,7 @@ public:
|
|||
// comp that we're attached to.
|
||||
const Point<int> mousePos (componentAttachedTo->getMouseXYRelative());
|
||||
|
||||
if (componentAttachedTo->reallyContains (mousePos.getX(), mousePos.getY(), true))
|
||||
if (componentAttachedTo->reallyContains (mousePos, true))
|
||||
{
|
||||
postCommandMessage (PopupMenuSettings::dismissCommandId); // dismiss asynchrounously
|
||||
return;
|
||||
|
|
@ -69287,7 +69333,7 @@ public:
|
|||
const uint32 now = Time::getMillisecondCounter();
|
||||
|
||||
if (now > timeEnteredCurrentChildComp + 100
|
||||
&& reallyContains (localMousePos.getX(), localMousePos.getY(), true)
|
||||
&& reallyContains (localMousePos, true)
|
||||
&& currentChild != 0
|
||||
&& (! disableMouseMoves)
|
||||
&& ! (activeSubMenu != 0 && activeSubMenu->isVisible()))
|
||||
|
|
@ -69379,7 +69425,7 @@ public:
|
|||
else if (wasDown && now > menuCreationTime + 250
|
||||
&& ! (isDown || overScrollArea))
|
||||
{
|
||||
isOver = reallyContains (localMousePos.getX(), localMousePos.getY(), true);
|
||||
isOver = reallyContains (localMousePos, true);
|
||||
|
||||
if (isOver)
|
||||
{
|
||||
|
|
@ -69452,7 +69498,7 @@ private:
|
|||
void updateMouseOverStatus (const Point<int>& globalMousePos)
|
||||
{
|
||||
const Point<int> relPos (getLocalPoint (0, globalMousePos));
|
||||
isOver = reallyContains (relPos.getX(), relPos.getY(), true);
|
||||
isOver = reallyContains (relPos, true);
|
||||
|
||||
if (activeSubMenu != 0)
|
||||
activeSubMenu->updateMouseOverStatus (globalMousePos);
|
||||
|
|
@ -69798,7 +69844,7 @@ private:
|
|||
|
||||
void highlightItemUnderMouse (const Point<int>& globalMousePos, const Point<int>& localMousePos)
|
||||
{
|
||||
isOver = reallyContains (localMousePos.getX(), localMousePos.getY(), true);
|
||||
isOver = reallyContains (localMousePos, true);
|
||||
|
||||
if (isOver)
|
||||
hasBeenOver = true;
|
||||
|
|
@ -71732,7 +71778,7 @@ void MouseHoverDetector::hoverTimerCallback()
|
|||
{
|
||||
const Point<int> pos (source->getMouseXYRelative());
|
||||
|
||||
if (source->reallyContains (pos.getX(), pos.getY(), false))
|
||||
if (source->reallyContains (pos, false))
|
||||
{
|
||||
hasJustHovered = true;
|
||||
mouseHovered (pos.getX(), pos.getY());
|
||||
|
|
@ -75390,7 +75436,7 @@ const uint8 MidiKeyboardComponent::blackNotes[] = { 1, 3, 6, 8, 10 };
|
|||
|
||||
int MidiKeyboardComponent::xyToNote (const Point<int>& pos, float& mousePositionVelocity)
|
||||
{
|
||||
if (! reallyContains (pos.getX(), pos.getY(), false))
|
||||
if (! reallyContains (pos, false))
|
||||
return -1;
|
||||
|
||||
Point<int> p (pos);
|
||||
|
|
|
|||
|
|
@ -64,7 +64,7 @@
|
|||
*/
|
||||
#define JUCE_MAJOR_VERSION 1
|
||||
#define JUCE_MINOR_VERSION 52
|
||||
#define JUCE_BUILDNUMBER 94
|
||||
#define JUCE_BUILDNUMBER 95
|
||||
|
||||
/** Current Juce version number.
|
||||
|
||||
|
|
@ -26113,15 +26113,21 @@ public:
|
|||
*/
|
||||
bool isAlwaysOnTop() const throw();
|
||||
|
||||
/** Returns the x co-ordinate of the component's left edge.
|
||||
/** Returns the x coordinate of the component's left edge.
|
||||
This is a distance in pixels from the left edge of the component's parent.
|
||||
@see getScreenX
|
||||
|
||||
Note that if you've used setTransform() to apply a transform, then the component's
|
||||
bounds will no longer be a direct reflection of the position at which it appears within
|
||||
its parent, as the transform will be applied to its bounding box.
|
||||
*/
|
||||
inline int getX() const throw() { return bounds_.getX(); }
|
||||
|
||||
/** Returns the y co-ordinate of the top of this component.
|
||||
/** Returns the y coordinate of the top of this component.
|
||||
This is a distance in pixels from the top edge of the component's parent.
|
||||
@see getScreenY
|
||||
|
||||
Note that if you've used setTransform() to apply a transform, then the component's
|
||||
bounds will no longer be a direct reflection of the position at which it appears within
|
||||
its parent, as the transform will be applied to its bounding box.
|
||||
*/
|
||||
inline int getY() const throw() { return bounds_.getY(); }
|
||||
|
||||
|
|
@ -26131,26 +26137,38 @@ public:
|
|||
/** Returns the component's height in pixels. */
|
||||
inline int getHeight() const throw() { return bounds_.getHeight(); }
|
||||
|
||||
/** Returns the x co-ordinate of the component's right-hand edge.
|
||||
/** Returns the x coordinate of the component's right-hand edge.
|
||||
This is a distance in pixels from the left edge of the component's parent.
|
||||
|
||||
Note that if you've used setTransform() to apply a transform, then the component's
|
||||
bounds will no longer be a direct reflection of the position at which it appears within
|
||||
its parent, as the transform will be applied to its bounding box.
|
||||
*/
|
||||
int getRight() const throw() { return bounds_.getRight(); }
|
||||
|
||||
/** Returns the component's top-left position as a Point. */
|
||||
const Point<int> getPosition() const throw() { return bounds_.getPosition(); }
|
||||
|
||||
/** Returns the y co-ordinate of the bottom edge of this component.
|
||||
/** Returns the y coordinate of the bottom edge of this component.
|
||||
This is a distance in pixels from the top edge of the component's parent.
|
||||
|
||||
Note that if you've used setTransform() to apply a transform, then the component's
|
||||
bounds will no longer be a direct reflection of the position at which it appears within
|
||||
its parent, as the transform will be applied to its bounding box.
|
||||
*/
|
||||
int getBottom() const throw() { return bounds_.getBottom(); }
|
||||
|
||||
/** Returns this component's bounding box.
|
||||
The rectangle returned is relative to the top-left of the component's parent.
|
||||
|
||||
Note that if you've used setTransform() to apply a transform, then the component's
|
||||
bounds will no longer be a direct reflection of the position at which it appears within
|
||||
its parent, as the transform will be applied to its bounding box.
|
||||
*/
|
||||
const Rectangle<int>& getBounds() const throw() { return bounds_; }
|
||||
|
||||
/** Returns the component's bounds, relative to its own origin.
|
||||
This is like getBounds(), but returns the rectangle in local co-ordinates, In practice, it'll
|
||||
This is like getBounds(), but returns the rectangle in local coordinates, In practice, it'll
|
||||
return a rectangle with position (0, 0), and the same size as this component.
|
||||
*/
|
||||
const Rectangle<int> getLocalBounds() const throw();
|
||||
|
|
@ -26166,12 +26184,12 @@ public:
|
|||
void getVisibleArea (RectangleList& result,
|
||||
bool includeSiblings) const;
|
||||
|
||||
/** Returns this component's x co-ordinate relative the the screen's top-left origin.
|
||||
/** Returns this component's x coordinate relative the the screen's top-left origin.
|
||||
@see getX, localPointToGlobal
|
||||
*/
|
||||
int getScreenX() const;
|
||||
|
||||
/** Returns this component's y co-ordinate relative the the screen's top-left origin.
|
||||
/** Returns this component's y coordinate relative the the screen's top-left origin.
|
||||
@see getY, localPointToGlobal
|
||||
*/
|
||||
int getScreenY() const;
|
||||
|
|
@ -26200,6 +26218,10 @@ public:
|
|||
This takes a rectangle that is relative to a different component, and returns its position relative
|
||||
to this component. If the sourceComponent parameter is null, the source rectangle is assumed to be
|
||||
a screen coordinate.
|
||||
|
||||
If you've used setTransform() to apply one or more transforms to components, then the source rectangle
|
||||
may not actually be rectanglular when converted to the target space, so in that situation this will return
|
||||
the smallest rectangle that fully contains the transformed area.
|
||||
*/
|
||||
const Rectangle<int> getLocalArea (const Component* sourceComponent,
|
||||
const Rectangle<int>& areaRelativeToSourceComponent) const;
|
||||
|
|
@ -26210,6 +26232,10 @@ public:
|
|||
const Point<int> localPointToGlobal (const Point<int>& localPoint) const;
|
||||
|
||||
/** Converts a rectangle from this component's coordinate space to a screen coordinate.
|
||||
|
||||
If you've used setTransform() to apply one or more transforms to components, then the source rectangle
|
||||
may not actually be rectanglular when converted to the target space, so in that situation this will return
|
||||
the smallest rectangle that fully contains the transformed area.
|
||||
@see getLocalPoint, localPointToGlobal
|
||||
*/
|
||||
const Rectangle<int> localAreaToGlobal (const Rectangle<int>& localArea) const;
|
||||
|
|
@ -26221,6 +26247,10 @@ public:
|
|||
|
||||
If the component actually moves, this method will make a synchronous call to moved().
|
||||
|
||||
Note that if you've used setTransform() to apply a transform, then the component's
|
||||
bounds will no longer be a direct reflection of the position at which it appears within
|
||||
its parent, as the transform will be applied to whatever bounds you set for it.
|
||||
|
||||
@see setBounds, ComponentListener::componentMovedOrResized
|
||||
*/
|
||||
void setTopLeftPosition (int x, int y);
|
||||
|
|
@ -26231,29 +26261,51 @@ public:
|
|||
The position is relative to the top-left of the component's parent.
|
||||
|
||||
If the component actually moves, this method will make a synchronous call to moved().
|
||||
|
||||
Note that if you've used setTransform() to apply a transform, then the component's
|
||||
bounds will no longer be a direct reflection of the position at which it appears within
|
||||
its parent, as the transform will be applied to whatever bounds you set for it.
|
||||
*/
|
||||
void setTopRightPosition (int x, int y);
|
||||
|
||||
/** Changes the size of the component.
|
||||
|
||||
A synchronous call to resized() will be occur if the size actually changes.
|
||||
|
||||
Note that if you've used setTransform() to apply a transform, then the component's
|
||||
bounds will no longer be a direct reflection of the position at which it appears within
|
||||
its parent, as the transform will be applied to whatever bounds you set for it.
|
||||
*/
|
||||
void setSize (int newWidth, int newHeight);
|
||||
|
||||
/** Changes the component's position and size.
|
||||
|
||||
The co-ordinates are relative to the top-left of the component's parent, or relative
|
||||
The coordinates are relative to the top-left of the component's parent, or relative
|
||||
to the origin of the screen is the component is on the desktop.
|
||||
|
||||
If this method changes the component's top-left position, it will make a synchronous
|
||||
call to moved(). If it changes the size, it will also make a call to resized().
|
||||
|
||||
Note that if you've used setTransform() to apply a transform, then the component's
|
||||
bounds will no longer be a direct reflection of the position at which it appears within
|
||||
its parent, as the transform will be applied to whatever bounds you set for it.
|
||||
|
||||
@see setTopLeftPosition, setSize, ComponentListener::componentMovedOrResized
|
||||
*/
|
||||
void setBounds (int x, int y, int width, int height);
|
||||
|
||||
/** Changes the component's position and size.
|
||||
|
||||
The coordinates are relative to the top-left of the component's parent, or relative
|
||||
to the origin of the screen is the component is on the desktop.
|
||||
|
||||
If this method changes the component's top-left position, it will make a synchronous
|
||||
call to moved(). If it changes the size, it will also make a call to resized().
|
||||
|
||||
Note that if you've used setTransform() to apply a transform, then the component's
|
||||
bounds will no longer be a direct reflection of the position at which it appears within
|
||||
its parent, as the transform will be applied to whatever bounds you set for it.
|
||||
|
||||
@see setBounds
|
||||
*/
|
||||
void setBounds (const Rectangle<int>& newBounds);
|
||||
|
|
@ -26264,6 +26316,8 @@ public:
|
|||
setBoundsRelative (0.2f, 0.2f, 0.5f, 0.5f) would give it half the
|
||||
width and height of the parent, with its top-left position 20% of
|
||||
the way across and down the parent.
|
||||
|
||||
@see setBounds
|
||||
*/
|
||||
void setBoundsRelative (float proportionalX, float proportionalY,
|
||||
float proportionalWidth, float proportionalHeight);
|
||||
|
|
@ -26272,6 +26326,8 @@ public:
|
|||
|
||||
This will position the component within its parent, leaving the specified number of
|
||||
pixels around each edge.
|
||||
|
||||
@see setBounds
|
||||
*/
|
||||
void setBoundsInset (const BorderSize& borders);
|
||||
|
||||
|
|
@ -26286,6 +26342,8 @@ public:
|
|||
|
||||
It will then be positioned within the rectangle according to the justification flags
|
||||
specified.
|
||||
|
||||
@see setBounds
|
||||
*/
|
||||
void setBoundsToFit (int x, int y, int width, int height,
|
||||
const Justification& justification,
|
||||
|
|
@ -26295,6 +26353,8 @@ public:
|
|||
|
||||
Leaves the component's size unchanged, but sets the position of its centre
|
||||
relative to its parent's top-left.
|
||||
|
||||
@see setBounds
|
||||
*/
|
||||
void setCentrePosition (int x, int y);
|
||||
|
||||
|
|
@ -26314,6 +26374,37 @@ public:
|
|||
*/
|
||||
void centreWithSize (int width, int height);
|
||||
|
||||
/** Sets a transform matrix to be applied to this component.
|
||||
|
||||
If you set a transform for a component, the component's position will be warped by it, relative to
|
||||
the component's parent's top-left origin. This means that the values you pass into setBounds() will no
|
||||
longer reflect the actual area within the parent that the component covers, as the bounds will be
|
||||
transformed and the component will probably end up actually appearing somewhere else within its parent.
|
||||
|
||||
When using transforms you need to be extremely careful when converting coordinates between the
|
||||
coordinate spaces of different components or the screen - you should always use getLocalPoint(),
|
||||
getLocalArea(), etc to do this, and never just manually add a component's position to a point in order to
|
||||
convert it between different components (but I'm sure you would never have done that anyway...).
|
||||
|
||||
Currently, transforms are not supported for desktop windows, so the transform will be ignored if you
|
||||
put a component on the desktop.
|
||||
|
||||
To remove a component's transform, simply pass AffineTransform::identity as the parameter to this method.
|
||||
*/
|
||||
void setTransform (const AffineTransform& transform);
|
||||
|
||||
/** Returns the transform that is currently being applied to this component.
|
||||
For more details about transforms, see setTransform().
|
||||
@see setTransform
|
||||
*/
|
||||
const AffineTransform getTransform() const;
|
||||
|
||||
/** Returns true if a non-identity transform is being applied to this component.
|
||||
For more details about transforms, see setTransform().
|
||||
@see setTransform
|
||||
*/
|
||||
bool isTransformed() const throw();
|
||||
|
||||
/** Returns a proportion of the component's width.
|
||||
|
||||
This is a handy equivalent of (getWidth() * proportion).
|
||||
|
|
@ -26340,7 +26431,7 @@ public:
|
|||
*/
|
||||
int getParentHeight() const throw();
|
||||
|
||||
/** Returns the screen co-ordinates of the monitor that contains this component.
|
||||
/** Returns the screen coordinates of the monitor that contains this component.
|
||||
|
||||
If there's only one monitor, this will return its size - if there are multiple
|
||||
monitors, it will return the area of the monitor that contains the component's
|
||||
|
|
@ -26509,7 +26600,7 @@ public:
|
|||
Overriding this method allows you to create components which only intercept
|
||||
mouse-clicks within a user-defined area.
|
||||
|
||||
This is called to find out whether a particular x, y co-ordinate is
|
||||
This is called to find out whether a particular x, y coordinate is
|
||||
considered to be inside the component or not, and is used by methods such
|
||||
as contains() and getComponentAt() to work out which component
|
||||
the mouse is clicked on.
|
||||
|
|
@ -26531,10 +26622,10 @@ public:
|
|||
Note that for components on the desktop, this method will be ignored, because it's
|
||||
not always possible to implement this behaviour on all platforms.
|
||||
|
||||
@param x the x co-ordinate to test, relative to the left hand edge of this
|
||||
@param x the x coordinate to test, relative to the left hand edge of this
|
||||
component. This value is guaranteed to be greater than or equal to
|
||||
zero, and less than the component's width
|
||||
@param y the y co-ordinate to test, relative to the top edge of this
|
||||
@param y the y coordinate to test, relative to the top edge of this
|
||||
component. This value is guaranteed to be greater than or equal to
|
||||
zero, and less than the component's height
|
||||
@returns true if the click is considered to be inside the component
|
||||
|
|
@ -26576,32 +26667,29 @@ public:
|
|||
|
||||
Never override this method! Use hitTest to create custom hit regions.
|
||||
|
||||
@param point the x co-ordinate to test, relative to this component's top-left.
|
||||
@param localPoint the coordinate to test, relative to this component's top-left.
|
||||
@returns true if the point is within the component's hit-test area, but only if
|
||||
that part of the component isn't clipped by its parent component. Note
|
||||
that this won't take into account any overlapping sibling components
|
||||
which might be in the way - for that, see reallyContains()
|
||||
@see hitTest, reallyContains, getComponentAt
|
||||
*/
|
||||
bool contains (const Point<int>& point);
|
||||
bool contains (const Point<int>& localPoint);
|
||||
|
||||
/** Returns true if a given point lies in this component, taking any overlapping
|
||||
siblings into account.
|
||||
|
||||
@param x the x co-ordinate to test, relative to this component's left hand edge.
|
||||
@param y the y co-ordinate to test, relative to this component's top edge.
|
||||
@param returnTrueIfWithinAChild if the point actually lies within a child of this
|
||||
component, this determines the value that will
|
||||
be returned.
|
||||
|
||||
@param localPoint the coordinate to test, relative to this component's top-left.
|
||||
@param returnTrueIfWithinAChild if the point actually lies within a child of this component,
|
||||
this determines whether that is counted as a hit.
|
||||
@see contains, getComponentAt
|
||||
*/
|
||||
bool reallyContains (int x, int y, bool returnTrueIfWithinAChild);
|
||||
bool reallyContains (const Point<int>& localPoint, bool returnTrueIfWithinAChild);
|
||||
|
||||
/** Returns the component at a certain point within this one.
|
||||
|
||||
@param x the x co-ordinate to test, relative to this component's left hand edge.
|
||||
@param y the y co-ordinate to test, relative to this component's top edge.
|
||||
@param x the x coordinate to test, relative to this component's left edge.
|
||||
@param y the y coordinate to test, relative to this component's top edge.
|
||||
@returns the component that is at this position - which may be 0, this component,
|
||||
or one of its children. Note that overlapping siblings that might actually
|
||||
be in the way are not taken into account by this method - to account for these,
|
||||
|
|
@ -26612,7 +26700,7 @@ public:
|
|||
|
||||
/** Returns the component at a certain point within this one.
|
||||
|
||||
@param position the co-ordinates to test, relative to this component's top-left.
|
||||
@param position the coordinate to test, relative to this component's top-left.
|
||||
@returns the component that is at this position - which may be 0, this component,
|
||||
or one of its children. Note that overlapping siblings that might actually
|
||||
be in the way are not taken into account by this method - to account for these,
|
||||
|
|
@ -27442,8 +27530,7 @@ public:
|
|||
static bool JUCE_CALLTYPE isMouseButtonDownAnywhere() throw();
|
||||
|
||||
/** Returns the mouse's current position, relative to this component.
|
||||
|
||||
The co-ordinates are relative to the component's top-left corner.
|
||||
The return value is relative to the component's top-left corner.
|
||||
*/
|
||||
const Point<int> getMouseXYRelative() const;
|
||||
|
||||
|
|
@ -27849,6 +27936,7 @@ private:
|
|||
String componentName_;
|
||||
Component* parentComponent_;
|
||||
Rectangle<int> bounds_;
|
||||
ScopedPointer <AffineTransform> affineTransform_;
|
||||
Array <Component*> childComponentList_;
|
||||
LookAndFeel* lookAndFeel_;
|
||||
MouseCursor cursor_;
|
||||
|
|
@ -27914,6 +28002,7 @@ private:
|
|||
void internalHierarchyChanged();
|
||||
void paintComponentAndChildren (Graphics& g);
|
||||
void paintComponent (Graphics& g);
|
||||
void paintTransformedChild (Graphics& g);
|
||||
void sendMovedResizedMessages (bool wasMoved, bool wasResized);
|
||||
void repaintParent();
|
||||
void sendFakeMouseMove() const;
|
||||
|
|
@ -36206,7 +36295,8 @@ private:
|
|||
void repeatTimerCallback();
|
||||
RepeatTimer& getRepeatTimer();
|
||||
|
||||
ButtonState updateState (const MouseEvent*);
|
||||
ButtonState updateState();
|
||||
ButtonState updateState (bool isOver, bool isDown);
|
||||
bool isShortcutPressed() const;
|
||||
void turnOffOtherButtonsInGroup (bool sendChangeNotification);
|
||||
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@
|
|||
*/
|
||||
#define JUCE_MAJOR_VERSION 1
|
||||
#define JUCE_MINOR_VERSION 52
|
||||
#define JUCE_BUILDNUMBER 94
|
||||
#define JUCE_BUILDNUMBER 95
|
||||
|
||||
/** Current Juce version number.
|
||||
|
||||
|
|
|
|||
|
|
@ -227,34 +227,29 @@ void Button::turnOffOtherButtonsInGroup (const bool sendChangeNotification)
|
|||
//==============================================================================
|
||||
void Button::enablementChanged()
|
||||
{
|
||||
updateState (0);
|
||||
updateState();
|
||||
repaint();
|
||||
}
|
||||
|
||||
Button::ButtonState Button::updateState (const MouseEvent* const e)
|
||||
Button::ButtonState Button::updateState()
|
||||
{
|
||||
ButtonState state = buttonNormal;
|
||||
return updateState (reallyContains (getMouseXYRelative(), true), isMouseButtonDown());
|
||||
}
|
||||
|
||||
Button::ButtonState Button::updateState (const bool over, const bool down)
|
||||
{
|
||||
ButtonState newState = buttonNormal;
|
||||
|
||||
if (isEnabled() && isVisible() && ! isCurrentlyBlockedByAnotherModalComponent())
|
||||
{
|
||||
Point<int> mousePos;
|
||||
|
||||
if (e == 0)
|
||||
mousePos = getMouseXYRelative();
|
||||
else
|
||||
mousePos = e->getEventRelativeTo (this).getPosition();
|
||||
|
||||
const bool over = reallyContains (mousePos.getX(), mousePos.getY(), true);
|
||||
const bool down = isMouseButtonDown();
|
||||
|
||||
if ((down && (over || (triggerOnMouseDown && buttonState == buttonDown))) || isKeyDown)
|
||||
state = buttonDown;
|
||||
newState = buttonDown;
|
||||
else if (over)
|
||||
state = buttonOver;
|
||||
newState = buttonOver;
|
||||
}
|
||||
|
||||
setState (state);
|
||||
return state;
|
||||
setState (newState);
|
||||
return newState;
|
||||
}
|
||||
|
||||
void Button::setState (const ButtonState newState)
|
||||
|
|
@ -403,19 +398,19 @@ void Button::paint (Graphics& g)
|
|||
}
|
||||
|
||||
//==============================================================================
|
||||
void Button::mouseEnter (const MouseEvent& e)
|
||||
void Button::mouseEnter (const MouseEvent&)
|
||||
{
|
||||
updateState (&e);
|
||||
updateState (true, false);
|
||||
}
|
||||
|
||||
void Button::mouseExit (const MouseEvent& e)
|
||||
void Button::mouseExit (const MouseEvent&)
|
||||
{
|
||||
updateState (&e);
|
||||
updateState (false, false);
|
||||
}
|
||||
|
||||
void Button::mouseDown (const MouseEvent& e)
|
||||
{
|
||||
updateState (&e);
|
||||
updateState (true, true);
|
||||
|
||||
if (isDown())
|
||||
{
|
||||
|
|
@ -430,7 +425,7 @@ void Button::mouseDown (const MouseEvent& e)
|
|||
void Button::mouseUp (const MouseEvent& e)
|
||||
{
|
||||
const bool wasDown = isDown();
|
||||
updateState (&e);
|
||||
updateState (isMouseOver(), false);
|
||||
|
||||
if (wasDown && isOver() && ! triggerOnMouseDown)
|
||||
internalClickCallback (e.mods);
|
||||
|
|
@ -439,7 +434,7 @@ void Button::mouseUp (const MouseEvent& e)
|
|||
void Button::mouseDrag (const MouseEvent& e)
|
||||
{
|
||||
const ButtonState oldState = buttonState;
|
||||
updateState (&e);
|
||||
updateState (isMouseOver(), true);
|
||||
|
||||
if (autoRepeatDelay >= 0 && buttonState != oldState && isDown())
|
||||
getRepeatTimer().startTimer (autoRepeatSpeed);
|
||||
|
|
@ -447,13 +442,13 @@ void Button::mouseDrag (const MouseEvent& e)
|
|||
|
||||
void Button::focusGained (FocusChangeType)
|
||||
{
|
||||
updateState (0);
|
||||
updateState();
|
||||
repaint();
|
||||
}
|
||||
|
||||
void Button::focusLost (FocusChangeType)
|
||||
{
|
||||
updateState (0);
|
||||
updateState();
|
||||
repaint();
|
||||
}
|
||||
|
||||
|
|
@ -467,7 +462,7 @@ void Button::setVisible (bool shouldBeVisible)
|
|||
if (! shouldBeVisible)
|
||||
needsToRelease = false;
|
||||
|
||||
updateState (0);
|
||||
updateState();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -597,7 +592,7 @@ bool Button::keyStateChanged (const bool, Component*)
|
|||
if (autoRepeatDelay >= 0 && (isKeyDown && ! wasDown))
|
||||
getRepeatTimer().startTimer (autoRepeatDelay);
|
||||
|
||||
updateState (0);
|
||||
updateState();
|
||||
|
||||
if (isEnabled() && wasDown && ! isKeyDown)
|
||||
{
|
||||
|
|
@ -642,10 +637,10 @@ void Button::repeatTimerCallback()
|
|||
if (needsRepainting)
|
||||
{
|
||||
getRepeatTimer().stopTimer();
|
||||
updateState (0);
|
||||
updateState();
|
||||
needsRepainting = false;
|
||||
}
|
||||
else if (autoRepeatSpeed > 0 && (isKeyDown || (updateState (0) == buttonDown)))
|
||||
else if (autoRepeatSpeed > 0 && (isKeyDown || (updateState() == buttonDown)))
|
||||
{
|
||||
int repeatSpeed = autoRepeatSpeed;
|
||||
|
||||
|
|
|
|||
|
|
@ -495,7 +495,8 @@ private:
|
|||
void repeatTimerCallback();
|
||||
RepeatTimer& getRepeatTimer();
|
||||
|
||||
ButtonState updateState (const MouseEvent*);
|
||||
ButtonState updateState();
|
||||
ButtonState updateState (bool isOver, bool isDown);
|
||||
bool isShortcutPressed() const;
|
||||
void turnOffOtherButtonsInGroup (bool sendChangeNotification);
|
||||
|
||||
|
|
|
|||
|
|
@ -590,7 +590,7 @@ void ComboBox::mouseUp (const MouseEvent& e2)
|
|||
|
||||
const MouseEvent e (e2.getEventRelativeTo (this));
|
||||
|
||||
if (reallyContains (e.x, e.y, true)
|
||||
if (reallyContains (e.getPosition(), true)
|
||||
&& (e2.eventComponent == this || ! label->isEditable()))
|
||||
{
|
||||
showPopup();
|
||||
|
|
|
|||
|
|
@ -352,6 +352,10 @@ void Slider::lookAndFeelChanged()
|
|||
|
||||
valueBox->setTooltip (getTooltip());
|
||||
}
|
||||
else
|
||||
{
|
||||
valueBox = 0;
|
||||
}
|
||||
|
||||
if (style == IncDecButtons)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -909,7 +909,7 @@ int TableHeaderComponent::getResizeDraggerAt (const int mouseX) const
|
|||
|
||||
void TableHeaderComponent::updateColumnUnderMouse (int x, int y)
|
||||
{
|
||||
const int newCol = (reallyContains (x, y, true) && getResizeDraggerAt (x) == 0)
|
||||
const int newCol = (reallyContains (Point<int> (x, y), true) && getResizeDraggerAt (x) == 0)
|
||||
? getColumnIdAtX (x) : 0;
|
||||
|
||||
if (newCol != columnIdUnderMouse)
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@ BEGIN_JUCE_NAMESPACE
|
|||
|
||||
|
||||
//==============================================================================
|
||||
#define checkMessageManagerIsLocked jassert (MessageManager::getInstance()->currentThreadHasLockedMessageManager());
|
||||
#define CHECK_MESSAGE_MANAGER_IS_LOCKED jassert (MessageManager::getInstance()->currentThreadHasLockedMessageManager());
|
||||
|
||||
Component* Component::currentlyFocusedComponent = 0;
|
||||
|
||||
|
|
@ -249,22 +249,34 @@ public:
|
|||
|
||||
static const Point<int> convertFromParentSpace (const Component& comp, const Point<int>& pointInParentSpace)
|
||||
{
|
||||
return pointInParentSpace - comp.getPosition();
|
||||
if (comp.affineTransform_ == 0)
|
||||
return pointInParentSpace - comp.getPosition();
|
||||
|
||||
return pointInParentSpace.toFloat().transformedBy (comp.affineTransform_->inverted()).toInt() - comp.getPosition();
|
||||
}
|
||||
|
||||
static const Rectangle<int> convertFromParentSpace (const Component& comp, const Rectangle<int>& areaInParentSpace)
|
||||
{
|
||||
return areaInParentSpace - comp.getPosition();
|
||||
if (comp.affineTransform_ == 0)
|
||||
return areaInParentSpace - comp.getPosition();
|
||||
|
||||
return areaInParentSpace.toFloat().transformed (comp.affineTransform_->inverted()).getSmallestIntegerContainer() - comp.getPosition();
|
||||
}
|
||||
|
||||
static const Point<int> convertToParentSpace (const Component& comp, const Point<int>& pointInLocalSpace)
|
||||
{
|
||||
return pointInLocalSpace + comp.getPosition();
|
||||
if (comp.affineTransform_ == 0)
|
||||
return pointInLocalSpace + comp.getPosition();
|
||||
|
||||
return (pointInLocalSpace + comp.getPosition()).toFloat().transformedBy (*comp.affineTransform_).toInt();
|
||||
}
|
||||
|
||||
static const Rectangle<int> convertToParentSpace (const Component& comp, const Rectangle<int>& areaInLocalSpace)
|
||||
{
|
||||
return areaInLocalSpace + comp.getPosition();
|
||||
if (comp.affineTransform_ == 0)
|
||||
return areaInLocalSpace + comp.getPosition();
|
||||
|
||||
return (areaInLocalSpace + comp.getPosition()).toFloat().transformed (*comp.affineTransform_).getSmallestIntegerContainer();
|
||||
}
|
||||
|
||||
template <typename Type>
|
||||
|
|
@ -337,8 +349,7 @@ public:
|
|||
{
|
||||
const Component& child = *comp.childComponentList_.getUnchecked(i);
|
||||
|
||||
//xxx if (child.isVisible() && ! child.isTransformed())
|
||||
if (child.isVisible())
|
||||
if (child.isVisible() && ! child.isTransformed())
|
||||
{
|
||||
const Rectangle<int> newClip (clipRect.getIntersection (child.bounds_));
|
||||
|
||||
|
|
@ -465,7 +476,7 @@ void Component::setName (const String& name)
|
|||
{
|
||||
// if component methods are being called from threads other than the message
|
||||
// thread, you'll need to use a MessageManagerLock object to make sure it's thread-safe.
|
||||
checkMessageManagerIsLocked
|
||||
CHECK_MESSAGE_MANAGER_IS_LOCKED
|
||||
|
||||
if (componentName_ != name)
|
||||
{
|
||||
|
|
@ -491,7 +502,7 @@ void Component::setVisible (bool shouldBeVisible)
|
|||
{
|
||||
// if component methods are being called from threads other than the message
|
||||
// thread, you'll need to use a MessageManagerLock object to make sure it's thread-safe.
|
||||
checkMessageManagerIsLocked
|
||||
CHECK_MESSAGE_MANAGER_IS_LOCKED
|
||||
|
||||
SafePointer<Component> safePointer (this);
|
||||
|
||||
|
|
@ -582,7 +593,7 @@ void Component::addToDesktop (int styleWanted, void* nativeWindowToAttachTo)
|
|||
{
|
||||
// if component methods are being called from threads other than the message
|
||||
// thread, you'll need to use a MessageManagerLock object to make sure it's thread-safe.
|
||||
checkMessageManagerIsLocked
|
||||
CHECK_MESSAGE_MANAGER_IS_LOCKED
|
||||
|
||||
if (isOpaque())
|
||||
styleWanted &= ~ComponentPeer::windowIsSemiTransparent;
|
||||
|
|
@ -670,7 +681,7 @@ void Component::removeFromDesktop()
|
|||
{
|
||||
// if component methods are being called from threads other than the message
|
||||
// thread, you'll need to use a MessageManagerLock object to make sure it's thread-safe.
|
||||
checkMessageManagerIsLocked
|
||||
CHECK_MESSAGE_MANAGER_IS_LOCKED
|
||||
|
||||
if (flags.hasHeavyweightPeerFlag)
|
||||
{
|
||||
|
|
@ -748,7 +759,7 @@ void Component::toFront (const bool setAsForeground)
|
|||
{
|
||||
// if component methods are being called from threads other than the message
|
||||
// thread, you'll need to use a MessageManagerLock object to make sure it's thread-safe.
|
||||
checkMessageManagerIsLocked
|
||||
CHECK_MESSAGE_MANAGER_IS_LOCKED
|
||||
|
||||
if (flags.hasHeavyweightPeerFlag)
|
||||
{
|
||||
|
|
@ -990,7 +1001,7 @@ void Component::setBounds (const int x, const int y, int w, int h)
|
|||
{
|
||||
// if component methods are being called from threads other than the message
|
||||
// thread, you'll need to use a MessageManagerLock object to make sure it's thread-safe.
|
||||
checkMessageManagerIsLocked
|
||||
CHECK_MESSAGE_MANAGER_IS_LOCKED
|
||||
|
||||
if (w < 0) w = 0;
|
||||
if (h < 0) h = 0;
|
||||
|
|
@ -1178,6 +1189,42 @@ void Component::setBoundsToFit (int x, int y, int width, int height,
|
|||
}
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
bool Component::isTransformed() const throw()
|
||||
{
|
||||
return affineTransform_ != 0;
|
||||
}
|
||||
|
||||
void Component::setTransform (const AffineTransform& newTransform)
|
||||
{
|
||||
if (newTransform.isIdentity())
|
||||
{
|
||||
if (affineTransform_ != 0)
|
||||
{
|
||||
repaint();
|
||||
affineTransform_ = 0;
|
||||
repaint();
|
||||
}
|
||||
}
|
||||
else if (affineTransform_ == 0)
|
||||
{
|
||||
repaint();
|
||||
affineTransform_ = new AffineTransform (newTransform);
|
||||
repaint();
|
||||
}
|
||||
else if (*affineTransform_ != newTransform)
|
||||
{
|
||||
repaint();
|
||||
*affineTransform_ = newTransform;
|
||||
repaint();
|
||||
}
|
||||
}
|
||||
|
||||
const AffineTransform Component::getTransform() const
|
||||
{
|
||||
return affineTransform_ != 0 ? *affineTransform_ : AffineTransform::identity;
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
bool Component::hitTest (int x, int y)
|
||||
{
|
||||
|
|
@ -1233,15 +1280,13 @@ bool Component::contains (const Point<int>& point)
|
|||
return false;
|
||||
}
|
||||
|
||||
bool Component::reallyContains (const int x, const int y, const bool returnTrueIfWithinAChild)
|
||||
bool Component::reallyContains (const Point<int>& point, const bool returnTrueIfWithinAChild)
|
||||
{
|
||||
const Point<int> p (x, y);
|
||||
|
||||
if (! contains (p))
|
||||
if (! contains (point))
|
||||
return false;
|
||||
|
||||
Component* const top = getTopLevelComponent();
|
||||
const Component* const compAtPosition = top->getComponentAt (top->getLocalPoint (this, p));
|
||||
const Component* const compAtPosition = top->getComponentAt (top->getLocalPoint (this, point));
|
||||
|
||||
return (compAtPosition == this) || (returnTrueIfWithinAChild && isParentOf (compAtPosition));
|
||||
}
|
||||
|
|
@ -1275,7 +1320,7 @@ void Component::addChildComponent (Component* const child, int zOrder)
|
|||
{
|
||||
// if component methods are being called from threads other than the message
|
||||
// thread, you'll need to use a MessageManagerLock object to make sure it's thread-safe.
|
||||
checkMessageManagerIsLocked
|
||||
CHECK_MESSAGE_MANAGER_IS_LOCKED
|
||||
|
||||
if (child != 0 && child->parentComponent_ != this)
|
||||
{
|
||||
|
|
@ -1328,7 +1373,7 @@ Component* Component::removeChildComponent (const int index)
|
|||
{
|
||||
// if component methods are being called from threads other than the message
|
||||
// thread, you'll need to use a MessageManagerLock object to make sure it's thread-safe.
|
||||
checkMessageManagerIsLocked
|
||||
CHECK_MESSAGE_MANAGER_IS_LOCKED
|
||||
|
||||
Component* const child = childComponentList_ [index];
|
||||
|
||||
|
|
@ -1500,7 +1545,7 @@ void Component::enterModalState (const bool takeKeyboardFocus_, ModalComponentMa
|
|||
{
|
||||
// if component methods are being called from threads other than the message
|
||||
// thread, you'll need to use a MessageManagerLock object to make sure it's thread-safe.
|
||||
checkMessageManagerIsLocked
|
||||
CHECK_MESSAGE_MANAGER_IS_LOCKED
|
||||
|
||||
// Check for an attempt to make a component modal when it already is!
|
||||
// This can cause nasty problems..
|
||||
|
|
@ -1674,7 +1719,7 @@ void Component::internalRepaint (int x, int y, int w, int h)
|
|||
{
|
||||
// if component methods are being called from threads other than the message
|
||||
// thread, you'll need to use a MessageManagerLock object to make sure it's thread-safe.
|
||||
checkMessageManagerIsLocked
|
||||
CHECK_MESSAGE_MANAGER_IS_LOCKED
|
||||
|
||||
if (x < 0)
|
||||
{
|
||||
|
|
@ -1701,7 +1746,17 @@ void Component::internalRepaint (int x, int y, int w, int h)
|
|||
if (parentComponent_ != 0)
|
||||
{
|
||||
if (parentComponent_->flags.visibleFlag)
|
||||
parentComponent_->internalRepaint (x + getX(), y + getY(), w, h);
|
||||
{
|
||||
if (affineTransform_ == 0)
|
||||
{
|
||||
parentComponent_->internalRepaint (x + getX(), y + getY(), w, h);
|
||||
}
|
||||
else
|
||||
{
|
||||
const Rectangle<int> r (ComponentHelpers::convertToParentSpace (*this, Rectangle<int> (x, y, w, h)));
|
||||
parentComponent_->internalRepaint (r.getX(), r.getY(), r.getWidth(), r.getHeight());
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (flags.hasHeavyweightPeerFlag)
|
||||
{
|
||||
|
|
@ -1737,6 +1792,15 @@ void Component::paintComponent (Graphics& g)
|
|||
}
|
||||
}
|
||||
|
||||
void Component::paintTransformedChild (Graphics& g)
|
||||
{
|
||||
if (affineTransform_ != 0)
|
||||
g.addTransform (*affineTransform_);
|
||||
|
||||
g.setOrigin (getX(), getY());
|
||||
paintEntireComponent (g, false);
|
||||
}
|
||||
|
||||
void Component::paintComponentAndChildren (Graphics& g)
|
||||
{
|
||||
const Rectangle<int> clipBounds (g.getClipBounds());
|
||||
|
|
@ -1766,8 +1830,7 @@ void Component::paintComponentAndChildren (Graphics& g)
|
|||
|
||||
if (child->flags.dontClipGraphicsFlag)
|
||||
{
|
||||
g.setOrigin (child->getX(), child->getY());
|
||||
child->paintEntireComponent (g, false);
|
||||
child->paintTransformedChild (g);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -1787,10 +1850,7 @@ void Component::paintComponentAndChildren (Graphics& g)
|
|||
}
|
||||
|
||||
if (nothingClipped || ! g.isClipEmpty())
|
||||
{
|
||||
g.setOrigin (child->getX(), child->getY());
|
||||
child->paintEntireComponent (g, false);
|
||||
}
|
||||
child->paintTransformedChild (g);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -2161,7 +2221,7 @@ void Component::addMouseListener (MouseListener* const newListener,
|
|||
{
|
||||
// if component methods are being called from threads other than the message
|
||||
// thread, you'll need to use a MessageManagerLock object to make sure it's thread-safe.
|
||||
checkMessageManagerIsLocked
|
||||
CHECK_MESSAGE_MANAGER_IS_LOCKED
|
||||
|
||||
// If you register a component as a mouselistener for itself, it'll receive all the events
|
||||
// twice - once via the direct callback that all components get anyway, and then again as a listener!
|
||||
|
|
@ -2177,7 +2237,7 @@ void Component::removeMouseListener (MouseListener* const listenerToRemove)
|
|||
{
|
||||
// if component methods are being called from threads other than the message
|
||||
// thread, you'll need to use a MessageManagerLock object to make sure it's thread-safe.
|
||||
checkMessageManagerIsLocked
|
||||
CHECK_MESSAGE_MANAGER_IS_LOCKED
|
||||
|
||||
if (mouseListeners_ != 0)
|
||||
mouseListeners_->removeListener (listenerToRemove);
|
||||
|
|
@ -2437,7 +2497,7 @@ void Component::internalMouseDrag (MouseInputSource& source, const Point<int>& r
|
|||
{
|
||||
Desktop& desktop = Desktop::getInstance();
|
||||
|
||||
flags.mouseOverFlag = reallyContains (relativePos.getX(), relativePos.getY(), false);
|
||||
flags.mouseOverFlag = reallyContains (relativePos, false);
|
||||
|
||||
BailOutChecker checker (this);
|
||||
|
||||
|
|
@ -2807,7 +2867,7 @@ void Component::grabKeyboardFocus()
|
|||
{
|
||||
// if component methods are being called from threads other than the message
|
||||
// thread, you'll need to use a MessageManagerLock object to make sure it's thread-safe.
|
||||
checkMessageManagerIsLocked
|
||||
CHECK_MESSAGE_MANAGER_IS_LOCKED
|
||||
|
||||
grabFocusInternal (focusChangedDirectly);
|
||||
}
|
||||
|
|
@ -2816,7 +2876,7 @@ void Component::moveKeyboardFocusToSibling (const bool moveToNext)
|
|||
{
|
||||
// if component methods are being called from threads other than the message
|
||||
// thread, you'll need to use a MessageManagerLock object to make sure it's thread-safe.
|
||||
checkMessageManagerIsLocked
|
||||
CHECK_MESSAGE_MANAGER_IS_LOCKED
|
||||
|
||||
if (parentComponent_ != 0)
|
||||
{
|
||||
|
|
@ -2872,20 +2932,9 @@ void Component::giveAwayFocus()
|
|||
}
|
||||
|
||||
//==============================================================================
|
||||
bool Component::isMouseOver() const throw()
|
||||
{
|
||||
return flags.mouseOverFlag;
|
||||
}
|
||||
|
||||
bool Component::isMouseButtonDown() const throw()
|
||||
{
|
||||
return flags.mouseDownFlag;
|
||||
}
|
||||
|
||||
bool Component::isMouseOverOrDragging() const throw()
|
||||
{
|
||||
return flags.mouseOverFlag || flags.mouseDownFlag;
|
||||
}
|
||||
bool Component::isMouseOver() const throw() { return flags.mouseOverFlag; }
|
||||
bool Component::isMouseButtonDown() const throw() { return flags.mouseDownFlag; }
|
||||
bool Component::isMouseOverOrDragging() const throw() { return flags.mouseOverFlag || flags.mouseDownFlag; }
|
||||
|
||||
bool JUCE_CALLTYPE Component::isMouseButtonDownAnywhere() throw()
|
||||
{
|
||||
|
|
@ -2900,8 +2949,7 @@ const Point<int> Component::getMouseXYRelative() const
|
|||
//==============================================================================
|
||||
const Rectangle<int> Component::getParentMonitorArea() const
|
||||
{
|
||||
return Desktop::getInstance()
|
||||
.getMonitorAreaContaining (localPointToGlobal (getLocalBounds().getCentre()));
|
||||
return Desktop::getInstance().getMonitorAreaContaining (getScreenBounds().getCentre());
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
|
|
|
|||
|
|
@ -258,15 +258,21 @@ public:
|
|||
bool isAlwaysOnTop() const throw();
|
||||
|
||||
//==============================================================================
|
||||
/** Returns the x co-ordinate of the component's left edge.
|
||||
/** Returns the x coordinate of the component's left edge.
|
||||
This is a distance in pixels from the left edge of the component's parent.
|
||||
@see getScreenX
|
||||
|
||||
Note that if you've used setTransform() to apply a transform, then the component's
|
||||
bounds will no longer be a direct reflection of the position at which it appears within
|
||||
its parent, as the transform will be applied to its bounding box.
|
||||
*/
|
||||
inline int getX() const throw() { return bounds_.getX(); }
|
||||
|
||||
/** Returns the y co-ordinate of the top of this component.
|
||||
/** Returns the y coordinate of the top of this component.
|
||||
This is a distance in pixels from the top edge of the component's parent.
|
||||
@see getScreenY
|
||||
|
||||
Note that if you've used setTransform() to apply a transform, then the component's
|
||||
bounds will no longer be a direct reflection of the position at which it appears within
|
||||
its parent, as the transform will be applied to its bounding box.
|
||||
*/
|
||||
inline int getY() const throw() { return bounds_.getY(); }
|
||||
|
||||
|
|
@ -276,26 +282,38 @@ public:
|
|||
/** Returns the component's height in pixels. */
|
||||
inline int getHeight() const throw() { return bounds_.getHeight(); }
|
||||
|
||||
/** Returns the x co-ordinate of the component's right-hand edge.
|
||||
/** Returns the x coordinate of the component's right-hand edge.
|
||||
This is a distance in pixels from the left edge of the component's parent.
|
||||
|
||||
Note that if you've used setTransform() to apply a transform, then the component's
|
||||
bounds will no longer be a direct reflection of the position at which it appears within
|
||||
its parent, as the transform will be applied to its bounding box.
|
||||
*/
|
||||
int getRight() const throw() { return bounds_.getRight(); }
|
||||
|
||||
/** Returns the component's top-left position as a Point. */
|
||||
const Point<int> getPosition() const throw() { return bounds_.getPosition(); }
|
||||
|
||||
/** Returns the y co-ordinate of the bottom edge of this component.
|
||||
/** Returns the y coordinate of the bottom edge of this component.
|
||||
This is a distance in pixels from the top edge of the component's parent.
|
||||
|
||||
Note that if you've used setTransform() to apply a transform, then the component's
|
||||
bounds will no longer be a direct reflection of the position at which it appears within
|
||||
its parent, as the transform will be applied to its bounding box.
|
||||
*/
|
||||
int getBottom() const throw() { return bounds_.getBottom(); }
|
||||
|
||||
/** Returns this component's bounding box.
|
||||
The rectangle returned is relative to the top-left of the component's parent.
|
||||
|
||||
Note that if you've used setTransform() to apply a transform, then the component's
|
||||
bounds will no longer be a direct reflection of the position at which it appears within
|
||||
its parent, as the transform will be applied to its bounding box.
|
||||
*/
|
||||
const Rectangle<int>& getBounds() const throw() { return bounds_; }
|
||||
|
||||
/** Returns the component's bounds, relative to its own origin.
|
||||
This is like getBounds(), but returns the rectangle in local co-ordinates, In practice, it'll
|
||||
This is like getBounds(), but returns the rectangle in local coordinates, In practice, it'll
|
||||
return a rectangle with position (0, 0), and the same size as this component.
|
||||
*/
|
||||
const Rectangle<int> getLocalBounds() const throw();
|
||||
|
|
@ -312,12 +330,12 @@ public:
|
|||
bool includeSiblings) const;
|
||||
|
||||
//==============================================================================
|
||||
/** Returns this component's x co-ordinate relative the the screen's top-left origin.
|
||||
/** Returns this component's x coordinate relative the the screen's top-left origin.
|
||||
@see getX, localPointToGlobal
|
||||
*/
|
||||
int getScreenX() const;
|
||||
|
||||
/** Returns this component's y co-ordinate relative the the screen's top-left origin.
|
||||
/** Returns this component's y coordinate relative the the screen's top-left origin.
|
||||
@see getY, localPointToGlobal
|
||||
*/
|
||||
int getScreenY() const;
|
||||
|
|
@ -346,6 +364,10 @@ public:
|
|||
This takes a rectangle that is relative to a different component, and returns its position relative
|
||||
to this component. If the sourceComponent parameter is null, the source rectangle is assumed to be
|
||||
a screen coordinate.
|
||||
|
||||
If you've used setTransform() to apply one or more transforms to components, then the source rectangle
|
||||
may not actually be rectanglular when converted to the target space, so in that situation this will return
|
||||
the smallest rectangle that fully contains the transformed area.
|
||||
*/
|
||||
const Rectangle<int> getLocalArea (const Component* sourceComponent,
|
||||
const Rectangle<int>& areaRelativeToSourceComponent) const;
|
||||
|
|
@ -356,6 +378,10 @@ public:
|
|||
const Point<int> localPointToGlobal (const Point<int>& localPoint) const;
|
||||
|
||||
/** Converts a rectangle from this component's coordinate space to a screen coordinate.
|
||||
|
||||
If you've used setTransform() to apply one or more transforms to components, then the source rectangle
|
||||
may not actually be rectanglular when converted to the target space, so in that situation this will return
|
||||
the smallest rectangle that fully contains the transformed area.
|
||||
@see getLocalPoint, localPointToGlobal
|
||||
*/
|
||||
const Rectangle<int> localAreaToGlobal (const Rectangle<int>& localArea) const;
|
||||
|
|
@ -368,6 +394,10 @@ public:
|
|||
|
||||
If the component actually moves, this method will make a synchronous call to moved().
|
||||
|
||||
Note that if you've used setTransform() to apply a transform, then the component's
|
||||
bounds will no longer be a direct reflection of the position at which it appears within
|
||||
its parent, as the transform will be applied to whatever bounds you set for it.
|
||||
|
||||
@see setBounds, ComponentListener::componentMovedOrResized
|
||||
*/
|
||||
void setTopLeftPosition (int x, int y);
|
||||
|
|
@ -378,29 +408,51 @@ public:
|
|||
The position is relative to the top-left of the component's parent.
|
||||
|
||||
If the component actually moves, this method will make a synchronous call to moved().
|
||||
|
||||
Note that if you've used setTransform() to apply a transform, then the component's
|
||||
bounds will no longer be a direct reflection of the position at which it appears within
|
||||
its parent, as the transform will be applied to whatever bounds you set for it.
|
||||
*/
|
||||
void setTopRightPosition (int x, int y);
|
||||
|
||||
/** Changes the size of the component.
|
||||
|
||||
A synchronous call to resized() will be occur if the size actually changes.
|
||||
|
||||
Note that if you've used setTransform() to apply a transform, then the component's
|
||||
bounds will no longer be a direct reflection of the position at which it appears within
|
||||
its parent, as the transform will be applied to whatever bounds you set for it.
|
||||
*/
|
||||
void setSize (int newWidth, int newHeight);
|
||||
|
||||
/** Changes the component's position and size.
|
||||
|
||||
The co-ordinates are relative to the top-left of the component's parent, or relative
|
||||
The coordinates are relative to the top-left of the component's parent, or relative
|
||||
to the origin of the screen is the component is on the desktop.
|
||||
|
||||
If this method changes the component's top-left position, it will make a synchronous
|
||||
call to moved(). If it changes the size, it will also make a call to resized().
|
||||
|
||||
Note that if you've used setTransform() to apply a transform, then the component's
|
||||
bounds will no longer be a direct reflection of the position at which it appears within
|
||||
its parent, as the transform will be applied to whatever bounds you set for it.
|
||||
|
||||
@see setTopLeftPosition, setSize, ComponentListener::componentMovedOrResized
|
||||
*/
|
||||
void setBounds (int x, int y, int width, int height);
|
||||
|
||||
/** Changes the component's position and size.
|
||||
|
||||
The coordinates are relative to the top-left of the component's parent, or relative
|
||||
to the origin of the screen is the component is on the desktop.
|
||||
|
||||
If this method changes the component's top-left position, it will make a synchronous
|
||||
call to moved(). If it changes the size, it will also make a call to resized().
|
||||
|
||||
Note that if you've used setTransform() to apply a transform, then the component's
|
||||
bounds will no longer be a direct reflection of the position at which it appears within
|
||||
its parent, as the transform will be applied to whatever bounds you set for it.
|
||||
|
||||
@see setBounds
|
||||
*/
|
||||
void setBounds (const Rectangle<int>& newBounds);
|
||||
|
|
@ -411,6 +463,8 @@ public:
|
|||
setBoundsRelative (0.2f, 0.2f, 0.5f, 0.5f) would give it half the
|
||||
width and height of the parent, with its top-left position 20% of
|
||||
the way across and down the parent.
|
||||
|
||||
@see setBounds
|
||||
*/
|
||||
void setBoundsRelative (float proportionalX, float proportionalY,
|
||||
float proportionalWidth, float proportionalHeight);
|
||||
|
|
@ -419,6 +473,8 @@ public:
|
|||
|
||||
This will position the component within its parent, leaving the specified number of
|
||||
pixels around each edge.
|
||||
|
||||
@see setBounds
|
||||
*/
|
||||
void setBoundsInset (const BorderSize& borders);
|
||||
|
||||
|
|
@ -433,6 +489,8 @@ public:
|
|||
|
||||
It will then be positioned within the rectangle according to the justification flags
|
||||
specified.
|
||||
|
||||
@see setBounds
|
||||
*/
|
||||
void setBoundsToFit (int x, int y, int width, int height,
|
||||
const Justification& justification,
|
||||
|
|
@ -442,6 +500,8 @@ public:
|
|||
|
||||
Leaves the component's size unchanged, but sets the position of its centre
|
||||
relative to its parent's top-left.
|
||||
|
||||
@see setBounds
|
||||
*/
|
||||
void setCentrePosition (int x, int y);
|
||||
|
||||
|
|
@ -461,6 +521,38 @@ public:
|
|||
*/
|
||||
void centreWithSize (int width, int height);
|
||||
|
||||
//==============================================================================
|
||||
/** Sets a transform matrix to be applied to this component.
|
||||
|
||||
If you set a transform for a component, the component's position will be warped by it, relative to
|
||||
the component's parent's top-left origin. This means that the values you pass into setBounds() will no
|
||||
longer reflect the actual area within the parent that the component covers, as the bounds will be
|
||||
transformed and the component will probably end up actually appearing somewhere else within its parent.
|
||||
|
||||
When using transforms you need to be extremely careful when converting coordinates between the
|
||||
coordinate spaces of different components or the screen - you should always use getLocalPoint(),
|
||||
getLocalArea(), etc to do this, and never just manually add a component's position to a point in order to
|
||||
convert it between different components (but I'm sure you would never have done that anyway...).
|
||||
|
||||
Currently, transforms are not supported for desktop windows, so the transform will be ignored if you
|
||||
put a component on the desktop.
|
||||
|
||||
To remove a component's transform, simply pass AffineTransform::identity as the parameter to this method.
|
||||
*/
|
||||
void setTransform (const AffineTransform& transform);
|
||||
|
||||
/** Returns the transform that is currently being applied to this component.
|
||||
For more details about transforms, see setTransform().
|
||||
@see setTransform
|
||||
*/
|
||||
const AffineTransform getTransform() const;
|
||||
|
||||
/** Returns true if a non-identity transform is being applied to this component.
|
||||
For more details about transforms, see setTransform().
|
||||
@see setTransform
|
||||
*/
|
||||
bool isTransformed() const throw();
|
||||
|
||||
//==============================================================================
|
||||
/** Returns a proportion of the component's width.
|
||||
|
||||
|
|
@ -488,7 +580,7 @@ public:
|
|||
*/
|
||||
int getParentHeight() const throw();
|
||||
|
||||
/** Returns the screen co-ordinates of the monitor that contains this component.
|
||||
/** Returns the screen coordinates of the monitor that contains this component.
|
||||
|
||||
If there's only one monitor, this will return its size - if there are multiple
|
||||
monitors, it will return the area of the monitor that contains the component's
|
||||
|
|
@ -660,7 +752,7 @@ public:
|
|||
Overriding this method allows you to create components which only intercept
|
||||
mouse-clicks within a user-defined area.
|
||||
|
||||
This is called to find out whether a particular x, y co-ordinate is
|
||||
This is called to find out whether a particular x, y coordinate is
|
||||
considered to be inside the component or not, and is used by methods such
|
||||
as contains() and getComponentAt() to work out which component
|
||||
the mouse is clicked on.
|
||||
|
|
@ -682,10 +774,10 @@ public:
|
|||
Note that for components on the desktop, this method will be ignored, because it's
|
||||
not always possible to implement this behaviour on all platforms.
|
||||
|
||||
@param x the x co-ordinate to test, relative to the left hand edge of this
|
||||
@param x the x coordinate to test, relative to the left hand edge of this
|
||||
component. This value is guaranteed to be greater than or equal to
|
||||
zero, and less than the component's width
|
||||
@param y the y co-ordinate to test, relative to the top edge of this
|
||||
@param y the y coordinate to test, relative to the top edge of this
|
||||
component. This value is guaranteed to be greater than or equal to
|
||||
zero, and less than the component's height
|
||||
@returns true if the click is considered to be inside the component
|
||||
|
|
@ -728,32 +820,29 @@ public:
|
|||
|
||||
Never override this method! Use hitTest to create custom hit regions.
|
||||
|
||||
@param point the x co-ordinate to test, relative to this component's top-left.
|
||||
@param localPoint the coordinate to test, relative to this component's top-left.
|
||||
@returns true if the point is within the component's hit-test area, but only if
|
||||
that part of the component isn't clipped by its parent component. Note
|
||||
that this won't take into account any overlapping sibling components
|
||||
which might be in the way - for that, see reallyContains()
|
||||
@see hitTest, reallyContains, getComponentAt
|
||||
*/
|
||||
bool contains (const Point<int>& point);
|
||||
bool contains (const Point<int>& localPoint);
|
||||
|
||||
/** Returns true if a given point lies in this component, taking any overlapping
|
||||
siblings into account.
|
||||
|
||||
@param x the x co-ordinate to test, relative to this component's left hand edge.
|
||||
@param y the y co-ordinate to test, relative to this component's top edge.
|
||||
@param returnTrueIfWithinAChild if the point actually lies within a child of this
|
||||
component, this determines the value that will
|
||||
be returned.
|
||||
|
||||
@param localPoint the coordinate to test, relative to this component's top-left.
|
||||
@param returnTrueIfWithinAChild if the point actually lies within a child of this component,
|
||||
this determines whether that is counted as a hit.
|
||||
@see contains, getComponentAt
|
||||
*/
|
||||
bool reallyContains (int x, int y, bool returnTrueIfWithinAChild);
|
||||
bool reallyContains (const Point<int>& localPoint, bool returnTrueIfWithinAChild);
|
||||
|
||||
/** Returns the component at a certain point within this one.
|
||||
|
||||
@param x the x co-ordinate to test, relative to this component's left hand edge.
|
||||
@param y the y co-ordinate to test, relative to this component's top edge.
|
||||
@param x the x coordinate to test, relative to this component's left edge.
|
||||
@param y the y coordinate to test, relative to this component's top edge.
|
||||
@returns the component that is at this position - which may be 0, this component,
|
||||
or one of its children. Note that overlapping siblings that might actually
|
||||
be in the way are not taken into account by this method - to account for these,
|
||||
|
|
@ -764,7 +853,7 @@ public:
|
|||
|
||||
/** Returns the component at a certain point within this one.
|
||||
|
||||
@param position the co-ordinates to test, relative to this component's top-left.
|
||||
@param position the coordinate to test, relative to this component's top-left.
|
||||
@returns the component that is at this position - which may be 0, this component,
|
||||
or one of its children. Note that overlapping siblings that might actually
|
||||
be in the way are not taken into account by this method - to account for these,
|
||||
|
|
@ -1613,8 +1702,7 @@ public:
|
|||
static bool JUCE_CALLTYPE isMouseButtonDownAnywhere() throw();
|
||||
|
||||
/** Returns the mouse's current position, relative to this component.
|
||||
|
||||
The co-ordinates are relative to the component's top-left corner.
|
||||
The return value is relative to the component's top-left corner.
|
||||
*/
|
||||
const Point<int> getMouseXYRelative() const;
|
||||
|
||||
|
|
@ -2033,6 +2121,7 @@ private:
|
|||
String componentName_;
|
||||
Component* parentComponent_;
|
||||
Rectangle<int> bounds_;
|
||||
ScopedPointer <AffineTransform> affineTransform_;
|
||||
Array <Component*> childComponentList_;
|
||||
LookAndFeel* lookAndFeel_;
|
||||
MouseCursor cursor_;
|
||||
|
|
@ -2099,6 +2188,7 @@ private:
|
|||
void internalHierarchyChanged();
|
||||
void paintComponentAndChildren (Graphics& g);
|
||||
void paintComponent (Graphics& g);
|
||||
void paintTransformedChild (Graphics& g);
|
||||
void sendMovedResizedMessages (bool wasMoved, bool wasResized);
|
||||
void repaintParent();
|
||||
void sendFakeMouseMove() const;
|
||||
|
|
|
|||
|
|
@ -127,7 +127,7 @@ int MenuBarComponent::getItemAt (const int x, const int y)
|
|||
{
|
||||
for (int i = 0; i < xPositions.size(); ++i)
|
||||
if (x >= xPositions[i] && x < xPositions[i + 1])
|
||||
return reallyContains (x, y, true) ? i : -1;
|
||||
return reallyContains (Point<int> (x, y), true) ? i : -1;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -522,7 +522,7 @@ public:
|
|||
// comp that we're attached to.
|
||||
const Point<int> mousePos (componentAttachedTo->getMouseXYRelative());
|
||||
|
||||
if (componentAttachedTo->reallyContains (mousePos.getX(), mousePos.getY(), true))
|
||||
if (componentAttachedTo->reallyContains (mousePos, true))
|
||||
{
|
||||
postCommandMessage (PopupMenuSettings::dismissCommandId); // dismiss asynchrounously
|
||||
return;
|
||||
|
|
@ -567,7 +567,7 @@ public:
|
|||
const uint32 now = Time::getMillisecondCounter();
|
||||
|
||||
if (now > timeEnteredCurrentChildComp + 100
|
||||
&& reallyContains (localMousePos.getX(), localMousePos.getY(), true)
|
||||
&& reallyContains (localMousePos, true)
|
||||
&& currentChild != 0
|
||||
&& (! disableMouseMoves)
|
||||
&& ! (activeSubMenu != 0 && activeSubMenu->isVisible()))
|
||||
|
|
@ -659,7 +659,7 @@ public:
|
|||
else if (wasDown && now > menuCreationTime + 250
|
||||
&& ! (isDown || overScrollArea))
|
||||
{
|
||||
isOver = reallyContains (localMousePos.getX(), localMousePos.getY(), true);
|
||||
isOver = reallyContains (localMousePos, true);
|
||||
|
||||
if (isOver)
|
||||
{
|
||||
|
|
@ -734,7 +734,7 @@ private:
|
|||
void updateMouseOverStatus (const Point<int>& globalMousePos)
|
||||
{
|
||||
const Point<int> relPos (getLocalPoint (0, globalMousePos));
|
||||
isOver = reallyContains (relPos.getX(), relPos.getY(), true);
|
||||
isOver = reallyContains (relPos, true);
|
||||
|
||||
if (activeSubMenu != 0)
|
||||
activeSubMenu->updateMouseOverStatus (globalMousePos);
|
||||
|
|
@ -1081,7 +1081,7 @@ private:
|
|||
|
||||
void highlightItemUnderMouse (const Point<int>& globalMousePos, const Point<int>& localMousePos)
|
||||
{
|
||||
isOver = reallyContains (localMousePos.getX(), localMousePos.getY(), true);
|
||||
isOver = reallyContains (localMousePos, true);
|
||||
|
||||
if (isOver)
|
||||
hasBeenOver = true;
|
||||
|
|
|
|||
|
|
@ -76,7 +76,7 @@ void MouseHoverDetector::hoverTimerCallback()
|
|||
{
|
||||
const Point<int> pos (source->getMouseXYRelative());
|
||||
|
||||
if (source->reallyContains (pos.getX(), pos.getY(), false))
|
||||
if (source->reallyContains (pos, false))
|
||||
{
|
||||
hasJustHovered = true;
|
||||
mouseHovered (pos.getX(), pos.getY());
|
||||
|
|
|
|||
|
|
@ -244,7 +244,7 @@ const uint8 MidiKeyboardComponent::blackNotes[] = { 1, 3, 6, 8, 10 };
|
|||
|
||||
int MidiKeyboardComponent::xyToNote (const Point<int>& pos, float& mousePositionVelocity)
|
||||
{
|
||||
if (! reallyContains (pos.getX(), pos.getY(), false))
|
||||
if (! reallyContains (pos, false))
|
||||
return -1;
|
||||
|
||||
Point<int> p (pos);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue