261 lines
7.1 KiB
C++
261 lines
7.1 KiB
C++
// This file is part of VSTGUI. It is subject to the license terms
|
|
// in the LICENSE file found in the top-level directory of this
|
|
// distribution and at http://github.com/steinbergmedia/vstgui/LICENSE
|
|
|
|
#include "clayeredviewcontainer.h"
|
|
#include "cframe.h"
|
|
#include "cdrawcontext.h"
|
|
#include "coffscreencontext.h"
|
|
#include "platform/iplatformframe.h"
|
|
|
|
namespace VSTGUI {
|
|
|
|
//-----------------------------------------------------------------------------
|
|
CLayeredViewContainer::CLayeredViewContainer (const CRect& r)
|
|
: CViewContainer (r)
|
|
{
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
void CLayeredViewContainer::setZIndex (uint32_t _zIndex)
|
|
{
|
|
if (_zIndex != zIndex)
|
|
{
|
|
zIndex = _zIndex;
|
|
if (layer)
|
|
layer->setZIndex (zIndex);
|
|
}
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
void CLayeredViewContainer::updateLayerSize ()
|
|
{
|
|
if (!layer)
|
|
return;
|
|
|
|
CRect newSize = getViewSize ();
|
|
getTransform ().transform (newSize);
|
|
auto frame = getFrame ();
|
|
|
|
auto* parent = static_cast<CViewContainer*> (getParentView ());
|
|
while (parent && parent != frame)
|
|
{
|
|
CRect parentSize = parent->getViewSize ();
|
|
parent->getTransform ().transform (newSize);
|
|
newSize.offset (parentSize.left, parentSize.top);
|
|
newSize.bound (parentSize);
|
|
parent = static_cast<CViewContainer*> (parent->getParentView ());
|
|
}
|
|
|
|
frame->getTransform ().transform (newSize);
|
|
|
|
if (parentLayerView)
|
|
{
|
|
CPoint p (parentLayerView->getVisibleViewSize ().getTopLeft ());
|
|
parentLayerView->translateToGlobal (p);
|
|
newSize.offsetInverse (p);
|
|
}
|
|
if (layer)
|
|
layer->setSize (newSize);
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
bool CLayeredViewContainer::removed (CView* parent)
|
|
{
|
|
if (!isAttached ())
|
|
return false;
|
|
registerListeners (false);
|
|
if (layer)
|
|
{
|
|
layer = nullptr;
|
|
parentLayerView = nullptr;
|
|
getFrame ()->unregisterScaleFactorChangedListener (this);
|
|
}
|
|
return CViewContainer::removed (parent);
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
bool CLayeredViewContainer::attached (CView* parent)
|
|
{
|
|
if (isAttached ())
|
|
return false;
|
|
|
|
setParentView (parent);
|
|
setParentFrame (parent->getFrame ());
|
|
if (auto frame = getFrame ())
|
|
{
|
|
while (parent && dynamic_cast<CFrame*>(parent) == nullptr)
|
|
{
|
|
parentLayerView = dynamic_cast<CLayeredViewContainer*>(parent);
|
|
if (parentLayerView)
|
|
{
|
|
break;
|
|
}
|
|
parent = parent->getParentView ();
|
|
}
|
|
layer = frame->getPlatformFrame ()->createPlatformViewLayer (this, parentLayerView ? parentLayerView->layer : nullptr);
|
|
if (layer)
|
|
{
|
|
layer->setZIndex (zIndex);
|
|
layer->setAlpha (getAlphaValue ());
|
|
updateLayerSize ();
|
|
frame->registerScaleFactorChangedListener (this);
|
|
}
|
|
}
|
|
parent = getParentView ();
|
|
|
|
registerListeners (true);
|
|
|
|
setParentView (nullptr);
|
|
setParentFrame (nullptr);
|
|
|
|
return CViewContainer::attached (parent);
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
void CLayeredViewContainer::registerListeners (bool state)
|
|
{
|
|
auto* parent = static_cast<CViewContainer*> (getParentView ());
|
|
while (parent)
|
|
{
|
|
if (state)
|
|
parent->registerViewContainerListener (this);
|
|
else
|
|
parent->unregisterViewContainerListener (this);
|
|
parent = static_cast<CViewContainer*> (parent->getParentView ());
|
|
}
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
void CLayeredViewContainer::viewContainerTransformChanged (CViewContainer* container)
|
|
{
|
|
updateLayerSize ();
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
void CLayeredViewContainer::invalid ()
|
|
{
|
|
CRect r = getViewSize ();
|
|
r.originize ();
|
|
invalidRect (r);
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
void CLayeredViewContainer::invalidRect (const CRect& rect)
|
|
{
|
|
if (layer)
|
|
{
|
|
CRect r (rect);
|
|
getDrawTransform ().transform (r);
|
|
layer->invalidRect (r);
|
|
}
|
|
else
|
|
{
|
|
CViewContainer::invalidRect (rect);
|
|
}
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
void CLayeredViewContainer::parentSizeChanged ()
|
|
{
|
|
CViewContainer::parentSizeChanged ();
|
|
if (layer)
|
|
{
|
|
updateLayerSize ();
|
|
invalid ();
|
|
}
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
void CLayeredViewContainer::setViewSize (const CRect& rect, bool invalid)
|
|
{
|
|
CViewContainer::setViewSize (rect, invalid);
|
|
updateLayerSize ();
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
void CLayeredViewContainer::setAlphaValue (float alpha)
|
|
{
|
|
if (layer)
|
|
{
|
|
setAlphaValueNoInvalidate (alpha);
|
|
layer->setAlpha (alpha);
|
|
}
|
|
else
|
|
CViewContainer::setAlphaValue (alpha);
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
void CLayeredViewContainer::drawRect (CDrawContext* pContext, const CRect& updateRect)
|
|
{
|
|
auto drawsIntoBitmap = false;
|
|
if (auto offscreenContext = dynamic_cast<COffscreenContext*> (pContext))
|
|
drawsIntoBitmap = offscreenContext->getBitmap () != nullptr;
|
|
if (!layer || drawsIntoBitmap)
|
|
CViewContainer::drawRect (pContext, updateRect);
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
void CLayeredViewContainer::drawViewLayerRects (const PlatformGraphicsDeviceContextPtr& context,
|
|
double scaleFactor, const std::vector<CRect>& rects)
|
|
{
|
|
CGraphicsTransform drawTransform = getDrawTransform ();
|
|
|
|
CRect visibleSize = getVisibleViewSize ();
|
|
CRect viewSize = getViewSize ();
|
|
CPoint p (viewSize.left < 0 ? viewSize.left - visibleSize.left : visibleSize.left,
|
|
viewSize.top < 0 ? viewSize.top - visibleSize.top : visibleSize.top);
|
|
|
|
auto surfaceSize = getViewSize ();
|
|
surfaceSize.originize ();
|
|
CDrawContext drawContext (context, surfaceSize, scaleFactor);
|
|
CDrawContext::Transform transform (
|
|
drawContext, drawTransform * CGraphicsTransform ().translate (-p.x, -p.y));
|
|
for (auto dirtyRect : rects)
|
|
{
|
|
drawTransform.inverse ().transform (dirtyRect);
|
|
dirtyRect.offset (p.x, p.y);
|
|
drawContext.saveGlobalState ();
|
|
drawContext.setClipRect (dirtyRect);
|
|
CViewContainer::drawRect (&drawContext, dirtyRect);
|
|
drawContext.restoreGlobalState ();
|
|
}
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
CGraphicsTransform CLayeredViewContainer::getDrawTransform () const
|
|
{
|
|
using ParentViews = std::list<CViewContainer*>;
|
|
|
|
CGraphicsTransform transform;
|
|
ParentViews parents;
|
|
auto frame = getFrame ();
|
|
|
|
auto* parent = static_cast<CViewContainer*> (getParentView ());
|
|
while (parent && parent != frame)
|
|
{
|
|
parents.push_front (parent);
|
|
parent = static_cast<CViewContainer*> (parent->getParentView ());
|
|
}
|
|
for (const auto& p : parents)
|
|
transform = p->getTransform () * transform;
|
|
|
|
auto self = static_cast<const CViewContainer*> (this);
|
|
if (self)
|
|
transform = self->getTransform () * transform;
|
|
|
|
if (frame)
|
|
transform = frame->getTransform () * transform;
|
|
|
|
return transform;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
void CLayeredViewContainer::onScaleFactorChanged (CFrame* frame, double newScaleFactor)
|
|
{
|
|
if (layer)
|
|
layer->onScaleFactorChanged (newScaleFactor);
|
|
}
|
|
|
|
}
|