Initial release

This commit is contained in:
civ
2026-08-16 18:24:52 +07:00
commit 876886a39a
13244 changed files with 2353959 additions and 0 deletions
@@ -0,0 +1,342 @@
// 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
#if VSTGUI_LIVE_EDITING
#include "uiselection.h"
#include "../iviewfactory.h"
#include "../uidescription.h"
#include "../cstream.h"
#include "../uiattributes.h"
#include "../../lib/cviewcontainer.h"
#include "../../lib/cframe.h"
#include "../../lib/ccolor.h"
#include "../../lib/coffscreencontext.h"
#include "../../lib/clayeredviewcontainer.h"
#include "../../lib/cbitmap.h"
#include <sstream>
#include <algorithm>
namespace VSTGUI {
//----------------------------------------------------------------------------------------------------
UISelection::UISelection (int32_t style)
: style (style)
{
}
//----------------------------------------------------------------------------------------------------
UISelection::~UISelection ()
{
clear ();
}
//----------------------------------------------------------------------------------------------------
auto UISelection::begin () const -> const_iterator
{
return viewList.begin ();
}
//----------------------------------------------------------------------------------------------------
auto UISelection::end () const -> const_iterator
{
return viewList.end ();
}
//----------------------------------------------------------------------------------------------------
auto UISelection::rbegin () const -> const_reverse_iterator
{
return viewList.rbegin ();
}
//----------------------------------------------------------------------------------------------------
auto UISelection::rend () const -> const_reverse_iterator
{
return viewList.rend ();
}
//----------------------------------------------------------------------------------------------------
void UISelection::setStyle (int32_t _style)
{
style = _style;
}
//----------------------------------------------------------------------------------------------------
void UISelection::add (CView* view)
{
vstgui_assert (view, "view cannot be nullptr");
willChange ();
if (style == kSingleSelectionStyle)
clear ();
viewList.emplace_back (view);
didChange ();
}
//----------------------------------------------------------------------------------------------------
void UISelection::remove (CView* view)
{
vstgui_assert (view, "view cannot be nullptr");
if (contains (view))
{
willChange ();
viewList.remove (view);
didChange ();
}
}
//----------------------------------------------------------------------------------------------------
void UISelection::setExclusive (CView* view)
{
vstgui_assert (view, "view cannot be nullptr");
if (viewList.size () == 1 && viewList.front () == view)
return;
UISelection::DeferChange dc (*this);
viewList.clear ();
add (view);
}
//----------------------------------------------------------------------------------------------------
void UISelection::clear ()
{
willChange ();
viewList.clear ();
didChange ();
}
//----------------------------------------------------------------------------------------------------
bool UISelection::contains (CView* view) const
{
return std::find (begin (), end (), view) != end ();
}
//----------------------------------------------------------------------------------------------------
bool UISelection::containsParent (CView* view) const
{
CView* parent = view->getParentView ();
if (parent)
{
if (contains (parent))
return true;
return containsParent (parent);
}
return false;
}
//----------------------------------------------------------------------------------------------------
int32_t UISelection::total () const
{
return (int32_t)viewList.size ();
}
//----------------------------------------------------------------------------------------------------
CView* UISelection::first () const
{
if (!viewList.empty ())
return *begin ();
return nullptr;
}
//----------------------------------------------------------------------------------------------------
CRect UISelection::getBounds () const
{
CRect result;
if (viewList.empty ())
return result;
const_iterator it = begin ();
result = getGlobalViewCoordinates (*it);
++it;
while (it != end ())
{
CRect vs = getGlobalViewCoordinates (*it);
result.unite (vs);
++it;
}
return result;
}
//----------------------------------------------------------------------------------------------------
CRect UISelection::getGlobalViewCoordinates (CView* view)
{
CRect result = view->translateToGlobal (view->getViewSize ());
if (auto frame = view->getFrame ())
return frame->getTransform ().inverse ().transform (result);
return result;
}
//----------------------------------------------------------------------------------------------------
void UISelection::moveBy (const CPoint& p)
{
viewsWillChange ();
const_iterator it = begin ();
while (it != end ())
{
if (!containsParent ((*it)))
{
CRect viewRect = (*it)->getViewSize ();
viewRect.offset (p.x, p.y);
(*it)->setViewSize (viewRect);
(*it)->setMouseableArea (viewRect);
}
it++;
}
viewsDidChange ();
}
//----------------------------------------------------------------------------------------------------
void UISelection::sizeBy (const CRect& r)
{
viewsWillChange ();
for (auto view : *this)
{
auto viewSize = view->getViewSize ();
viewSize.left += r.left;
viewSize.top += r.top;
viewSize.right += r.right;
viewSize.bottom += r.bottom;
view->setViewSize (viewSize);
view->setMouseableArea (viewSize);
}
viewsDidChange ();
}
//----------------------------------------------------------------------------------------------------
void UISelection::invalidRects () const
{
const_iterator it = begin ();
while (it != end ())
{
if (!containsParent ((*it)))
{
(*it)->invalid ();
}
it++;
}
}
//----------------------------------------------------------------------------------------------------
void UISelection::willChange ()
{
if (++inChange == 1)
forEachListener ([this] (IUISelectionListener* l) { l->selectionWillChange (this); });
}
//----------------------------------------------------------------------------------------------------
void UISelection::didChange ()
{
if (--inChange == 0)
forEachListener ([this] (IUISelectionListener* l) { l->selectionDidChange (this); });
}
//----------------------------------------------------------------------------------------------------
void UISelection::viewsWillChange ()
{
if (++inViewsChange == 1)
{
invalidRects ();
forEachListener ([this] (IUISelectionListener* l) { l->selectionViewsWillChange (this); });
}
}
//----------------------------------------------------------------------------------------------------
void UISelection::viewsDidChange ()
{
if (--inViewsChange == 0)
{
invalidRects ();
forEachListener ([this] (IUISelectionListener* l) { l->selectionViewsDidChange (this); });
}
}
//----------------------------------------------------------------------------------------------------
bool UISelection::store (OutputStream& stream, IUIDescription* uiDescription)
{
UIDescription* desc = dynamic_cast<UIDescription*>(uiDescription);
if (desc)
{
std::list<CView*> views;
for (auto view : *this)
{
if (!containsParent (view))
{
views.emplace_back (view);
}
}
auto attr = makeOwned<UIAttributes> ();
attr->setPointAttribute ("selection-drag-offset", dragOffset);
return desc->storeViews (views, stream, attr);
}
return false;
}
//----------------------------------------------------------------------------------------------------
bool UISelection::restore (InputStream& stream, IUIDescription* uiDescription)
{
clear ();
UIDescription* desc = dynamic_cast<UIDescription*>(uiDescription);
if (desc)
{
UIAttributes* attr = nullptr;
if (desc->restoreViews (stream, viewList, &attr))
{
if (attr)
{
attr->getPointAttribute ("selection-drag-offset", dragOffset);
attr->forget ();
}
return true;
}
}
return false;
}
//----------------------------------------------------------------------------------------------------
SharedPointer<CBitmap> createBitmapFromSelection (UISelection* selection, CFrame* frame,
CViewContainer* anchorView)
{
CRect selectionRect = selection->getBounds ();
auto scaleFactor = frame->getScaleFactor ();
auto bitmap = renderBitmapOffscreen (selectionRect.getSize (), scaleFactor, [&] (auto& context) {
CGraphicsTransform tm;
CGraphicsTransform invTm;
if (anchorView)
{
tm = anchorView->getTransform ();
invTm = tm.inverse ();
invTm.transform (selectionRect);
tm = tm * CGraphicsTransform ().translate (-selectionRect.left, -selectionRect.top);
}
double originalZoom = 1.;
if (anchorView && anchorView->isAttached ())
{
// reset frame zoom
originalZoom = anchorView->getFrame ()->getZoom ();
anchorView->getFrame ()->setZoom (1.);
}
CDrawContext::Transform tr (context, tm);
for (auto view : *selection)
{
if (!selection->containsParent (view))
{
CPoint p;
p = view->translateToGlobal (p);
if (anchorView)
invTm.transform (p);
CDrawContext::Transform transform (context,
CGraphicsTransform ().translate (p.x, p.y));
context.setClipRect (view->getViewSize ());
view->drawRect (&context, view->getViewSize ());
}
}
if (anchorView && anchorView->isAttached ())
{
anchorView->getFrame ()->setZoom (originalZoom);
}
});
return bitmap;
}
} // VSTGUI
#endif // VSTGUI_LIVE_EDITING