1
0
Fork 0
mirror of https://github.com/juce-framework/JUCE.git synced 2026-01-10 23:44:24 +00:00
JUCE/src/gui/components/special/juce_MagnifierComponent.cpp

341 lines
10 KiB
C++

/*
==============================================================================
This file is part of the JUCE library - "Jules' Utility Class Extensions"
Copyright 2004-9 by Raw Material Software Ltd.
------------------------------------------------------------------------------
JUCE can be redistributed and/or modified under the terms of the GNU General
Public License (Version 2), as published by the Free Software Foundation.
A copy of the license is included in the JUCE distribution, or can be found
online at www.gnu.org/licenses.
JUCE is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
------------------------------------------------------------------------------
To release a closed-source product which uses JUCE, commercial licenses are
available: visit www.rawmaterialsoftware.com/juce for more information.
==============================================================================
*/
#include "../../../core/juce_StandardHeader.h"
BEGIN_JUCE_NAMESPACE
#include "juce_MagnifierComponent.h"
#include "../../graphics/imaging/juce_Image.h"
//==============================================================================
class MagnifyingPeer : public ComponentPeer
{
public:
//==============================================================================
MagnifyingPeer (Component* const component_,
MagnifierComponent* const magnifierComp_)
: ComponentPeer (component_, 0),
magnifierComp (magnifierComp_)
{
}
~MagnifyingPeer()
{
}
//==============================================================================
void* getNativeHandle() const { return 0; }
void setVisible (bool) {}
void setTitle (const String&) {}
void setPosition (int, int) {}
void setSize (int, int) {}
void setBounds (int, int, int, int, const bool) {}
void setMinimised (bool) {}
bool isMinimised() const { return false; }
void setFullScreen (bool) {}
bool isFullScreen() const { return false; }
const BorderSize getFrameSize() const { return BorderSize (0); }
bool setAlwaysOnTop (bool) { return true; }
void toFront (bool) {}
void toBehind (ComponentPeer*) {}
void setIcon (const Image&) {}
bool isFocused() const
{
return magnifierComp->hasKeyboardFocus (true);
}
void grabFocus()
{
ComponentPeer* peer = magnifierComp->getPeer();
if (peer != 0)
peer->grabFocus();
}
void textInputRequired (int x, int y)
{
ComponentPeer* peer = magnifierComp->getPeer();
if (peer != 0)
peer->textInputRequired (x, y);
}
void getBounds (int& x, int& y, int& w, int& h) const
{
x = magnifierComp->getScreenX();
y = magnifierComp->getScreenY();
w = component->getWidth();
h = component->getHeight();
}
int getScreenX() const { return magnifierComp->getScreenX(); }
int getScreenY() const { return magnifierComp->getScreenY(); }
void relativePositionToGlobal (int& x, int& y)
{
const double zoom = magnifierComp->getScaleFactor();
x = roundToInt (x * zoom);
y = roundToInt (y * zoom);
magnifierComp->relativePositionToGlobal (x, y);
}
void globalPositionToRelative (int& x, int& y)
{
magnifierComp->globalPositionToRelative (x, y);
const double zoom = magnifierComp->getScaleFactor();
x = roundToInt (x / zoom);
y = roundToInt (y / zoom);
}
bool contains (int x, int y, bool) const
{
return ((unsigned int) x) < (unsigned int) magnifierComp->getWidth()
&& ((unsigned int) y) < (unsigned int) magnifierComp->getHeight();
}
void repaint (int x, int y, int w, int h)
{
const double zoom = magnifierComp->getScaleFactor();
magnifierComp->repaint ((int) (x * zoom),
(int) (y * zoom),
roundToInt (w * zoom) + 1,
roundToInt (h * zoom) + 1);
}
void performAnyPendingRepaintsNow()
{
}
//==============================================================================
juce_UseDebuggingNewOperator
private:
MagnifierComponent* const magnifierComp;
MagnifyingPeer (const MagnifyingPeer&);
const MagnifyingPeer& operator= (const MagnifyingPeer&);
};
//==============================================================================
class PeerHolderComp : public Component
{
public:
PeerHolderComp (MagnifierComponent* const magnifierComp_)
: magnifierComp (magnifierComp_)
{
setVisible (true);
}
~PeerHolderComp()
{
}
ComponentPeer* createNewPeer (int, void*)
{
return new MagnifyingPeer (this, magnifierComp);
}
void childBoundsChanged (Component* c)
{
if (c != 0)
{
setSize (c->getWidth(), c->getHeight());
magnifierComp->childBoundsChanged (this);
}
}
void mouseWheelMove (const MouseEvent& e, float ix, float iy)
{
// unhandled mouse wheel moves can be referred upwards to the parent comp..
Component* const p = magnifierComp->getParentComponent();
if (p != 0)
p->mouseWheelMove (e.getEventRelativeTo (p), ix, iy);
}
private:
MagnifierComponent* const magnifierComp;
PeerHolderComp (const PeerHolderComp&);
const PeerHolderComp& operator= (const PeerHolderComp&);
};
//==============================================================================
MagnifierComponent::MagnifierComponent (Component* const content_,
const bool deleteContentCompWhenNoLongerNeeded)
: content (content_),
scaleFactor (0.0),
peer (0),
deleteContent (deleteContentCompWhenNoLongerNeeded),
quality (Graphics::lowResamplingQuality)
{
holderComp = new PeerHolderComp (this);
setScaleFactor (1.0);
}
MagnifierComponent::~MagnifierComponent()
{
delete holderComp;
if (deleteContent)
delete content;
}
void MagnifierComponent::setScaleFactor (double newScaleFactor)
{
jassert (newScaleFactor > 0.0); // hmm - unlikely to work well with a negative scale factor
newScaleFactor = jlimit (1.0 / 8.0, 1000.0, newScaleFactor);
if (scaleFactor != newScaleFactor)
{
scaleFactor = newScaleFactor;
if (scaleFactor == 1.0)
{
holderComp->removeFromDesktop();
peer = 0;
addChildComponent (content);
childBoundsChanged (content);
}
else
{
holderComp->addAndMakeVisible (content);
holderComp->childBoundsChanged (content);
childBoundsChanged (holderComp);
holderComp->addToDesktop (0);
peer = holderComp->getPeer();
}
repaint();
}
}
void MagnifierComponent::setResamplingQuality (Graphics::ResamplingQuality newQuality)
{
quality = newQuality;
}
void MagnifierComponent::paint (Graphics& g)
{
const int w = holderComp->getWidth();
const int h = holderComp->getHeight();
if (w == 0 || h == 0)
return;
const Rectangle r (g.getClipBounds());
const int srcX = (int) (r.getX() / scaleFactor);
const int srcY = (int) (r.getY() / scaleFactor);
int srcW = roundToInt (r.getRight() / scaleFactor) - srcX;
int srcH = roundToInt (r.getBottom() / scaleFactor) - srcY;
if (scaleFactor >= 1.0)
{
++srcW;
++srcH;
}
Image temp (Image::ARGB, jmax (w, srcX + srcW), jmax (h, srcY + srcH), false);
temp.clear (srcX, srcY, srcW, srcH);
Graphics g2 (temp);
g2.reduceClipRegion (srcX, srcY, srcW, srcH);
holderComp->paintEntireComponent (g2);
g.setImageResamplingQuality (quality);
g.drawImage (&temp,
0, 0, (int) (w * scaleFactor), (int) (h * scaleFactor),
0, 0, w, h,
false);
}
void MagnifierComponent::childBoundsChanged (Component* c)
{
if (c != 0)
setSize (roundToInt (c->getWidth() * scaleFactor),
roundToInt (c->getHeight() * scaleFactor));
}
void MagnifierComponent::mouseDown (const MouseEvent& e)
{
if (peer != 0)
peer->handleMouseDown (scaleInt (e.x), scaleInt (e.y), e.eventTime.toMilliseconds());
}
void MagnifierComponent::mouseUp (const MouseEvent& e)
{
if (peer != 0)
peer->handleMouseUp (e.mods.getRawFlags(), scaleInt (e.x), scaleInt (e.y), e.eventTime.toMilliseconds());
}
void MagnifierComponent::mouseDrag (const MouseEvent& e)
{
if (peer != 0)
peer->handleMouseDrag (scaleInt (e.x), scaleInt (e.y), e.eventTime.toMilliseconds());
}
void MagnifierComponent::mouseMove (const MouseEvent& e)
{
if (peer != 0)
peer->handleMouseMove (scaleInt (e.x), scaleInt (e.y), e.eventTime.toMilliseconds());
}
void MagnifierComponent::mouseEnter (const MouseEvent& e)
{
if (peer != 0)
peer->handleMouseEnter (scaleInt (e.x), scaleInt (e.y), e.eventTime.toMilliseconds());
}
void MagnifierComponent::mouseExit (const MouseEvent& e)
{
if (peer != 0)
peer->handleMouseExit (scaleInt (e.x), scaleInt (e.y), e.eventTime.toMilliseconds());
}
void MagnifierComponent::mouseWheelMove (const MouseEvent& e, float ix, float iy)
{
if (peer != 0)
peer->handleMouseWheel (roundToInt (ix * 256.0f),
roundToInt (iy * 256.0f),
e.eventTime.toMilliseconds());
else
Component::mouseWheelMove (e, ix, iy);
}
int MagnifierComponent::scaleInt (const int n) const
{
return roundToInt (n / scaleFactor);
}
END_JUCE_NAMESPACE