Files
2026-08-16 18:24:52 +07:00

1568 lines
51 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 "uiactions.h"
#if VSTGUI_LIVE_EDITING
#include "uieditview.h"
#include "../uidescription.h"
#include "../uiattributes.h"
#include "../../lib/cgraphicspath.h"
#include "../../lib/cbitmap.h"
#include "../detail/uiviewcreatorattributes.h"
namespace VSTGUI {
//----------------------------------------------------------------------------------------------------
//----------------------------------------------------------------------------------------------------
//----------------------------------------------------------------------------------------------------
SizeToFitOperation::SizeToFitOperation (UISelection* selection)
: BaseSelectionOperation<std::pair<SharedPointer<CView>, CRect> > (selection)
{
for (auto view : *selection)
emplace_back (view, view->getViewSize ());
}
//----------------------------------------------------------------------------------------------------
UTF8StringPtr SizeToFitOperation::getName ()
{
return "Size To Fit";
}
//----------------------------------------------------------------------------------------------------
void SizeToFitOperation::perform ()
{
selection->viewsWillChange ();
for (auto& element : *this)
{
element.first->invalid ();
element.first->sizeToFit ();
element.first->invalid ();
}
selection->viewsDidChange ();
}
//----------------------------------------------------------------------------------------------------
void SizeToFitOperation::undo ()
{
selection->viewsWillChange ();
for (auto& element : *this)
{
element.first->invalid ();
element.first->setViewSize (element.second);
element.first->setMouseableArea (element.second);
element.first->invalid ();
}
selection->viewsDidChange ();
}
//----------------------------------------------------------------------------------------------------
//----------------------------------------------------------------------------------------------------
//----------------------------------------------------------------------------------------------------
UnembedViewOperation::UnembedViewOperation (UISelection* selection, const IViewFactory* factory)
: BaseSelectionOperation<SharedPointer<CView>> (selection), factory (factory)
{
containerView = selection->first ()->asViewContainer ();
collectSubviews (containerView, true);
parent = containerView->getParentView ()->asViewContainer ();
}
//----------------------------------------------------------------------------------------------------
void UnembedViewOperation::collectSubviews (CViewContainer* container, bool deep)
{
container->forEachChild ([&] (CView* view) {
if (factory->getViewName (view))
{
emplace_back (view);
}
else if (deep)
{
if (auto c = view->asViewContainer ())
collectSubviews (c, false);
}
});
}
//----------------------------------------------------------------------------------------------------
UTF8StringPtr UnembedViewOperation::getName ()
{
return "Unembed Views";
}
//----------------------------------------------------------------------------------------------------
void UnembedViewOperation::perform ()
{
UISelection::DeferChange dc (*selection);
selection->remove (containerView);
CRect containerViewSize = containerView->getViewSize ();
const_reverse_iterator it = rbegin ();
while (it != rend ())
{
CView* view = (*it);
CRect viewSize = view->getViewSize ();
CRect mouseSize = view->getMouseableArea ();
containerView->removeView (view, false);
viewSize.offset (containerViewSize.left, containerViewSize.top);
mouseSize.offset (containerViewSize.left, containerViewSize.top);
view->setViewSize (viewSize);
view->setMouseableArea (mouseSize);
if (parent->addView (view))
selection->add (view);
it++;
}
parent->removeView (containerView, false);
}
//----------------------------------------------------------------------------------------------------
void UnembedViewOperation::undo ()
{
CRect containerViewSize = containerView->getViewSize ();
for (auto& view : *this)
{
parent->removeView (view, false);
CRect viewSize = view->getViewSize ();
CRect mouseSize = view->getMouseableArea ();
viewSize.offset (-containerViewSize.left, -containerViewSize.top);
mouseSize.offset (-containerViewSize.left, -containerViewSize.top);
view->setViewSize (viewSize);
view->setMouseableArea (mouseSize);
containerView->addView (view);
}
parent->addView (containerView);
selection->setExclusive (containerView);
}
//-----------------------------------------------------------------------------
EmbedViewOperation::EmbedViewOperation (UISelection* selection, CViewContainer* newContainer)
: BaseSelectionOperation<std::pair<SharedPointer<CView>, CRect> > (selection)
, newContainer (owned (newContainer))
{
parent = selection->first ()->getParentView ()->asViewContainer ();
for (auto view : *selection)
{
if (view->getParentView () == parent)
{
emplace_back (view, view->getViewSize ());
}
}
CRect r = selection->first ()->getViewSize ();
for (auto& element : *this)
{
CView* view = element.first;
CRect viewSize = view->getViewSize ();
if (viewSize.left < r.left)
r.left = viewSize.left;
if (viewSize.right > r.right)
r.right = viewSize.right;
if (viewSize.top < r.top)
r.top = viewSize.top;
if (viewSize.bottom > r.bottom)
r.bottom = viewSize.bottom;
}
r.extend (10, 10);
newContainer->setViewSize (r);
newContainer->setMouseableArea (r);
}
//-----------------------------------------------------------------------------
UTF8StringPtr EmbedViewOperation::getName ()
{
return "Embed Views";
}
//-----------------------------------------------------------------------------
void EmbedViewOperation::perform ()
{
CRect parentRect = newContainer->getViewSize ();
for (auto& element : *this)
{
CView* view = element.first;
parent->removeView (view, false);
CRect r = view->getViewSize ();
r.offset (-parentRect.left, -parentRect.top);
view->setViewSize (r);
view->setMouseableArea (r);
newContainer->addView (view);
}
parent->addView (newContainer);
newContainer->remember ();
selection->setExclusive (newContainer);
}
//-----------------------------------------------------------------------------
void EmbedViewOperation::undo ()
{
selection->clear ();
const_reverse_iterator it = rbegin ();
while (it != rend ())
{
CView* view = (*it).first;
newContainer->removeView (view, false);
CRect r = (*it).second;
view->setViewSize (r);
view->setMouseableArea (r);
parent->addView (view);
selection->add (view);
it++;
}
parent->removeView (newContainer);
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
ViewCopyOperation::ViewCopyOperation (UISelection* copySelection, UISelection* workingSelection,
CViewContainer* parent, const CPoint& offset,
IUIDescription* desc)
: parent (parent), copySelection (copySelection), workingSelection (workingSelection)
{
CRect selectionBounds = copySelection->getBounds ();
for (auto view : *copySelection)
{
if (!copySelection->containsParent (view))
{
CRect viewSize = UISelection::getGlobalViewCoordinates (view);
CRect newSize (0, 0, view->getWidth (), view->getHeight ());
newSize.offset (offset.x, offset.y);
newSize.offset (viewSize.left - selectionBounds.left, viewSize.top - selectionBounds.top);
view->setViewSize (newSize);
view->setMouseableArea (newSize);
emplace_back (view);
}
}
for (auto view : *workingSelection)
oldSelectedViews.emplace_back (view);
}
//-----------------------------------------------------------------------------
UTF8StringPtr ViewCopyOperation::getName ()
{
if (size () > 0)
return "Copy Views";
return "Copy View";
}
//-----------------------------------------------------------------------------
void ViewCopyOperation::perform ()
{
workingSelection->clear ();
for (auto& view : *this)
{
parent->addView (view);
(view)->remember ();
(view)->invalid ();
workingSelection->add (view);
}
}
//-----------------------------------------------------------------------------
void ViewCopyOperation::undo ()
{
workingSelection->clear ();
for (auto& view : *this)
{
view->invalid ();
parent->removeView (view, true);
}
for (auto& view : oldSelectedViews)
{
workingSelection->add (view);
view->invalid ();
}
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
ViewSizeChangeOperation::ViewSizeChangeOperation (UISelection* selection, bool sizing, bool autosizingEnabled)
: BaseSelectionOperation<std::pair<SharedPointer<CView>, CRect> > (selection)
, first (true)
, sizing (sizing)
, autosizing (autosizingEnabled)
{
for (auto view : *selection)
emplace_back (view, view->getViewSize ());
}
//-----------------------------------------------------------------------------
UTF8StringPtr ViewSizeChangeOperation::getName ()
{
if (size () > 1)
return sizing ? "Resize Views" : "Move Views";
return sizing ? "Resize View" : "Move View";
}
//-----------------------------------------------------------------------------
void ViewSizeChangeOperation::perform ()
{
if (first)
{
first = false;
return;
}
undo ();
}
//-----------------------------------------------------------------------------
void ViewSizeChangeOperation::undo ()
{
selection->clear ();
for (auto& element : *this)
{
CView* view = element.first;
CRect size (element.second);
view->invalid ();
element.second = view->getViewSize ();
CViewContainer* container = nullptr;
bool oldAutosizing = false;
if (!autosizing)
{
container = view->asViewContainer ();
if (container)
{
oldAutosizing = container->getAutosizingEnabled ();
container->setAutosizingEnabled (false);
}
}
view->setViewSize (size);
view->setMouseableArea (size);
view->invalid ();
selection->add (view);
if (!autosizing && container)
{
container->setAutosizingEnabled (oldAutosizing);
}
}
}
//-----------------------------------------------------------------------------
bool ViewSizeChangeOperation::didChange ()
{
auto result = false;
for (auto& element : *this)
{
if (element.second != element.first->getViewSize ())
result = true;
}
return result;
}
//----------------------------------------------------------------------------------------------------
//----------------------------------------------------------------------------------------------------
//----------------------------------------------------------------------------------------------------
DeleteOperation::DeleteOperation (UISelection* selection)
: selection (selection)
{
for (auto view : *selection)
{
CViewContainer* container = view->getParentView ()->asViewContainer ();
if (dynamic_cast<UIEditView*>(container) == nullptr)
{
CView* nextView = nullptr;
ViewIterator it (container);
while (*it)
{
if (*it == view)
{
while (*it && selection->contains (*it))
{
++it;
}
nextView = *it;
break;
}
++it;
}
insert (std::make_pair (container, DeleteOperationViewAndNext (view, nextView)));
}
}
}
//----------------------------------------------------------------------------------------------------
UTF8StringPtr DeleteOperation::getName ()
{
if (size () > 1)
return "Delete Views";
return "Delete View";
}
//----------------------------------------------------------------------------------------------------
void DeleteOperation::perform ()
{
selection->clear ();
for (auto& element : *this)
element.first->removeView (element.second.view);
}
//----------------------------------------------------------------------------------------------------
void DeleteOperation::undo ()
{
selection->clear ();
UISelection::DeferChange dc (*selection);
for (auto& element : *this)
{
if (element.second.nextView)
element.first->addView (element.second.view, element.second.nextView);
else
element.first->addView (element.second.view);
element.second.view->remember ();
selection->add (element.second.view);
}
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
InsertViewOperation::InsertViewOperation (CViewContainer* parent, CView* view, UISelection* selection)
: parent (parent)
, view (view)
, selection (selection)
{
}
//-----------------------------------------------------------------------------
UTF8StringPtr InsertViewOperation::getName ()
{
return "Insert New Subview";
}
//-----------------------------------------------------------------------------
void InsertViewOperation::perform ()
{
if (parent->addView (view))
selection->setExclusive (view);
}
//-----------------------------------------------------------------------------
void InsertViewOperation::undo ()
{
selection->remove (view);
view->remember ();
if (!parent->removeView (view))
view->forget ();
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
TransformViewTypeOperation::TransformViewTypeOperation (UISelection* selection, CView* view,
IdStringPtr viewClassName,
UIDescription* desc,
const IViewFactory* factory)
: view (view)
, newView (nullptr)
, insertIndex (-1)
, parent (view->getParentView ()->asViewContainer ())
, selection (selection)
, factory (factory)
, description (desc)
{
if (const auto* vfEditingSupport = dynamic_cast<const IViewFactoryEditingSupport*> (factory))
{
UIAttributes attr;
if (vfEditingSupport->getAttributesForView (view, desc, attr))
{
attr.setAttribute (UIViewCreator::kAttrClass, viewClassName);
newView = factory->createView (attr, desc);
ViewIterator it (parent);
while (*it)
{
++insertIndex;
if (*it == view)
break;
++it;
}
}
}
}
//-----------------------------------------------------------------------------
TransformViewTypeOperation::~TransformViewTypeOperation ()
{
if (newView)
newView->forget ();
}
//-----------------------------------------------------------------------------
UTF8StringPtr TransformViewTypeOperation::getName ()
{
return "Transform View Type";
}
//-----------------------------------------------------------------------------
void TransformViewTypeOperation::exchangeSubViews (CViewContainer* src, CViewContainer* dst)
{
if (dynamic_cast<const IViewFactoryEditingSupport*> (factory))
{
if (src && dst)
{
std::list<CView*> temp;
src->forEachChild ([&] (CView* childView) {
if (IViewFactory::getViewName (childView))
{
temp.emplace_back (childView);
}
else if (auto container = childView->asViewContainer ())
{
exchangeSubViews (container, dst);
}
});
for (auto& viewToMove : temp)
{
src->removeView (viewToMove, false);
dst->addView (viewToMove);
}
}
}
}
//-----------------------------------------------------------------------------
void TransformViewTypeOperation::perform ()
{
if (newView)
{
newView->remember ();
parent->removeView (view);
parent->addView (newView);
if (insertIndex >= 0)
parent->changeViewZOrder (newView, static_cast<uint32_t> (insertIndex));
exchangeSubViews (view->asViewContainer (), newView->asViewContainer ());
selection->setExclusive (newView);
}
}
//-----------------------------------------------------------------------------
void TransformViewTypeOperation::undo ()
{
if (newView)
{
view->remember ();
parent->removeView (newView);
parent->addView (view);
if (insertIndex >= 0)
parent->changeViewZOrder (view, static_cast<uint32_t> (insertIndex));
exchangeSubViews (newView->asViewContainer (), view->asViewContainer ());
selection->setExclusive (view);
}
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
AttributeChangeAction::AttributeChangeAction (UIDescription* desc, UISelection* selection, const std::string& attrName, const std::string& attrValue)
: desc (desc)
, selection (selection)
, attrName (attrName)
, attrValue (attrValue)
{
const auto* viewFactory = desc->getViewFactory ();
std::string attrOldValue;
for (auto view : *selection)
{
viewFactory->getAttributeValue (view, attrName, attrOldValue, desc);
insert (std::make_pair (view, attrOldValue));
}
name = "'" + attrName + "' change";
}
//-----------------------------------------------------------------------------
UTF8StringPtr AttributeChangeAction::getName ()
{
return name.c_str ();
}
//-----------------------------------------------------------------------------
void AttributeChangeAction::updateSelection ()
{
for (auto& element : *this)
{
if (selection->contains (element.first) == false)
{
UISelection::DeferChange dc (*selection);
selection->clear ();
for (auto& it2 : *this)
selection->add (it2.first);
break;
}
}
}
//-----------------------------------------------------------------------------
void AttributeChangeAction::perform ()
{
const IViewFactory* viewFactory = desc->getViewFactory ();
UIAttributes attr;
attr.setAttribute (attrName, attrValue);
selection->viewsWillChange ();
for (auto& element : *this)
{
element.first->invalid (); // we need to invalid before changing anything as the size may change
viewFactory->applyAttributeValues (element.first, attr, desc);
element.first->invalid (); // and afterwards also
}
selection->viewsDidChange ();
updateSelection ();
}
//-----------------------------------------------------------------------------
void AttributeChangeAction::undo ()
{
const IViewFactory* viewFactory = desc->getViewFactory ();
selection->viewsWillChange ();
for (auto& element : *this)
{
UIAttributes attr;
attr.setAttribute (attrName, element.second);
element.first->invalid (); // we need to invalid before changing anything as the size may change
viewFactory->applyAttributeValues (element.first, attr, desc);
element.first->invalid (); // and afterwards also
}
selection->viewsDidChange ();
updateSelection ();
}
//----------------------------------------------------------------------------------------------------
//----------------------------------------------------------------------------------------------------
//----------------------------------------------------------------------------------------------------
MultipleAttributeChangeAction::MultipleAttributeChangeAction (UIDescription* description, const std::list<CView*>& views, IViewCreator::AttrType attrType, UTF8StringPtr oldValue, UTF8StringPtr newValue)
: description (description)
, oldValue (oldValue)
, newValue (newValue)
{
for (auto& view : views)
collectViewsWithAttributeValue (description->getViewFactory (), description, view, attrType,
oldValue);
}
//----------------------------------------------------------------------------------------------------
void MultipleAttributeChangeAction::collectViewsWithAttributeValue (const IViewFactory* viewFactory,
IUIDescription* desc,
CView* startView,
IViewCreator::AttrType type,
const std::string& value)
{
const auto* viewFactoryEditing = dynamic_cast<const IViewFactoryEditingSupport*> (viewFactory);
if (!viewFactoryEditing)
return;
std::list<CView*> views;
collectAllSubViews (startView, views);
for (auto& view : views)
{
std::list<std::string> attrNames;
if (viewFactoryEditing->getAttributeNamesForView (view, attrNames))
{
for (auto& attrName : attrNames)
{
if (viewFactoryEditing->getAttributeType (view, attrName) == type)
{
std::string typeValue;
if (viewFactory->getAttributeValue (view, attrName, typeValue, desc))
{
if (typeValue == value)
{
emplace_back (view, attrName);
}
}
}
}
}
}
}
//----------------------------------------------------------------------------------------------------
void MultipleAttributeChangeAction::collectAllSubViews (CView* view, std::list<CView*>& views)
{
views.emplace_back (view);
if (auto container = view->asViewContainer ())
{
container->forEachChild ([&] (CView* view) {
collectAllSubViews (view, views);
});
}
}
//----------------------------------------------------------------------------------------------------
void MultipleAttributeChangeAction::setAttributeValue (UTF8StringPtr value)
{
const IViewFactory* viewFactory = description->getViewFactory ();
for (auto& element : *this)
{
CView* view = element.first;
UIAttributes newAttr;
newAttr.setAttribute (element.second, value);
viewFactory->applyAttributeValues (view, newAttr, description);
view->invalid ();
}
}
//----------------------------------------------------------------------------------------------------
void MultipleAttributeChangeAction::perform ()
{
setAttributeValue (newValue.c_str ());
}
//----------------------------------------------------------------------------------------------------
void MultipleAttributeChangeAction::undo ()
{
setAttributeValue (oldValue.c_str ());
}
//----------------------------------------------------------------------------------------------------
//----------------------------------------------------------------------------------------------------
//----------------------------------------------------------------------------------------------------
TagChangeAction::TagChangeAction (UIDescription* description, UTF8StringPtr name, UTF8StringPtr newTagString, bool remove, bool performOrUndo)
: description(description)
, name (name)
, newTag (newTagString ? newTagString : "")
, remove (remove)
, performOrUndo (performOrUndo)
, isNewTag (!description->hasTagName (name))
{
description->getControlTagString (name, originalTag);
}
//----------------------------------------------------------------------------------------------------
UTF8StringPtr TagChangeAction::getName ()
{
return isNewTag ? "Add Tag" : "Change Tag";
}
//----------------------------------------------------------------------------------------------------
void TagChangeAction::perform ()
{
if (performOrUndo)
{
if (remove)
{
description->removeTag (name.c_str ());
}
else
{
description->changeControlTagString (name.c_str (), newTag, isNewTag);
}
}
}
//----------------------------------------------------------------------------------------------------
void TagChangeAction::undo ()
{
if (performOrUndo == false)
{
if (isNewTag)
description->removeTag (name.c_str ());
else
description->changeControlTagString (name.c_str (), originalTag, remove);
}
}
//----------------------------------------------------------------------------------------------------
TagNameChangeAction::TagNameChangeAction (UIDescription* description, UTF8StringPtr oldName, UTF8StringPtr newName, bool performOrUndo)
: description(description)
, oldName (oldName)
, newName (newName)
, performOrUndo (performOrUndo)
{
}
//----------------------------------------------------------------------------------------------------
UTF8StringPtr TagNameChangeAction::getName ()
{
return "Change Tag Name";
}
//----------------------------------------------------------------------------------------------------
void TagNameChangeAction::perform ()
{
if (performOrUndo)
description->changeTagName (oldName.c_str(), newName.c_str());
}
//----------------------------------------------------------------------------------------------------
void TagNameChangeAction::undo ()
{
if (performOrUndo == false)
description->changeTagName (newName.c_str(), oldName.c_str());
}
//----------------------------------------------------------------------------------------------------
//----------------------------------------------------------------------------------------------------
//----------------------------------------------------------------------------------------------------
ColorNameChangeAction::ColorNameChangeAction (UIDescription* description, UTF8StringPtr oldName, UTF8StringPtr newName, bool performOrUndo)
: description(description)
, oldName (oldName)
, newName (newName)
, performOrUndo (performOrUndo)
{
}
//----------------------------------------------------------------------------------------------------
UTF8StringPtr ColorNameChangeAction::getName ()
{
return "Change Color Name";
}
//----------------------------------------------------------------------------------------------------
void ColorNameChangeAction::perform ()
{
if (performOrUndo)
description->changeColorName (oldName.c_str(), newName.c_str());
}
//----------------------------------------------------------------------------------------------------
void ColorNameChangeAction::undo ()
{
if (performOrUndo == false)
description->changeColorName (newName.c_str(), oldName.c_str());
}
//----------------------------------------------------------------------------------------------------
ColorChangeAction::ColorChangeAction (UIDescription* description, UTF8StringPtr name, const CColor& color, bool remove, bool performOrUndo)
: description(description)
, name (name)
, newColor (color)
, remove (remove)
, performOrUndo (performOrUndo)
, isNewColor (!description->hasColorName (name))
{
if (!isNewColor)
description->getColor (name, oldColor);
}
//----------------------------------------------------------------------------------------------------
UTF8StringPtr ColorChangeAction::getName ()
{
return isNewColor ? "Add Color" : "Change Color";
}
//----------------------------------------------------------------------------------------------------
void ColorChangeAction::perform ()
{
if (performOrUndo)
{
if (remove)
{
description->removeColor (name.c_str ());
}
else
{
description->changeColor (name.c_str (), newColor);
}
}
}
//----------------------------------------------------------------------------------------------------
void ColorChangeAction::undo ()
{
if (performOrUndo == false)
{
if (isNewColor)
description->removeColor (name.c_str ());
else
description->changeColor (name.c_str (), oldColor);
}
}
//----------------------------------------------------------------------------------------------------
//----------------------------------------------------------------------------------------------------
//----------------------------------------------------------------------------------------------------
BitmapChangeAction::BitmapChangeAction (UIDescription* description, UTF8StringPtr name, UTF8StringPtr path, bool remove, bool performOrUndo)
: description(description)
, name (name)
, path (path ? path : "")
, remove (remove)
, performOrUndo (performOrUndo)
, isNewBitmap (!description->hasBitmapName (name))
{
CBitmap* bitmap = description->getBitmap (name);
if (bitmap)
originalPath = bitmap->getResourceDescription().u.name;
}
//----------------------------------------------------------------------------------------------------
UTF8StringPtr BitmapChangeAction::getName ()
{
return isNewBitmap ? "Add New Bitmap" : "Change Bitmap";
}
//----------------------------------------------------------------------------------------------------
void BitmapChangeAction::perform ()
{
if (performOrUndo)
{
if (remove)
{
description->removeBitmap (name.c_str ());
}
else
{
description->changeBitmap (name.c_str (), path.c_str ());
}
}
}
//----------------------------------------------------------------------------------------------------
void BitmapChangeAction::undo ()
{
if (performOrUndo == false)
{
if (isNewBitmap)
description->removeBitmap (name.c_str ());
else
description->changeBitmap (name.c_str (), originalPath.c_str ());
}
}
//----------------------------------------------------------------------------------------------------
BitmapNameChangeAction::BitmapNameChangeAction (UIDescription* description, UTF8StringPtr oldName, UTF8StringPtr newName, bool performOrUndo)
: description(description)
, oldName (oldName)
, newName (newName)
, performOrUndo (performOrUndo)
{
}
//----------------------------------------------------------------------------------------------------
UTF8StringPtr BitmapNameChangeAction::getName ()
{
return "Change Bitmap Name";
}
//----------------------------------------------------------------------------------------------------
void BitmapNameChangeAction::perform ()
{
if (performOrUndo)
description->changeBitmapName (oldName.c_str(), newName.c_str());
}
//----------------------------------------------------------------------------------------------------
void BitmapNameChangeAction::undo ()
{
if (performOrUndo == false)
description->changeBitmapName (newName.c_str(), oldName.c_str());
}
//----------------------------------------------------------------------------------------------------
//----------------------------------------------------------------------------------------------------
//----------------------------------------------------------------------------------------------------
NinePartTiledBitmapChangeAction::NinePartTiledBitmapChangeAction (UIDescription* description, UTF8StringPtr name, const CRect* rect, bool performOrUndo)
: description (description)
, name (name)
, oldRect (nullptr)
, newRect (nullptr)
, performOrUndo (performOrUndo)
{
if (rect)
newRect = new CRect (*rect);
CBitmap* bitmap = description->getBitmap (name);
if (bitmap)
{
CNinePartTiledBitmap* tiledBitmap = dynamic_cast<CNinePartTiledBitmap*>(bitmap);
if (tiledBitmap)
{
const CNinePartTiledDescription& offset = tiledBitmap->getPartOffsets ();
oldRect = new CRect;
oldRect->left = offset.left;
oldRect->top = offset.top;
oldRect->right = offset.right;
oldRect->bottom = offset.bottom;
}
}
}
//----------------------------------------------------------------------------------------------------
NinePartTiledBitmapChangeAction::~NinePartTiledBitmapChangeAction ()
{
if (newRect)
delete newRect;
if (oldRect)
delete oldRect;
}
//----------------------------------------------------------------------------------------------------
UTF8StringPtr NinePartTiledBitmapChangeAction::getName ()
{
return "Change NinePartTiledBitmap";
}
//----------------------------------------------------------------------------------------------------
void NinePartTiledBitmapChangeAction::perform ()
{
if (performOrUndo)
{
CBitmap* bitmap = description->getBitmap (name.c_str ());
if (bitmap)
description->changeBitmap (name.c_str (), bitmap->getResourceDescription ().u.name, newRect);
}
}
//----------------------------------------------------------------------------------------------------
void NinePartTiledBitmapChangeAction::undo ()
{
if (performOrUndo == false)
{
CBitmap* bitmap = description->getBitmap (name.c_str ());
if (bitmap)
description->changeBitmap (name.c_str (), bitmap->getResourceDescription ().u.name, oldRect);
}
}
//----------------------------------------------------------------------------------------------------
//----------------------------------------------------------------------------------------------------
//----------------------------------------------------------------------------------------------------
MultiFrameBitmapChangeAction::MultiFrameBitmapChangeAction (
UIDescription* description, UTF8StringPtr name, const CMultiFrameBitmapDescription* desc,
bool performOrUndo)
: description (description), name (name), performOrUndo (performOrUndo)
{
if (desc)
newDesc = std::make_unique<CMultiFrameBitmapDescription> (*desc);
CBitmap* bitmap = description->getBitmap (name);
if (bitmap)
{
if (auto mfb = dynamic_cast<CMultiFrameBitmap*> (bitmap))
{
oldDesc = std::make_unique<CMultiFrameBitmapDescription> ();
oldDesc->frameSize = mfb->getFrameSize ();
oldDesc->numFrames = mfb->getNumFrames ();
oldDesc->framesPerRow = mfb->getNumFramesPerRow ();
}
}
}
//----------------------------------------------------------------------------------------------------
MultiFrameBitmapChangeAction::~MultiFrameBitmapChangeAction () {}
//----------------------------------------------------------------------------------------------------
UTF8StringPtr MultiFrameBitmapChangeAction::getName () { return "Change MultiFrameBitmap"; }
//----------------------------------------------------------------------------------------------------
void MultiFrameBitmapChangeAction::perform ()
{
if (performOrUndo)
{
CBitmap* bitmap = description->getBitmap (name.data ());
if (bitmap)
description->changeMultiFrameBitmap (
name.data (), bitmap->getResourceDescription ().u.name, newDesc.get ());
}
}
//----------------------------------------------------------------------------------------------------
void MultiFrameBitmapChangeAction::undo ()
{
if (performOrUndo == false)
{
CBitmap* bitmap = description->getBitmap (name.data ());
if (bitmap)
description->changeMultiFrameBitmap (
name.data (), bitmap->getResourceDescription ().u.name, oldDesc.get ());
}
}
//----------------------------------------------------------------------------------------------------
//----------------------------------------------------------------------------------------------------
//----------------------------------------------------------------------------------------------------
BitmapFilterChangeAction::BitmapFilterChangeAction (UIDescription* description, UTF8StringPtr bitmapName, const std::list<SharedPointer<UIAttributes> >& attributes, bool performOrUndo)
: description (description)
, bitmapName (bitmapName)
, newAttributes (attributes)
, performOrUndo (performOrUndo)
{
description->collectBitmapFilters (bitmapName, oldAttributes);
}
//----------------------------------------------------------------------------------------------------
UTF8StringPtr BitmapFilterChangeAction::getName ()
{
return "Change Bitmap Filter";
}
//----------------------------------------------------------------------------------------------------
void BitmapFilterChangeAction::perform ()
{
if (performOrUndo)
{
description->changeBitmapFilters (bitmapName.c_str (), newAttributes);
}
}
//----------------------------------------------------------------------------------------------------
void BitmapFilterChangeAction::undo ()
{
if (performOrUndo == false)
{
description->changeBitmapFilters (bitmapName.c_str (), oldAttributes);
}
}
//----------------------------------------------------------------------------------------------------
//----------------------------------------------------------------------------------------------------
//----------------------------------------------------------------------------------------------------
GradientChangeAction::GradientChangeAction (UIDescription* description, UTF8StringPtr name, CGradient* gradient, bool remove, bool performOrUndo)
: description(description)
, name (name)
, gradient (gradient)
, remove (remove)
, performOrUndo (performOrUndo)
{
originalGradient = description->getGradient (name);
}
//----------------------------------------------------------------------------------------------------
UTF8StringPtr GradientChangeAction::getName ()
{
return originalGradient ? "Change Gradient" : "Add New Gradient";
}
//----------------------------------------------------------------------------------------------------
void GradientChangeAction::perform ()
{
if (performOrUndo)
{
if (remove)
{
description->removeGradient (name.c_str ());
}
else
{
description->changeGradient (name.c_str (), gradient);
}
}
}
//----------------------------------------------------------------------------------------------------
void GradientChangeAction::undo ()
{
if (performOrUndo == false)
{
if (originalGradient)
{
description->changeGradient (name.c_str (), originalGradient);
}
else
{
description->removeGradient (name.c_str ());
}
}
}
//----------------------------------------------------------------------------------------------------
GradientNameChangeAction::GradientNameChangeAction (UIDescription* description, UTF8StringPtr oldName, UTF8StringPtr newName, bool performOrUndo)
: description(description)
, oldName (oldName)
, newName (newName)
, performOrUndo (performOrUndo)
{
}
//----------------------------------------------------------------------------------------------------
UTF8StringPtr GradientNameChangeAction::getName ()
{
return "Change Gradient Name";
}
//----------------------------------------------------------------------------------------------------
void GradientNameChangeAction::perform ()
{
if (performOrUndo)
description->changeGradientName (oldName.c_str(), newName.c_str());
}
//----------------------------------------------------------------------------------------------------
void GradientNameChangeAction::undo ()
{
if (performOrUndo == false)
description->changeGradientName (newName.c_str(), oldName.c_str());
}
//----------------------------------------------------------------------------------------------------
//----------------------------------------------------------------------------------------------------
//----------------------------------------------------------------------------------------------------
FontChangeAction::FontChangeAction (UIDescription* description, UTF8StringPtr name, CFontRef font, bool remove, bool performOrUndo)
: description(description)
, name (name)
, font (font)
, remove (remove)
, performOrUndo (performOrUndo)
{
originalFont = description->getFont (name);
if (remove)
description->getAlternativeFontNames (name, alternativeNames);
}
//----------------------------------------------------------------------------------------------------
UTF8StringPtr FontChangeAction::getName ()
{
return originalFont ? "Change Font" : "Add New Font";
}
//----------------------------------------------------------------------------------------------------
void FontChangeAction::perform ()
{
if (performOrUndo)
{
if (remove)
{
description->removeFont (name.c_str ());
}
else
{
description->changeFont (name.c_str (), font);
}
}
}
//----------------------------------------------------------------------------------------------------
void FontChangeAction::undo ()
{
if (performOrUndo == false)
{
if (originalFont)
{
description->changeFont (name.c_str (), originalFont);
description->changeAlternativeFontNames (name.c_str (), alternativeNames.c_str ());
}
else
{
description->removeFont (name.c_str ());
}
}
}
//----------------------------------------------------------------------------------------------------
FontNameChangeAction::FontNameChangeAction (UIDescription* description, UTF8StringPtr oldName, UTF8StringPtr newName, bool performOrUndo)
: description(description)
, oldName (oldName)
, newName (newName)
, performOrUndo (performOrUndo)
{
}
//----------------------------------------------------------------------------------------------------
UTF8StringPtr FontNameChangeAction::getName ()
{
return "Change Font Name";
}
//----------------------------------------------------------------------------------------------------
void FontNameChangeAction::perform ()
{
if (performOrUndo)
description->changeFontName (oldName.c_str(), newName.c_str());
}
//----------------------------------------------------------------------------------------------------
void FontNameChangeAction::undo ()
{
if (performOrUndo == false)
description->changeFontName (newName.c_str(), oldName.c_str());
}
//----------------------------------------------------------------------------------------------------
//----------------------------------------------------------------------------------------------------
//----------------------------------------------------------------------------------------------------
AlternateFontChangeAction::AlternateFontChangeAction (UIDescription* description, UTF8StringPtr fontName, UTF8StringPtr newAlternateFontNames)
: description (description)
, fontName (fontName)
, newAlternateFontNames (newAlternateFontNames ? newAlternateFontNames : "")
{
description->getAlternativeFontNames (fontName, oldAlternateFontNames);
}
//----------------------------------------------------------------------------------------------------
UTF8StringPtr AlternateFontChangeAction::getName ()
{
return "Change Alternative Font Names";
}
//----------------------------------------------------------------------------------------------------
void AlternateFontChangeAction::perform ()
{
description->changeAlternativeFontNames (fontName.c_str (), newAlternateFontNames.c_str ());
}
//----------------------------------------------------------------------------------------------------
void AlternateFontChangeAction::undo ()
{
description->changeAlternativeFontNames (fontName.c_str (), oldAlternateFontNames.c_str ());
}
//----------------------------------------------------------------------------------------------------
//----------------------------------------------------------------------------------------------------
//----------------------------------------------------------------------------------------------------
HierarchyMoveViewOperation::HierarchyMoveViewOperation (CView* view, UISelection* selection, int32_t dir)
: view (view)
, parent (nullptr)
, selection (selection)
, dir (dir)
{
parent = view->getParentView ()->asViewContainer ();
}
//----------------------------------------------------------------------------------------------------
UTF8StringPtr HierarchyMoveViewOperation::getName ()
{
return "Change View Hierarchy";
}
//----------------------------------------------------------------------------------------------------
void HierarchyMoveViewOperation::perform ()
{
if (!parent)
return;
uint32_t currentIndex = 0;
ViewIterator it (parent);
while (*it && *it != view)
{
++it;
currentIndex++;
}
selection->willChange ();
parent->changeViewZOrder (view, currentIndex + dir);
selection->didChange ();
parent->invalid ();
}
//----------------------------------------------------------------------------------------------------
void HierarchyMoveViewOperation::undo ()
{
dir = -dir;
perform ();
dir = -dir;
}
//----------------------------------------------------------------------------------------------------
//----------------------------------------------------------------------------------------------------
//----------------------------------------------------------------------------------------------------
TemplateNameChangeAction::TemplateNameChangeAction (UIDescription* description, IActionPerformer* actionPerformer, UTF8StringPtr oldName, UTF8StringPtr newName)
: description (description)
, actionPerformer (actionPerformer)
, oldName (oldName)
, newName (newName)
{
}
//----------------------------------------------------------------------------------------------------
UTF8StringPtr TemplateNameChangeAction::getName ()
{
return "Change Template Name";
}
//----------------------------------------------------------------------------------------------------
void TemplateNameChangeAction::perform ()
{
actionPerformer->onTemplateNameChange (oldName.c_str (), newName.c_str ());
description->changeTemplateName (oldName.c_str (), newName.c_str ());
}
//----------------------------------------------------------------------------------------------------
void TemplateNameChangeAction::undo ()
{
actionPerformer->onTemplateNameChange (newName.c_str (), oldName.c_str ());
description->changeTemplateName (newName.c_str (), oldName.c_str ());
}
//----------------------------------------------------------------------------------------------------
//----------------------------------------------------------------------------------------------------
//----------------------------------------------------------------------------------------------------
CreateNewTemplateAction::CreateNewTemplateAction (UIDescription* description, IActionPerformer* actionPerformer, UTF8StringPtr name, UTF8StringPtr baseViewClassName)
: description (description)
, actionPerformer (actionPerformer)
, name (name)
, baseViewClassName (baseViewClassName)
{
}
//----------------------------------------------------------------------------------------------------
UTF8StringPtr CreateNewTemplateAction::getName ()
{
return "Create New Template";
}
//----------------------------------------------------------------------------------------------------
void CreateNewTemplateAction::perform ()
{
auto attr = makeOwned<UIAttributes> ();
attr->setAttribute (UIViewCreator::kAttrClass, baseViewClassName);
attr->setAttribute ("size", "400,400");
description->addNewTemplate (name.c_str (), attr);
if (view == nullptr)
view = description->createView (name.c_str (), description->getController ());
actionPerformer->onTemplateCreation (name.c_str (), view);
}
//----------------------------------------------------------------------------------------------------
void CreateNewTemplateAction::undo ()
{
description->removeTemplate (name.c_str ());
}
//----------------------------------------------------------------------------------------------------
//----------------------------------------------------------------------------------------------------
//----------------------------------------------------------------------------------------------------
DuplicateTemplateAction::DuplicateTemplateAction (UIDescription* description, IActionPerformer* actionPerformer, UTF8StringPtr name, UTF8StringPtr dupName)
: description (description)
, actionPerformer (actionPerformer)
, name (name)
, dupName (dupName)
{
}
//----------------------------------------------------------------------------------------------------
UTF8StringPtr DuplicateTemplateAction::getName ()
{
return "Duplicate Template";
}
//----------------------------------------------------------------------------------------------------
void DuplicateTemplateAction::perform ()
{
description->duplicateTemplate (name.c_str (), dupName.c_str ());
if (view == nullptr)
view = description->createView (dupName.c_str (), description->getController ());
actionPerformer->onTemplateCreation (dupName.c_str (), view);
}
//----------------------------------------------------------------------------------------------------
void DuplicateTemplateAction::undo ()
{
description->removeTemplate (dupName.c_str ());
}
//----------------------------------------------------------------------------------------------------
//----------------------------------------------------------------------------------------------------
//----------------------------------------------------------------------------------------------------
DeleteTemplateAction::DeleteTemplateAction (UIDescription* description, IActionPerformer* actionPerformer, CView* view, UTF8StringPtr name)
: description (description)
, actionPerformer (actionPerformer)
, view (view)
, name (name)
{
attributes = const_cast<UIAttributes*> (description->getViewAttributes (name));
}
//----------------------------------------------------------------------------------------------------
UTF8StringPtr DeleteTemplateAction::getName ()
{
return "Delete Template";
}
//----------------------------------------------------------------------------------------------------
void DeleteTemplateAction::perform ()
{
attributes->remember ();
description->removeTemplate (name.c_str ());
}
//----------------------------------------------------------------------------------------------------
void DeleteTemplateAction::undo ()
{
actionPerformer->onTemplateCreation (name.c_str (), view);
description->addNewTemplate (name.c_str (), attributes);
}
//----------------------------------------------------------------------------------------------------
//----------------------------------------------------------------------------------------------------
//----------------------------------------------------------------------------------------------------
ChangeFocusDrawingAction::ChangeFocusDrawingAction (UIDescription* description, const FocusDrawingSettings& newSettings)
: description (description)
, newSettings (newSettings)
{
oldSettings = description->getFocusDrawingSettings ();
}
//----------------------------------------------------------------------------------------------------
UTF8StringPtr ChangeFocusDrawingAction::getName ()
{
return "Change Focus Drawing Settings";
}
//----------------------------------------------------------------------------------------------------
void ChangeFocusDrawingAction::perform ()
{
description->setFocusDrawingSettings (newSettings);
}
//----------------------------------------------------------------------------------------------------
void ChangeFocusDrawingAction::undo ()
{
description->setFocusDrawingSettings (oldSettings);
}
//----------------------------------------------------------------------------------------------------
//----------------------------------------------------------------------------------------------------
//----------------------------------------------------------------------------------------------------
ChangeTemplateMinMaxAction::ChangeTemplateMinMaxAction (UIDescription* description, UTF8StringPtr templateName, CPoint minSize, CPoint maxSize)
: description (description)
, templateName (templateName)
, minSize (minSize)
, maxSize (maxSize)
{
if (auto attr = description->getViewAttributes (templateName))
{
CPoint p;
if (attr->getPointAttribute (kTemplateAttributeMinSize, p))
oldMinSize = p;
else
oldMinSize = {-1, -1};
if (attr->getPointAttribute (kTemplateAttributeMaxSize, p))
oldMaxSize = p;
else
oldMaxSize = {-1, -1};
}
}
//----------------------------------------------------------------------------------------------------
void ChangeTemplateMinMaxAction::setMinMaxSize (CPoint minimum, CPoint maximum)
{
if (auto attr = const_cast<UIAttributes*> (description->getViewAttributes (templateName.data ())))
{
if (minimum.x == -1. && minimum.y == -1.)
{
attr->removeAttribute (kTemplateAttributeMinSize);
}
else
{
attr->setPointAttribute (kTemplateAttributeMinSize, minimum);
}
if (maximum.x == -1. && maximum.y == -1.)
{
attr->removeAttribute (kTemplateAttributeMaxSize);
}
else
{
attr->setPointAttribute (kTemplateAttributeMaxSize, maximum);
}
}
}
//----------------------------------------------------------------------------------------------------
UTF8StringPtr ChangeTemplateMinMaxAction::getName ()
{
return "Change Template Min/Max Sizes";
}
//----------------------------------------------------------------------------------------------------
void ChangeTemplateMinMaxAction::perform ()
{
setMinMaxSize (minSize, maxSize);
}
//----------------------------------------------------------------------------------------------------
void ChangeTemplateMinMaxAction::undo ()
{
setMinMaxSize (oldMinSize, oldMaxSize);
}
//----------------------------------------------------------------------------------------------------
} // VSTGUI
#endif // VSTGUI_LIVE_EDITING