1 // This file is part of VSTGUI. It is subject to the license terms
2 // in the LICENSE file found in the top-level directory of this
3 // distribution and at http://github.com/steinbergmedia/vstgui/LICENSE
4 
5 #include "uiactions.h"
6 
7 #if VSTGUI_LIVE_EDITING
8 
9 #include "uieditview.h"
10 #include "../uiviewfactory.h"
11 #include "../uidescription.h"
12 #include "../uiattributes.h"
13 #include "../../lib/cgraphicspath.h"
14 #include "../../lib/cbitmap.h"
15 #include "../detail/uiviewcreatorattributes.h"
16 
17 namespace VSTGUI {
18 
19 //----------------------------------------------------------------------------------------------------
20 //----------------------------------------------------------------------------------------------------
21 //----------------------------------------------------------------------------------------------------
SizeToFitOperation(UISelection * selection)22 SizeToFitOperation::SizeToFitOperation (UISelection* selection)
23 : BaseSelectionOperation<std::pair<SharedPointer<CView>, CRect> > (selection)
24 {
25 	for (auto view : *selection)
26 		emplace_back (view, view->getViewSize ());
27 }
28 
29 //----------------------------------------------------------------------------------------------------
getName()30 UTF8StringPtr SizeToFitOperation::getName ()
31 {
32 	return "Size To Fit";
33 }
34 
35 //----------------------------------------------------------------------------------------------------
perform()36 void SizeToFitOperation::perform ()
37 {
38 	selection->changed (UISelection::kMsgSelectionViewWillChange);
39 	for (auto& element : *this)
40 	{
41 		element.first->invalid ();
42 		element.first->sizeToFit ();
43 		element.first->invalid ();
44 	}
45 	selection->changed (UISelection::kMsgSelectionViewChanged);
46 }
47 
48 //----------------------------------------------------------------------------------------------------
undo()49 void SizeToFitOperation::undo ()
50 {
51 	selection->changed (UISelection::kMsgSelectionViewWillChange);
52 	for (auto& element : *this)
53 	{
54 		element.first->invalid ();
55 		element.first->setViewSize (element.second);
56 		element.first->setMouseableArea (element.second);
57 		element.first->invalid ();
58 	}
59 	selection->changed (UISelection::kMsgSelectionViewChanged);
60 }
61 
62 //----------------------------------------------------------------------------------------------------
63 //----------------------------------------------------------------------------------------------------
64 //----------------------------------------------------------------------------------------------------
UnembedViewOperation(UISelection * selection,const IViewFactory * factory)65 UnembedViewOperation::UnembedViewOperation (UISelection* selection, const IViewFactory* factory)
66 : BaseSelectionOperation<SharedPointer<CView> > (selection)
67 , factory (static_cast<const UIViewFactory*> (factory))
68 {
69 	containerView = selection->first ()->asViewContainer ();
70 	collectSubviews (containerView, true);
71 	parent = containerView->getParentView ()->asViewContainer ();
72 }
73 
74 //----------------------------------------------------------------------------------------------------
collectSubviews(CViewContainer * container,bool deep)75 void UnembedViewOperation::collectSubviews (CViewContainer* container, bool deep)
76 {
77 	container->forEachChild ([&] (CView* view) {
78 		if (factory->getViewName (view))
79 		{
80 			emplace_back (view);
81 		}
82 		else if (deep)
83 		{
84 			if (auto c = view->asViewContainer ())
85 				collectSubviews (c, false);
86 		}
87 	});
88 }
89 
90 //----------------------------------------------------------------------------------------------------
getName()91 UTF8StringPtr UnembedViewOperation::getName ()
92 {
93 	return "Unembed Views";
94 }
95 
96 //----------------------------------------------------------------------------------------------------
perform()97 void UnembedViewOperation::perform ()
98 {
99 	IDependency::DeferChanges dc (selection);
100 	selection->remove (containerView);
101 	CRect containerViewSize = containerView->getViewSize ();
102 	const_reverse_iterator it = rbegin ();
103 	while (it != rend ())
104 	{
105 		CView* view = (*it);
106 		CRect viewSize = view->getViewSize ();
107 		CRect mouseSize = view->getMouseableArea ();
108 		containerView->removeView (view, false);
109 		viewSize.offset (containerViewSize.left, containerViewSize.top);
110 		mouseSize.offset (containerViewSize.left, containerViewSize.top);
111 		view->setViewSize (viewSize);
112 		view->setMouseableArea (mouseSize);
113 		if (parent->addView (view))
114 			selection->add (view);
115 		it++;
116 	}
117 	parent->removeView (containerView, false);
118 }
119 
120 //----------------------------------------------------------------------------------------------------
undo()121 void UnembedViewOperation::undo ()
122 {
123 	CRect containerViewSize = containerView->getViewSize ();
124 	for (auto& view : *this)
125 	{
126 		parent->removeView (view, false);
127 		CRect viewSize = view->getViewSize ();
128 		CRect mouseSize = view->getMouseableArea ();
129 		viewSize.offset (-containerViewSize.left, -containerViewSize.top);
130 		mouseSize.offset (-containerViewSize.left, -containerViewSize.top);
131 		view->setViewSize (viewSize);
132 		view->setMouseableArea (mouseSize);
133 		containerView->addView (view);
134 	}
135 	parent->addView (containerView);
136 	selection->setExclusive (containerView);
137 }
138 
139 //-----------------------------------------------------------------------------
EmbedViewOperation(UISelection * selection,CViewContainer * newContainer)140 EmbedViewOperation::EmbedViewOperation (UISelection* selection, CViewContainer* newContainer)
141 : BaseSelectionOperation<std::pair<SharedPointer<CView>, CRect> > (selection)
142 , newContainer (owned (newContainer))
143 {
144 	parent = selection->first ()->getParentView ()->asViewContainer ();
145 	for (auto view : *selection)
146 	{
147 		if (view->getParentView () == parent)
148 		{
149 			emplace_back (view, view->getViewSize ());
150 		}
151 	}
152 
153 	CRect r = selection->first ()->getViewSize ();
154 	for (auto& element : *this)
155 	{
156 		CView* view = element.first;
157 		CRect viewSize = view->getViewSize ();
158 		if (viewSize.left < r.left)
159 			r.left = viewSize.left;
160 		if (viewSize.right > r.right)
161 			r.right = viewSize.right;
162 		if (viewSize.top < r.top)
163 			r.top = viewSize.top;
164 		if (viewSize.bottom > r.bottom)
165 			r.bottom = viewSize.bottom;
166 	}
167 	r.extend (10, 10);
168 	newContainer->setViewSize (r);
169 	newContainer->setMouseableArea (r);
170 }
171 
172 //-----------------------------------------------------------------------------
getName()173 UTF8StringPtr EmbedViewOperation::getName ()
174 {
175 	return "Embed Views";
176 }
177 
178 //-----------------------------------------------------------------------------
perform()179 void EmbedViewOperation::perform ()
180 {
181 	CRect parentRect = newContainer->getViewSize ();
182 	for (auto& element : *this)
183 	{
184 		CView* view = element.first;
185 		parent->removeView (view, false);
186 		CRect r = view->getViewSize ();
187 		r.offset (-parentRect.left, -parentRect.top);
188 		view->setViewSize (r);
189 		view->setMouseableArea (r);
190 		newContainer->addView (view);
191 	}
192 	parent->addView (newContainer);
193 	newContainer->remember ();
194 	selection->setExclusive (newContainer);
195 }
196 
197 //-----------------------------------------------------------------------------
undo()198 void EmbedViewOperation::undo ()
199 {
200 	selection->clear ();
201 	CRect parentRect = newContainer->getViewSize ();
202 	const_reverse_iterator it = rbegin ();
203 	while (it != rend ())
204 	{
205 		CView* view = (*it).first;
206 		newContainer->removeView (view, false);
207 		CRect r = (*it).second;
208 		view->setViewSize (r);
209 		view->setMouseableArea (r);
210 		parent->addView (view);
211 		selection->add (view);
212 		it++;
213 	}
214 	parent->removeView (newContainer);
215 }
216 
217 //-----------------------------------------------------------------------------
218 //-----------------------------------------------------------------------------
219 //-----------------------------------------------------------------------------
ViewCopyOperation(UISelection * copySelection,UISelection * workingSelection,CViewContainer * parent,const CPoint & offset,IUIDescription * desc)220 ViewCopyOperation::ViewCopyOperation (UISelection* copySelection, UISelection* workingSelection,
221                                       CViewContainer* parent, const CPoint& offset,
222                                       IUIDescription* desc)
223 : parent (parent), copySelection (copySelection), workingSelection (workingSelection)
224 {
225 	CRect selectionBounds = copySelection->getBounds ();
226 	for (auto view : *copySelection)
227 	{
228 		if (!copySelection->containsParent (view))
229 		{
230 			CRect viewSize = UISelection::getGlobalViewCoordinates (view);
231 			CRect newSize (0, 0, view->getWidth (), view->getHeight ());
232 			newSize.offset (offset.x, offset.y);
233 			newSize.offset (viewSize.left - selectionBounds.left, viewSize.top - selectionBounds.top);
234 
235 			view->setViewSize (newSize);
236 			view->setMouseableArea (newSize);
237 			emplace_back (view);
238 		}
239 	}
240 
241 	for (auto view : *workingSelection)
242 		oldSelectedViews.emplace_back (view);
243 }
244 
245 //-----------------------------------------------------------------------------
getName()246 UTF8StringPtr ViewCopyOperation::getName ()
247 {
248 	if (size () > 0)
249 		return "Copy Views";
250 	return "Copy View";
251 }
252 
253 //-----------------------------------------------------------------------------
perform()254 void ViewCopyOperation::perform ()
255 {
256 	workingSelection->clear ();
257 	for (auto& view : *this)
258 	{
259 		parent->addView (view);
260 		(view)->remember ();
261 		(view)->invalid ();
262 		workingSelection->add (view);
263 	}
264 }
265 
266 //-----------------------------------------------------------------------------
undo()267 void ViewCopyOperation::undo ()
268 {
269 	workingSelection->clear ();
270 	for (auto& view : *this)
271 	{
272 		view->invalid ();
273 		parent->removeView (view, true);
274 	}
275 	for (auto& view : oldSelectedViews)
276 	{
277 		workingSelection->add (view);
278 		view->invalid ();
279 	}
280 }
281 
282 //-----------------------------------------------------------------------------
283 //-----------------------------------------------------------------------------
284 //-----------------------------------------------------------------------------
ViewSizeChangeOperation(UISelection * selection,bool sizing,bool autosizingEnabled)285 ViewSizeChangeOperation::ViewSizeChangeOperation (UISelection* selection, bool sizing, bool autosizingEnabled)
286 : BaseSelectionOperation<std::pair<SharedPointer<CView>, CRect> > (selection)
287 , first (true)
288 , sizing (sizing)
289 , autosizing (autosizingEnabled)
290 {
291 	for (auto view : *selection)
292 		emplace_back (view, view->getViewSize ());
293 }
294 
295 //-----------------------------------------------------------------------------
getName()296 UTF8StringPtr ViewSizeChangeOperation::getName ()
297 {
298 	if (size () > 1)
299 		return sizing ? "Resize Views" : "Move Views";
300 	return sizing ? "Resize View" : "Move View";
301 }
302 
303 //-----------------------------------------------------------------------------
perform()304 void ViewSizeChangeOperation::perform ()
305 {
306 	if (first)
307 	{
308 		first = false;
309 		return;
310 	}
311 	undo ();
312 }
313 
314 //-----------------------------------------------------------------------------
undo()315 void ViewSizeChangeOperation::undo ()
316 {
317 	selection->clear ();
318 	for (auto& element : *this)
319 	{
320 		CView* view = element.first;
321 		CRect size (element.second);
322 		view->invalid ();
323 		element.second = view->getViewSize ();
324 		CViewContainer* container = nullptr;
325 		bool oldAutosizing = false;
326 		if (!autosizing)
327 		{
328 			container = view->asViewContainer ();
329 			if (container)
330 			{
331 				oldAutosizing = container->getAutosizingEnabled ();
332 				container->setAutosizingEnabled (false);
333 			}
334 		}
335 		view->setViewSize (size);
336 		view->setMouseableArea (size);
337 		view->invalid ();
338 		selection->add (view);
339 		if (!autosizing && container)
340 		{
341 			container->setAutosizingEnabled (oldAutosizing);
342 		}
343 	}
344 }
345 
346 //-----------------------------------------------------------------------------
didChange()347 bool ViewSizeChangeOperation::didChange ()
348 {
349 	auto result = false;
350 	for (auto& element : *this)
351 	{
352 		if (element.second != element.first->getViewSize ())
353 			result = true;
354 	}
355 	return result;
356 }
357 
358 //----------------------------------------------------------------------------------------------------
359 //----------------------------------------------------------------------------------------------------
360 //----------------------------------------------------------------------------------------------------
DeleteOperation(UISelection * selection)361 DeleteOperation::DeleteOperation (UISelection* selection)
362 : selection (selection)
363 {
364 	for (auto view : *selection)
365 	{
366 		CViewContainer* container = view->getParentView ()->asViewContainer ();
367 		if (dynamic_cast<UIEditView*>(container) == nullptr)
368 		{
369 			CView* nextView = nullptr;
370 			ViewIterator it (container);
371 			while (*it)
372 			{
373 				if (*it == view)
374 				{
375 					while (*it && selection->contains (*it))
376 					{
377 						++it;
378 					}
379 					nextView = *it;
380 					break;
381 				}
382 				++it;
383 			}
384 			insert (std::make_pair (container, DeleteOperationViewAndNext (view, nextView)));
385 		}
386 	}
387 }
388 
389 //----------------------------------------------------------------------------------------------------
getName()390 UTF8StringPtr DeleteOperation::getName ()
391 {
392 	if (size () > 1)
393 		return "Delete Views";
394 	return "Delete View";
395 }
396 
397 //----------------------------------------------------------------------------------------------------
perform()398 void DeleteOperation::perform ()
399 {
400 	selection->clear ();
401 	for (auto& element : *this)
402 		element.first->removeView (element.second.view);
403 }
404 
405 //----------------------------------------------------------------------------------------------------
undo()406 void DeleteOperation::undo ()
407 {
408 	selection->clear ();
409 	IDependency::DeferChanges dc (selection);
410 	for (auto& element : *this)
411 	{
412 		if (element.second.nextView)
413 			element.first->addView (element.second.view, element.second.nextView);
414 		else
415 			element.first->addView (element.second.view);
416 		element.second.view->remember ();
417 		selection->add (element.second.view);
418 	}
419 }
420 
421 //-----------------------------------------------------------------------------
422 //-----------------------------------------------------------------------------
423 //-----------------------------------------------------------------------------
InsertViewOperation(CViewContainer * parent,CView * view,UISelection * selection)424 InsertViewOperation::InsertViewOperation (CViewContainer* parent, CView* view, UISelection* selection)
425 : parent (parent)
426 , view (view)
427 , selection (selection)
428 {
429 }
430 
431 //-----------------------------------------------------------------------------
getName()432 UTF8StringPtr InsertViewOperation::getName ()
433 {
434 	return "Insert New Subview";
435 }
436 
437 //-----------------------------------------------------------------------------
perform()438 void InsertViewOperation::perform ()
439 {
440 	if (parent->addView (view))
441 		selection->setExclusive (view);
442 }
443 
444 //-----------------------------------------------------------------------------
undo()445 void InsertViewOperation::undo ()
446 {
447 	selection->remove (view);
448 	view->remember ();
449 	if (!parent->removeView (view))
450 		view->forget ();
451 }
452 
453 //-----------------------------------------------------------------------------
454 //-----------------------------------------------------------------------------
455 //-----------------------------------------------------------------------------
TransformViewTypeOperation(UISelection * selection,IdStringPtr viewClassName,UIDescription * desc,const UIViewFactory * factory)456 TransformViewTypeOperation::TransformViewTypeOperation (UISelection* selection, IdStringPtr viewClassName, UIDescription* desc, const UIViewFactory* factory)
457 : view (selection->first ())
458 , newView (nullptr)
459 , beforeView (nullptr)
460 , parent (view->getParentView ()->asViewContainer ())
461 , selection (selection)
462 , factory (factory)
463 , description (desc)
464 {
465 	UIAttributes attr;
466 	if (factory->getAttributesForView (view, desc, attr))
467 	{
468 		attr.setAttribute (UIViewCreator::kAttrClass, viewClassName);
469 		newView = factory->createView (attr, desc);
470 		ViewIterator it (parent);
471 		while (*it)
472 		{
473 			if (*it == view)
474 			{
475 				beforeView = *++it;
476 				break;
477 			}
478 			++it;
479 		}
480 	}
481 }
482 
483 //-----------------------------------------------------------------------------
~TransformViewTypeOperation()484 TransformViewTypeOperation::~TransformViewTypeOperation ()
485 {
486 	if (newView)
487 		newView->forget ();
488 }
489 
490 //-----------------------------------------------------------------------------
getName()491 UTF8StringPtr TransformViewTypeOperation::getName ()
492 {
493 	return "Transform View Type";
494 }
495 
496 //-----------------------------------------------------------------------------
exchangeSubViews(CViewContainer * src,CViewContainer * dst)497 void TransformViewTypeOperation::exchangeSubViews (CViewContainer* src, CViewContainer* dst)
498 {
499 	if (src && dst)
500 	{
501 		std::list<CView*> temp;
502 
503 		src->forEachChild ([&] (CView* childView) {
504 			if (factory->getViewName (childView))
505 			{
506 				temp.emplace_back (childView);
507 			}
508 			else if (auto container = childView->asViewContainer ())
509 			{
510 				exchangeSubViews (container, dst);
511 			}
512 		});
513 		for (auto& view : temp)
514 		{
515 			src->removeView (view, false);
516 			dst->addView (view);
517 		}
518 	}
519 }
520 
521 //-----------------------------------------------------------------------------
perform()522 void TransformViewTypeOperation::perform ()
523 {
524 	if (newView)
525 	{
526 		newView->remember ();
527 		parent->removeView (view);
528 		if (beforeView)
529 			parent->addView (newView, beforeView);
530 		else
531 			parent->addView (newView);
532 		exchangeSubViews (view->asViewContainer (), newView->asViewContainer ());
533 		selection->setExclusive (newView);
534 	}
535 }
536 
537 //-----------------------------------------------------------------------------
undo()538 void TransformViewTypeOperation::undo ()
539 {
540 	if (newView)
541 	{
542 		view->remember ();
543 		parent->removeView (newView);
544 		if (beforeView)
545 			parent->addView (view, beforeView);
546 		else
547 			parent->addView (view);
548 		exchangeSubViews (newView->asViewContainer (), view->asViewContainer ());
549 		selection->setExclusive (view);
550 	}
551 }
552 
553 //-----------------------------------------------------------------------------
554 //-----------------------------------------------------------------------------
555 //-----------------------------------------------------------------------------
AttributeChangeAction(UIDescription * desc,UISelection * selection,const std::string & attrName,const std::string & attrValue)556 AttributeChangeAction::AttributeChangeAction (UIDescription* desc, UISelection* selection, const std::string& attrName, const std::string& attrValue)
557 : desc (desc)
558 , selection (selection)
559 , attrName (attrName)
560 , attrValue (attrValue)
561 {
562 	const UIViewFactory* viewFactory = dynamic_cast<const UIViewFactory*> (desc->getViewFactory ());
563 	std::string attrOldValue;
564 	for (auto view : *selection)
565 	{
566 		viewFactory->getAttributeValue (view, attrName, attrOldValue, desc);
567 		insert (std::make_pair (view, attrOldValue));
568 	}
569 	name = "'" + attrName + "' change";
570 }
571 
572 //-----------------------------------------------------------------------------
getName()573 UTF8StringPtr AttributeChangeAction::getName ()
574 {
575 	return name.c_str ();
576 }
577 
578 //-----------------------------------------------------------------------------
updateSelection()579 void AttributeChangeAction::updateSelection ()
580 {
581 	for (auto& element : *this)
582 	{
583 		if (selection->contains (element.first) == false)
584 		{
585 			IDependency::DeferChanges dc (selection);
586 			selection->clear ();
587 			for (auto& it2 : *this)
588 				selection->add (it2.first);
589 			break;
590 		}
591 	}
592 }
593 
594 //-----------------------------------------------------------------------------
perform()595 void AttributeChangeAction::perform ()
596 {
597 	const IViewFactory* viewFactory = desc->getViewFactory ();
598 	UIAttributes attr;
599 	attr.setAttribute (attrName, attrValue);
600 	selection->changed (UISelection::kMsgSelectionViewWillChange);
601 	for (auto& element : *this)
602 	{
603 		element.first->invalid ();	// we need to invalid before changing anything as the size may change
604 		viewFactory->applyAttributeValues (element.first, attr, desc);
605 		element.first->invalid ();	// and afterwards also
606 	}
607 	selection->changed (UISelection::kMsgSelectionViewChanged);
608 	updateSelection ();
609 }
610 
611 //-----------------------------------------------------------------------------
undo()612 void AttributeChangeAction::undo ()
613 {
614 	const IViewFactory* viewFactory = desc->getViewFactory ();
615 	selection->changed (UISelection::kMsgSelectionViewWillChange);
616 	for (auto& element : *this)
617 	{
618 		UIAttributes attr;
619 		attr.setAttribute (attrName, element.second);
620 		element.first->invalid ();	// we need to invalid before changing anything as the size may change
621 		viewFactory->applyAttributeValues (element.first, attr, desc);
622 		element.first->invalid ();	// and afterwards also
623 	}
624 	selection->changed (UISelection::kMsgSelectionViewChanged);
625 	updateSelection ();
626 }
627 
628 //----------------------------------------------------------------------------------------------------
629 //----------------------------------------------------------------------------------------------------
630 //----------------------------------------------------------------------------------------------------
MultipleAttributeChangeAction(UIDescription * description,const std::list<CView * > & views,IViewCreator::AttrType attrType,UTF8StringPtr oldValue,UTF8StringPtr newValue)631 MultipleAttributeChangeAction::MultipleAttributeChangeAction (UIDescription* description, const std::list<CView*>& views, IViewCreator::AttrType attrType, UTF8StringPtr oldValue, UTF8StringPtr newValue)
632 : description (description)
633 , oldValue (oldValue)
634 , newValue (newValue)
635 {
636 	const UIViewFactory* viewFactory = dynamic_cast<const UIViewFactory*>(description->getViewFactory ());
637 	for (auto& view : views)
638 		collectViewsWithAttributeValue (viewFactory, description, view, attrType, oldValue);
639 }
640 
641 //----------------------------------------------------------------------------------------------------
collectViewsWithAttributeValue(const UIViewFactory * viewFactory,IUIDescription * desc,CView * startView,IViewCreator::AttrType type,const std::string & value)642 void MultipleAttributeChangeAction::collectViewsWithAttributeValue (const UIViewFactory* viewFactory, IUIDescription* desc, CView* startView, IViewCreator::AttrType type, const std::string& value)
643 {
644 	std::list<CView*> views;
645 	collectAllSubViews (startView, views);
646 	for (auto& view : views)
647 	{
648 		std::list<std::string> attrNames;
649 		if (viewFactory->getAttributeNamesForView (view, attrNames))
650 		{
651 			for (auto& attrName : attrNames)
652 			{
653 				if (viewFactory->getAttributeType (view, attrName) == type)
654 				{
655 					std::string typeValue;
656 					if (viewFactory->getAttributeValue (view, attrName, typeValue, desc))
657 					{
658 						if (typeValue == value)
659 						{
660 							emplace_back (view, attrName);
661 						}
662 					}
663 				}
664 			}
665 		}
666 	}
667 }
668 
669 //----------------------------------------------------------------------------------------------------
collectAllSubViews(CView * view,std::list<CView * > & views)670 void MultipleAttributeChangeAction::collectAllSubViews (CView* view, std::list<CView*>& views)
671 {
672 	views.emplace_back (view);
673 	if (auto container = view->asViewContainer ())
674 	{
675 		container->forEachChild ([&] (CView* view) {
676 			collectAllSubViews (view, views);
677 		});
678 	}
679 }
680 
681 //----------------------------------------------------------------------------------------------------
setAttributeValue(UTF8StringPtr value)682 void MultipleAttributeChangeAction::setAttributeValue (UTF8StringPtr value)
683 {
684 	const IViewFactory* viewFactory = description->getViewFactory ();
685 	for (auto& element : *this)
686 	{
687 		CView* view = element.first;
688 		UIAttributes newAttr;
689 		newAttr.setAttribute (element.second, value);
690 		viewFactory->applyAttributeValues (view, newAttr, description);
691 		view->invalid ();
692 	}
693 }
694 
695 //----------------------------------------------------------------------------------------------------
perform()696 void MultipleAttributeChangeAction::perform ()
697 {
698 	setAttributeValue (newValue.c_str ());
699 }
700 
701 //----------------------------------------------------------------------------------------------------
undo()702 void MultipleAttributeChangeAction::undo ()
703 {
704 	setAttributeValue (oldValue.c_str ());
705 }
706 
707 //----------------------------------------------------------------------------------------------------
708 //----------------------------------------------------------------------------------------------------
709 //----------------------------------------------------------------------------------------------------
TagChangeAction(UIDescription * description,UTF8StringPtr name,UTF8StringPtr newTagString,bool remove,bool performOrUndo)710 TagChangeAction::TagChangeAction (UIDescription* description, UTF8StringPtr name, UTF8StringPtr newTagString, bool remove, bool performOrUndo)
711 : description(description)
712 , name (name)
713 , newTag (newTagString ? newTagString : "")
714 , remove (remove)
715 , performOrUndo (performOrUndo)
716 , isNewTag (!description->hasTagName (name))
717 {
718 	description->getControlTagString (name, originalTag);
719 }
720 
721 //----------------------------------------------------------------------------------------------------
getName()722 UTF8StringPtr TagChangeAction::getName ()
723 {
724 	return isNewTag ? "Add Tag" : "Change Tag";
725 }
726 
727 //----------------------------------------------------------------------------------------------------
perform()728 void TagChangeAction::perform ()
729 {
730 	if (performOrUndo)
731 	{
732 		if (remove)
733 		{
734 			description->removeTag (name.c_str ());
735 		}
736 		else
737 		{
738 			description->changeControlTagString (name.c_str (), newTag, isNewTag);
739 		}
740 	}
741 }
742 
743 //----------------------------------------------------------------------------------------------------
undo()744 void TagChangeAction::undo ()
745 {
746 	if (performOrUndo == false)
747 	{
748 		if (isNewTag)
749 			description->removeTag (name.c_str ());
750 		else
751 			description->changeControlTagString (name.c_str (), originalTag, remove);
752 	}
753 }
754 
755 //----------------------------------------------------------------------------------------------------
TagNameChangeAction(UIDescription * description,UTF8StringPtr oldName,UTF8StringPtr newName,bool performOrUndo)756 TagNameChangeAction::TagNameChangeAction (UIDescription* description, UTF8StringPtr oldName, UTF8StringPtr newName, bool performOrUndo)
757 : description(description)
758 , oldName (oldName)
759 , newName (newName)
760 , performOrUndo (performOrUndo)
761 {
762 }
763 
764 //----------------------------------------------------------------------------------------------------
getName()765 UTF8StringPtr TagNameChangeAction::getName ()
766 {
767 	return "Change Tag Name";
768 }
769 
770 //----------------------------------------------------------------------------------------------------
perform()771 void TagNameChangeAction::perform ()
772 {
773 	if (performOrUndo)
774 		description->changeTagName (oldName.c_str(), newName.c_str());
775 }
776 
777 //----------------------------------------------------------------------------------------------------
undo()778 void TagNameChangeAction::undo ()
779 {
780 	if (performOrUndo == false)
781 		description->changeTagName (newName.c_str(), oldName.c_str());
782 }
783 
784 //----------------------------------------------------------------------------------------------------
785 //----------------------------------------------------------------------------------------------------
786 //----------------------------------------------------------------------------------------------------
ColorNameChangeAction(UIDescription * description,UTF8StringPtr oldName,UTF8StringPtr newName,bool performOrUndo)787 ColorNameChangeAction::ColorNameChangeAction (UIDescription* description, UTF8StringPtr oldName, UTF8StringPtr newName, bool performOrUndo)
788 : description(description)
789 , oldName (oldName)
790 , newName (newName)
791 , performOrUndo (performOrUndo)
792 {
793 }
794 
795 //----------------------------------------------------------------------------------------------------
getName()796 UTF8StringPtr ColorNameChangeAction::getName ()
797 {
798 	return "Change Color Name";
799 }
800 
801 //----------------------------------------------------------------------------------------------------
perform()802 void ColorNameChangeAction::perform ()
803 {
804 	if (performOrUndo)
805 		description->changeColorName (oldName.c_str(), newName.c_str());
806 }
807 
808 //----------------------------------------------------------------------------------------------------
undo()809 void ColorNameChangeAction::undo ()
810 {
811 	if (performOrUndo == false)
812 		description->changeColorName (newName.c_str(), oldName.c_str());
813 }
814 
815 //----------------------------------------------------------------------------------------------------
ColorChangeAction(UIDescription * description,UTF8StringPtr name,const CColor & color,bool remove,bool performOrUndo)816 ColorChangeAction::ColorChangeAction (UIDescription* description, UTF8StringPtr name, const CColor& color, bool remove, bool performOrUndo)
817 : description(description)
818 , name (name)
819 , newColor (color)
820 , remove (remove)
821 , performOrUndo (performOrUndo)
822 , isNewColor (!description->hasColorName (name))
823 {
824 	if (!isNewColor)
825 		description->getColor (name, oldColor);
826 }
827 
828 //----------------------------------------------------------------------------------------------------
getName()829 UTF8StringPtr ColorChangeAction::getName ()
830 {
831 	return isNewColor ? "Add Color" : "Change Color";
832 }
833 
834 //----------------------------------------------------------------------------------------------------
perform()835 void ColorChangeAction::perform ()
836 {
837 	if (performOrUndo)
838 	{
839 		if (remove)
840 		{
841 			description->removeColor (name.c_str ());
842 		}
843 		else
844 		{
845 			description->changeColor (name.c_str (), newColor);
846 		}
847 	}
848 }
849 
850 //----------------------------------------------------------------------------------------------------
undo()851 void ColorChangeAction::undo ()
852 {
853 	if (performOrUndo == false)
854 	{
855 		if (isNewColor)
856 			description->removeColor (name.c_str ());
857 		else
858 			description->changeColor (name.c_str (), oldColor);
859 	}
860 }
861 
862 //----------------------------------------------------------------------------------------------------
863 //----------------------------------------------------------------------------------------------------
864 //----------------------------------------------------------------------------------------------------
BitmapChangeAction(UIDescription * description,UTF8StringPtr name,UTF8StringPtr path,bool remove,bool performOrUndo)865 BitmapChangeAction::BitmapChangeAction (UIDescription* description, UTF8StringPtr name, UTF8StringPtr path, bool remove, bool performOrUndo)
866 : description(description)
867 , name (name)
868 , path (path ? path : "")
869 , remove (remove)
870 , performOrUndo (performOrUndo)
871 , isNewBitmap (!description->hasBitmapName (name))
872 {
873 	CBitmap* bitmap = description->getBitmap (name);
874 	if (bitmap)
875 		originalPath = bitmap->getResourceDescription().u.name;
876 }
877 
878 //----------------------------------------------------------------------------------------------------
getName()879 UTF8StringPtr BitmapChangeAction::getName ()
880 {
881 	return isNewBitmap ? "Add New Bitmap" : "Change Bitmap";
882 }
883 
884 //----------------------------------------------------------------------------------------------------
perform()885 void BitmapChangeAction::perform ()
886 {
887 	if (performOrUndo)
888 	{
889 		if (remove)
890 		{
891 			description->removeBitmap (name.c_str ());
892 		}
893 		else
894 		{
895 			description->changeBitmap (name.c_str (), path.c_str ());
896 		}
897 	}
898 }
899 
900 //----------------------------------------------------------------------------------------------------
undo()901 void BitmapChangeAction::undo ()
902 {
903 	if (performOrUndo == false)
904 	{
905 		if (isNewBitmap)
906 			description->removeBitmap (name.c_str ());
907 		else
908 			description->changeBitmap (name.c_str (), originalPath.c_str ());
909 	}
910 }
911 
912 //----------------------------------------------------------------------------------------------------
BitmapNameChangeAction(UIDescription * description,UTF8StringPtr oldName,UTF8StringPtr newName,bool performOrUndo)913 BitmapNameChangeAction::BitmapNameChangeAction (UIDescription* description, UTF8StringPtr oldName, UTF8StringPtr newName, bool performOrUndo)
914 : description(description)
915 , oldName (oldName)
916 , newName (newName)
917 , performOrUndo (performOrUndo)
918 {
919 }
920 
921 //----------------------------------------------------------------------------------------------------
getName()922 UTF8StringPtr BitmapNameChangeAction::getName ()
923 {
924 	return "Change Bitmap Name";
925 }
926 
927 //----------------------------------------------------------------------------------------------------
perform()928 void BitmapNameChangeAction::perform ()
929 {
930 	if (performOrUndo)
931 		description->changeBitmapName (oldName.c_str(), newName.c_str());
932 }
933 
934 //----------------------------------------------------------------------------------------------------
undo()935 void BitmapNameChangeAction::undo ()
936 {
937 	if (performOrUndo == false)
938 		description->changeBitmapName (newName.c_str(), oldName.c_str());
939 }
940 
941 //----------------------------------------------------------------------------------------------------
942 //----------------------------------------------------------------------------------------------------
943 //----------------------------------------------------------------------------------------------------
NinePartTiledBitmapChangeAction(UIDescription * description,UTF8StringPtr name,const CRect * rect,bool performOrUndo)944 NinePartTiledBitmapChangeAction::NinePartTiledBitmapChangeAction (UIDescription* description, UTF8StringPtr name, const CRect* rect, bool performOrUndo)
945 : description (description)
946 , name (name)
947 , oldRect (nullptr)
948 , newRect (nullptr)
949 , performOrUndo (performOrUndo)
950 {
951 	if (rect)
952 		newRect = new CRect (*rect);
953 	CBitmap* bitmap = description->getBitmap (name);
954 	if (bitmap)
955 	{
956 		CNinePartTiledBitmap* tiledBitmap = dynamic_cast<CNinePartTiledBitmap*>(bitmap);
957 		if (tiledBitmap)
958 		{
959 			const CNinePartTiledDescription& offset = tiledBitmap->getPartOffsets ();
960 			oldRect = new CRect;
961 			oldRect->left = offset.left;
962 			oldRect->top = offset.top;
963 			oldRect->right = offset.right;
964 			oldRect->bottom = offset.bottom;
965 		}
966 	}
967 }
968 
969 //----------------------------------------------------------------------------------------------------
~NinePartTiledBitmapChangeAction()970 NinePartTiledBitmapChangeAction::~NinePartTiledBitmapChangeAction ()
971 {
972 	if (newRect)
973 		delete newRect;
974 	if (oldRect)
975 		delete oldRect;
976 }
977 
978 //----------------------------------------------------------------------------------------------------
getName()979 UTF8StringPtr NinePartTiledBitmapChangeAction::getName ()
980 {
981 	return "Change NinePartTiledBitmap";
982 }
983 
984 //----------------------------------------------------------------------------------------------------
perform()985 void NinePartTiledBitmapChangeAction::perform ()
986 {
987 	if (performOrUndo)
988 	{
989 		CBitmap* bitmap = description->getBitmap (name.c_str ());
990 		if (bitmap)
991 			description->changeBitmap (name.c_str (), bitmap->getResourceDescription ().u.name, newRect);
992 	}
993 }
994 
995 //----------------------------------------------------------------------------------------------------
undo()996 void NinePartTiledBitmapChangeAction::undo ()
997 {
998 	if (performOrUndo == false)
999 	{
1000 		CBitmap* bitmap = description->getBitmap (name.c_str ());
1001 		if (bitmap)
1002 			description->changeBitmap (name.c_str (), bitmap->getResourceDescription ().u.name, oldRect);
1003 	}
1004 }
1005 
1006 //----------------------------------------------------------------------------------------------------
1007 //----------------------------------------------------------------------------------------------------
1008 //----------------------------------------------------------------------------------------------------
BitmapFilterChangeAction(UIDescription * description,UTF8StringPtr bitmapName,const std::list<SharedPointer<UIAttributes>> & attributes,bool performOrUndo)1009 BitmapFilterChangeAction::BitmapFilterChangeAction (UIDescription* description, UTF8StringPtr bitmapName, const std::list<SharedPointer<UIAttributes> >& attributes, bool performOrUndo)
1010 : description (description)
1011 , bitmapName (bitmapName)
1012 , newAttributes (attributes)
1013 , performOrUndo (performOrUndo)
1014 {
1015 	description->collectBitmapFilters (bitmapName, oldAttributes);
1016 }
1017 
1018 //----------------------------------------------------------------------------------------------------
getName()1019 UTF8StringPtr BitmapFilterChangeAction::getName ()
1020 {
1021 	return "Change Bitmap Filter";
1022 }
1023 
1024 //----------------------------------------------------------------------------------------------------
perform()1025 void BitmapFilterChangeAction::perform ()
1026 {
1027 	if (performOrUndo)
1028 	{
1029 		description->changeBitmapFilters (bitmapName.c_str (), newAttributes);
1030 	}
1031 }
1032 
1033 //----------------------------------------------------------------------------------------------------
undo()1034 void BitmapFilterChangeAction::undo ()
1035 {
1036 	if (performOrUndo == false)
1037 	{
1038 		description->changeBitmapFilters (bitmapName.c_str (), oldAttributes);
1039 	}
1040 }
1041 
1042 //----------------------------------------------------------------------------------------------------
1043 //----------------------------------------------------------------------------------------------------
1044 //----------------------------------------------------------------------------------------------------
GradientChangeAction(UIDescription * description,UTF8StringPtr name,CGradient * gradient,bool remove,bool performOrUndo)1045 GradientChangeAction::GradientChangeAction (UIDescription* description, UTF8StringPtr name, CGradient* gradient, bool remove, bool performOrUndo)
1046 : description(description)
1047 , name (name)
1048 , gradient (gradient)
1049 , remove (remove)
1050 , performOrUndo (performOrUndo)
1051 {
1052 	originalGradient = description->getGradient (name);
1053 }
1054 
1055 //----------------------------------------------------------------------------------------------------
getName()1056 UTF8StringPtr GradientChangeAction::getName ()
1057 {
1058 	return originalGradient ? "Change Gradient" : "Add New Gradient";
1059 }
1060 
1061 //----------------------------------------------------------------------------------------------------
perform()1062 void GradientChangeAction::perform ()
1063 {
1064 	if (performOrUndo)
1065 	{
1066 		if (remove)
1067 		{
1068 			description->removeGradient (name.c_str ());
1069 		}
1070 		else
1071 		{
1072 			description->changeGradient (name.c_str (), gradient);
1073 		}
1074 	}
1075 }
1076 
1077 //----------------------------------------------------------------------------------------------------
undo()1078 void GradientChangeAction::undo ()
1079 {
1080 	if (performOrUndo == false)
1081 	{
1082 		if (originalGradient)
1083 		{
1084 			description->changeGradient (name.c_str (), originalGradient);
1085 		}
1086 		else
1087 		{
1088 			description->removeGradient (name.c_str ());
1089 		}
1090 	}
1091 }
1092 
1093 //----------------------------------------------------------------------------------------------------
GradientNameChangeAction(UIDescription * description,UTF8StringPtr oldName,UTF8StringPtr newName,bool performOrUndo)1094 GradientNameChangeAction::GradientNameChangeAction (UIDescription* description, UTF8StringPtr oldName, UTF8StringPtr newName, bool performOrUndo)
1095 : description(description)
1096 , oldName (oldName)
1097 , newName (newName)
1098 , performOrUndo (performOrUndo)
1099 {
1100 }
1101 
1102 //----------------------------------------------------------------------------------------------------
getName()1103 UTF8StringPtr GradientNameChangeAction::getName ()
1104 {
1105 	return "Change Gradient Name";
1106 }
1107 
1108 //----------------------------------------------------------------------------------------------------
perform()1109 void GradientNameChangeAction::perform ()
1110 {
1111 	if (performOrUndo)
1112 		description->changeGradientName (oldName.c_str(), newName.c_str());
1113 }
1114 
1115 //----------------------------------------------------------------------------------------------------
undo()1116 void GradientNameChangeAction::undo ()
1117 {
1118 	if (performOrUndo == false)
1119 		description->changeGradientName (newName.c_str(), oldName.c_str());
1120 }
1121 
1122 //----------------------------------------------------------------------------------------------------
1123 //----------------------------------------------------------------------------------------------------
1124 //----------------------------------------------------------------------------------------------------
FontChangeAction(UIDescription * description,UTF8StringPtr name,CFontRef font,bool remove,bool performOrUndo)1125 FontChangeAction::FontChangeAction (UIDescription* description, UTF8StringPtr name, CFontRef font, bool remove, bool performOrUndo)
1126 : description(description)
1127 , name (name)
1128 , font (font)
1129 , remove (remove)
1130 , performOrUndo (performOrUndo)
1131 {
1132 	originalFont = description->getFont (name);
1133 	if (remove)
1134 		description->getAlternativeFontNames (name, alternativeNames);
1135 }
1136 
1137 //----------------------------------------------------------------------------------------------------
getName()1138 UTF8StringPtr FontChangeAction::getName ()
1139 {
1140 	return originalFont ? "Change Font" : "Add New Font";
1141 }
1142 
1143 //----------------------------------------------------------------------------------------------------
perform()1144 void FontChangeAction::perform ()
1145 {
1146 	if (performOrUndo)
1147 	{
1148 		if (remove)
1149 		{
1150 			description->removeFont (name.c_str ());
1151 		}
1152 		else
1153 		{
1154 			description->changeFont (name.c_str (), font);
1155 		}
1156 	}
1157 }
1158 
1159 //----------------------------------------------------------------------------------------------------
undo()1160 void FontChangeAction::undo ()
1161 {
1162 	if (performOrUndo == false)
1163 	{
1164 		if (originalFont)
1165 		{
1166 			description->changeFont (name.c_str (), originalFont);
1167 			description->changeAlternativeFontNames (name.c_str (), alternativeNames.c_str ());
1168 		}
1169 		else
1170 		{
1171 			description->removeFont (name.c_str ());
1172 		}
1173 	}
1174 }
1175 
1176 //----------------------------------------------------------------------------------------------------
FontNameChangeAction(UIDescription * description,UTF8StringPtr oldName,UTF8StringPtr newName,bool performOrUndo)1177 FontNameChangeAction::FontNameChangeAction (UIDescription* description, UTF8StringPtr oldName, UTF8StringPtr newName, bool performOrUndo)
1178 : description(description)
1179 , oldName (oldName)
1180 , newName (newName)
1181 , performOrUndo (performOrUndo)
1182 {
1183 }
1184 
1185 //----------------------------------------------------------------------------------------------------
getName()1186 UTF8StringPtr FontNameChangeAction::getName ()
1187 {
1188 	return "Change Font Name";
1189 }
1190 
1191 //----------------------------------------------------------------------------------------------------
perform()1192 void FontNameChangeAction::perform ()
1193 {
1194 	if (performOrUndo)
1195 		description->changeFontName (oldName.c_str(), newName.c_str());
1196 }
1197 
1198 //----------------------------------------------------------------------------------------------------
undo()1199 void FontNameChangeAction::undo ()
1200 {
1201 	if (performOrUndo == false)
1202 		description->changeFontName (newName.c_str(), oldName.c_str());
1203 }
1204 
1205 //----------------------------------------------------------------------------------------------------
1206 //----------------------------------------------------------------------------------------------------
1207 //----------------------------------------------------------------------------------------------------
AlternateFontChangeAction(UIDescription * description,UTF8StringPtr fontName,UTF8StringPtr newAlternateFontNames)1208 AlternateFontChangeAction::AlternateFontChangeAction (UIDescription* description, UTF8StringPtr fontName, UTF8StringPtr newAlternateFontNames)
1209 : description (description)
1210 , fontName (fontName)
1211 , newAlternateFontNames (newAlternateFontNames ? newAlternateFontNames : "")
1212 {
1213 	description->getAlternativeFontNames (fontName, oldAlternateFontNames);
1214 }
1215 
1216 //----------------------------------------------------------------------------------------------------
getName()1217 UTF8StringPtr AlternateFontChangeAction::getName ()
1218 {
1219 	return "Change Alternative Font Names";
1220 }
1221 
1222 //----------------------------------------------------------------------------------------------------
perform()1223 void AlternateFontChangeAction::perform ()
1224 {
1225 	description->changeAlternativeFontNames (fontName.c_str (), newAlternateFontNames.c_str ());
1226 }
1227 
1228 //----------------------------------------------------------------------------------------------------
undo()1229 void AlternateFontChangeAction::undo ()
1230 {
1231 	description->changeAlternativeFontNames (fontName.c_str (), oldAlternateFontNames.c_str ());
1232 }
1233 
1234 //----------------------------------------------------------------------------------------------------
1235 //----------------------------------------------------------------------------------------------------
1236 //----------------------------------------------------------------------------------------------------
HierarchyMoveViewOperation(CView * view,UISelection * selection,bool up)1237 HierarchyMoveViewOperation::HierarchyMoveViewOperation (CView* view, UISelection* selection, bool up)
1238 : view (view)
1239 , parent (nullptr)
1240 , selection (selection)
1241 , up (up)
1242 {
1243 	parent = view->getParentView ()->asViewContainer ();
1244 }
1245 
1246 //----------------------------------------------------------------------------------------------------
getName()1247 UTF8StringPtr HierarchyMoveViewOperation::getName ()
1248 {
1249 	return "Change View Hierarchy";
1250 }
1251 
1252 //----------------------------------------------------------------------------------------------------
perform()1253 void HierarchyMoveViewOperation::perform ()
1254 {
1255 	if (!parent)
1256 		return;
1257 	uint32_t currentIndex = 0;
1258 	ViewIterator it (parent);
1259 	while (*it && *it != view)
1260 	{
1261 		it++;
1262 		currentIndex++;
1263 	}
1264 	parent->changeViewZOrder (view, up ? currentIndex - 1 : currentIndex + 1);
1265 	selection->changed (UISelection::kMsgSelectionChanged);
1266 	parent->invalid ();
1267 }
1268 
1269 //----------------------------------------------------------------------------------------------------
undo()1270 void HierarchyMoveViewOperation::undo ()
1271 {
1272 	up = !up;
1273 	perform ();
1274 	up = !up;
1275 }
1276 
1277 //----------------------------------------------------------------------------------------------------
1278 //----------------------------------------------------------------------------------------------------
1279 //----------------------------------------------------------------------------------------------------
TemplateNameChangeAction(UIDescription * description,IActionPerformer * actionPerformer,UTF8StringPtr oldName,UTF8StringPtr newName)1280 TemplateNameChangeAction::TemplateNameChangeAction (UIDescription* description, IActionPerformer* actionPerformer, UTF8StringPtr oldName, UTF8StringPtr newName)
1281 : description (description)
1282 , actionPerformer (actionPerformer)
1283 , oldName (oldName)
1284 , newName (newName)
1285 {
1286 }
1287 
1288 //----------------------------------------------------------------------------------------------------
getName()1289 UTF8StringPtr TemplateNameChangeAction::getName ()
1290 {
1291 	return "Change Template Name";
1292 }
1293 
1294 //----------------------------------------------------------------------------------------------------
perform()1295 void TemplateNameChangeAction::perform ()
1296 {
1297 	actionPerformer->onTemplateNameChange (oldName.c_str (), newName.c_str ());
1298 	description->changeTemplateName (oldName.c_str (), newName.c_str ());
1299 }
1300 
1301 //----------------------------------------------------------------------------------------------------
undo()1302 void TemplateNameChangeAction::undo ()
1303 {
1304 	actionPerformer->onTemplateNameChange (newName.c_str (), oldName.c_str ());
1305 	description->changeTemplateName (newName.c_str (), oldName.c_str ());
1306 }
1307 
1308 //----------------------------------------------------------------------------------------------------
1309 //----------------------------------------------------------------------------------------------------
1310 //----------------------------------------------------------------------------------------------------
CreateNewTemplateAction(UIDescription * description,IActionPerformer * actionPerformer,UTF8StringPtr name,UTF8StringPtr baseViewClassName)1311 CreateNewTemplateAction::CreateNewTemplateAction (UIDescription* description, IActionPerformer* actionPerformer, UTF8StringPtr name, UTF8StringPtr baseViewClassName)
1312 : description (description)
1313 , actionPerformer (actionPerformer)
1314 , name (name)
1315 , baseViewClassName (baseViewClassName)
1316 {
1317 }
1318 
1319 //----------------------------------------------------------------------------------------------------
getName()1320 UTF8StringPtr CreateNewTemplateAction::getName ()
1321 {
1322 	return "Create New Template";
1323 }
1324 
1325 //----------------------------------------------------------------------------------------------------
perform()1326 void CreateNewTemplateAction::perform ()
1327 {
1328 	auto attr = makeOwned<UIAttributes> ();
1329 	attr->setAttribute (UIViewCreator::kAttrClass, baseViewClassName);
1330 	attr->setAttribute ("size", "400,400");
1331 	description->addNewTemplate (name.c_str (), attr);
1332 	if (view == nullptr)
1333 		view = description->createView (name.c_str (), description->getController ());
1334 	actionPerformer->onTemplateCreation (name.c_str (), view);
1335 }
1336 
1337 //----------------------------------------------------------------------------------------------------
undo()1338 void CreateNewTemplateAction::undo ()
1339 {
1340 	description->removeTemplate (name.c_str ());
1341 }
1342 
1343 //----------------------------------------------------------------------------------------------------
1344 //----------------------------------------------------------------------------------------------------
1345 //----------------------------------------------------------------------------------------------------
DuplicateTemplateAction(UIDescription * description,IActionPerformer * actionPerformer,UTF8StringPtr name,UTF8StringPtr dupName)1346 DuplicateTemplateAction::DuplicateTemplateAction (UIDescription* description, IActionPerformer* actionPerformer, UTF8StringPtr name, UTF8StringPtr dupName)
1347 : description (description)
1348 , actionPerformer (actionPerformer)
1349 , name (name)
1350 , dupName (dupName)
1351 {
1352 }
1353 
1354 //----------------------------------------------------------------------------------------------------
getName()1355 UTF8StringPtr DuplicateTemplateAction::getName ()
1356 {
1357 	return "Duplicate Template";
1358 }
1359 
1360 //----------------------------------------------------------------------------------------------------
perform()1361 void DuplicateTemplateAction::perform ()
1362 {
1363 	description->duplicateTemplate (name.c_str (), dupName.c_str ());
1364 	if (view == nullptr)
1365 		view = description->createView (dupName.c_str (), description->getController ());
1366 	actionPerformer->onTemplateCreation (dupName.c_str (), view);
1367 }
1368 
1369 //----------------------------------------------------------------------------------------------------
undo()1370 void DuplicateTemplateAction::undo ()
1371 {
1372 	description->removeTemplate (dupName.c_str ());
1373 }
1374 
1375 //----------------------------------------------------------------------------------------------------
1376 //----------------------------------------------------------------------------------------------------
1377 //----------------------------------------------------------------------------------------------------
DeleteTemplateAction(UIDescription * description,IActionPerformer * actionPerformer,CView * view,UTF8StringPtr name)1378 DeleteTemplateAction::DeleteTemplateAction (UIDescription* description, IActionPerformer* actionPerformer, CView* view, UTF8StringPtr name)
1379 : description (description)
1380 , actionPerformer (actionPerformer)
1381 , view (view)
1382 , name (name)
1383 {
1384 	attributes = const_cast<UIAttributes*> (description->getViewAttributes (name));
1385 }
1386 
1387 //----------------------------------------------------------------------------------------------------
getName()1388 UTF8StringPtr DeleteTemplateAction::getName ()
1389 {
1390 	return "Delete Template";
1391 }
1392 
1393 //----------------------------------------------------------------------------------------------------
perform()1394 void DeleteTemplateAction::perform ()
1395 {
1396 	attributes->remember ();
1397 	description->removeTemplate (name.c_str ());
1398 }
1399 
1400 //----------------------------------------------------------------------------------------------------
undo()1401 void DeleteTemplateAction::undo ()
1402 {
1403 	actionPerformer->onTemplateCreation (name.c_str (), view);
1404 	description->addNewTemplate (name.c_str (), attributes);
1405 }
1406 
1407 //----------------------------------------------------------------------------------------------------
1408 //----------------------------------------------------------------------------------------------------
1409 //----------------------------------------------------------------------------------------------------
ChangeFocusDrawingAction(UIDescription * description,const FocusDrawingSettings & newSettings)1410 ChangeFocusDrawingAction::ChangeFocusDrawingAction (UIDescription* description, const FocusDrawingSettings& newSettings)
1411 : description (description)
1412 , newSettings (newSettings)
1413 {
1414 	oldSettings = description->getFocusDrawingSettings ();
1415 }
1416 
1417 //----------------------------------------------------------------------------------------------------
getName()1418 UTF8StringPtr ChangeFocusDrawingAction::getName ()
1419 {
1420 	return "Change Focus Drawing Settings";
1421 }
1422 
1423 //----------------------------------------------------------------------------------------------------
perform()1424 void ChangeFocusDrawingAction::perform ()
1425 {
1426 	description->setFocusDrawingSettings (newSettings);
1427 }
1428 
1429 //----------------------------------------------------------------------------------------------------
undo()1430 void ChangeFocusDrawingAction::undo ()
1431 {
1432 	description->setFocusDrawingSettings (oldSettings);
1433 }
1434 
1435 //----------------------------------------------------------------------------------------------------
1436 //----------------------------------------------------------------------------------------------------
1437 //----------------------------------------------------------------------------------------------------
ChangeTemplateMinMaxAction(UIDescription * description,UTF8StringPtr templateName,CPoint minSize,CPoint maxSize)1438 ChangeTemplateMinMaxAction::ChangeTemplateMinMaxAction (UIDescription* description, UTF8StringPtr templateName, CPoint minSize, CPoint maxSize)
1439 : description (description)
1440 , templateName (templateName)
1441 , minSize (minSize)
1442 , maxSize (maxSize)
1443 {
1444 	if (auto attr = description->getViewAttributes (templateName))
1445 	{
1446 		CPoint p;
1447 		if (attr->getPointAttribute (kTemplateAttributeMinSize, p))
1448 			oldMinSize = p;
1449 		else
1450 			oldMinSize = {-1, -1};
1451 		if (attr->getPointAttribute (kTemplateAttributeMaxSize, p))
1452 			oldMaxSize = p;
1453 		else
1454 			oldMaxSize = {-1, -1};
1455 	}
1456 }
1457 
1458 //----------------------------------------------------------------------------------------------------
setMinMaxSize(CPoint minimum,CPoint maximum)1459 void ChangeTemplateMinMaxAction::setMinMaxSize (CPoint minimum, CPoint maximum)
1460 {
1461 	if (auto attr = const_cast<UIAttributes*> (description->getViewAttributes (templateName.data ())))
1462 	{
1463 		if (minimum.x == -1. && minimum.y == -1.)
1464 		{
1465 			attr->removeAttribute (kTemplateAttributeMinSize);
1466 		}
1467 		else
1468 		{
1469 			attr->setPointAttribute (kTemplateAttributeMinSize, minimum);
1470 		}
1471 		if (maximum.x == -1. && maximum.y == -1.)
1472 		{
1473 			attr->removeAttribute (kTemplateAttributeMaxSize);
1474 		}
1475 		else
1476 		{
1477 			attr->setPointAttribute (kTemplateAttributeMaxSize, maximum);
1478 		}
1479 	}
1480 
1481 }
1482 
1483 //----------------------------------------------------------------------------------------------------
getName()1484 UTF8StringPtr ChangeTemplateMinMaxAction::getName ()
1485 {
1486 	return "Change Template Min/Max Sizes";
1487 }
1488 
1489 //----------------------------------------------------------------------------------------------------
perform()1490 void ChangeTemplateMinMaxAction::perform ()
1491 {
1492 	setMinMaxSize (minSize, maxSize);
1493 }
1494 
1495 //----------------------------------------------------------------------------------------------------
undo()1496 void ChangeTemplateMinMaxAction::undo ()
1497 {
1498 	setMinMaxSize (oldMinSize, oldMaxSize);
1499 }
1500 
1501 //----------------------------------------------------------------------------------------------------
1502 } // namespace
1503 
1504 #endif // VSTGUI_LIVE_EDITING
1505