!B (Sandbox) (CE-21795) Importing models with multisubmaterials via fbx switches...
[CRYENGINE.git] / Code / Sandbox / Plugins / EditorSchematyc2 / Editor / DocGraphView.cpp
blob8d681f16309b85d889e871d6933bc8dc712c4c77
1 // Copyright 2001-2016 Crytek GmbH / Crytek Group. All rights reserved.
3 #include "StdAfx.h"
4 #include "DocGraphView.h"
6 #include <QBoxLayout>
7 #include <Util/QParentWndWidget.h>
8 #include <QPushButton>
9 #include <QSplitter>
10 #include <Serialization/QPropertyTree/QPropertyTree.h>
11 #include <CrySerialization/IArchiveHost.h>
12 #include <CrySystem/ITimer.h>
13 #include <CrySchematyc2/TypeInfo.h>
14 #include <CrySchematyc2/Env/IEnvRegistry.h>
15 #include <CrySchematyc2/Utils/CryLinkUtils.h>
16 #include <CrySchematyc2/Services/ILog.h>
18 #include "BrowserIcons.h"
19 #include "QuickSearchDlg.h"
20 #include "QMFCApp/QWinHost.h"
22 #include <Controls/EditorDialog.h>
23 #include <QAdvancedPropertyTree.h>
24 #include <QVBoxLayout>
26 namespace Schematyc2
28 class CPropertyTreeDlg : public CEditorDialog
30 public:
31 CPropertyTreeDlg(const QString& moduleName, const Serialization::SStruct& properties)
32 : CEditorDialog(moduleName)
34 QAdvancedPropertyTree* pPropertyTree = new QAdvancedPropertyTree("Properties Dialog", this);
35 pPropertyTree->attach(properties);
37 //---
39 QPushButton* okButton = new QPushButton(tr("Ok"), this);
40 okButton->setDefault(true);
41 connect(okButton, &QPushButton::clicked, [this]()
43 accept();
44 });
46 QPushButton* cancelButton = new QPushButton(tr("Cancel"), this);
47 connect(cancelButton, &QPushButton::clicked, [this]()
49 reject();
50 });
52 auto buttonsLayout = new QHBoxLayout();
53 buttonsLayout->addSpacerItem(new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Preferred));
54 buttonsLayout->addWidget(okButton);
55 buttonsLayout->addWidget(cancelButton);
57 //---
59 auto mainLayout = new QVBoxLayout();
60 mainLayout->addWidget(pPropertyTree);
61 mainLayout->addLayout(buttonsLayout);
62 setLayout(mainLayout);
66 namespace DocGraphViewUtils
68 static const struct { EScriptGraphNodeType scriptGraphNodeType; Gdiplus::Color color; } HEADER_COLORS[] =
70 { EScriptGraphNodeType::Begin, Gdiplus::Color(38, 184, 33) },
71 { EScriptGraphNodeType::BeginConstructor , Gdiplus::Color(38, 184, 33) },
72 { EScriptGraphNodeType::BeginSignalReceiver, Gdiplus::Color(38, 184, 33) },
73 { EScriptGraphNodeType::Return, Gdiplus::Color(38, 184, 33) },
74 { EScriptGraphNodeType::Branch, Gdiplus::Color(38, 184, 33) },
75 { EScriptGraphNodeType::Set, Gdiplus::Color(0, 108, 217) },
76 { EScriptGraphNodeType::Get, Gdiplus::Color(0, 108, 217) },
77 { EScriptGraphNodeType::SendSignal, Gdiplus::Color(38, 184, 33) },
78 { EScriptGraphNodeType::Function, Gdiplus::Color(215, 55, 55) },
79 { EScriptGraphNodeType::Condition, Gdiplus::Color(250, 232, 12) },
80 { EScriptGraphNodeType::AbstractInterfaceFunction, Gdiplus::Color(160, 160, 160) },
81 { EScriptGraphNodeType::StartTimer, Gdiplus::Color(38, 184, 33) },
82 { EScriptGraphNodeType::StopTimer, Gdiplus::Color(38, 184, 33) },
83 { EScriptGraphNodeType::ResetTimer, Gdiplus::Color(38, 184, 33) },
84 { EScriptGraphNodeType::State, Gdiplus::Color(0, 108, 217) },
85 { EScriptGraphNodeType::Comment, Gdiplus::Color(255, 255, 255) }
88 static const Gdiplus::Color DEFAULT_HEADER_COLOR = Gdiplus::Color(38, 184, 33);
90 inline Gdiplus::Color GetHeaderColor(EScriptGraphNodeType scriptGraphNodeType)
92 for(size_t headerColorIdx = 0; headerColorIdx < CRY_ARRAY_COUNT(HEADER_COLORS); ++ headerColorIdx)
94 if(HEADER_COLORS[headerColorIdx].scriptGraphNodeType == scriptGraphNodeType)
96 return HEADER_COLORS[headerColorIdx].color;
99 return DEFAULT_HEADER_COLOR;
102 static const struct { EScriptGraphColor color; Gdiplus::Color value; } s_colorValues[] =
104 { EScriptGraphColor::Red, Gdiplus::Color(215, 55, 55) },
105 { EScriptGraphColor::Green , Gdiplus::Color(38, 184, 33) },
106 { EScriptGraphColor::Blue, Gdiplus::Color(0, 108, 217) },
107 { EScriptGraphColor::Yellow, Gdiplus::Color(250, 232, 12) },
108 { EScriptGraphColor::Orange, Gdiplus::Color(255, 100, 15) },
109 { EScriptGraphColor::White, Gdiplus::Color(255, 255, 255) }
112 inline Gdiplus::Color GetColorValue(EScriptGraphColor color)
114 for(uint32 colorIdx = 0; colorIdx < CRY_ARRAY_COUNT(s_colorValues); ++ colorIdx)
116 if(s_colorValues[colorIdx].color == color)
118 return s_colorValues[colorIdx].value;
121 return Gdiplus::Color();
124 static const struct { EnvTypeId typeId; Gdiplus::Color color; } PORT_COLORS[] =
126 { GetEnvTypeId<bool>(), Gdiplus::Color(0, 108, 217) },
127 { GetEnvTypeId<int32>(), Gdiplus::Color(215, 55, 55) },
128 { GetEnvTypeId<uint32>(), Gdiplus::Color(215, 55, 55) },
129 { GetEnvTypeId<float>(), Gdiplus::Color(185, 185, 185) },
130 { GetEnvTypeId<Vec3>(), Gdiplus::Color(250, 232, 12) },
131 { GetEnvTypeId<SGUID>(), Gdiplus::Color(38, 184, 33) },
132 { GetEnvTypeId<CPoolString>(), Gdiplus::Color(128, 100, 162) },
133 { GetEnvTypeId<ExplicitEntityId>(), Gdiplus::Color(215, 55, 55) }
136 static const Gdiplus::Color DEFAULT_PORT_COLOR = Gdiplus::Color(28, 212, 22);
138 inline Gdiplus::Color GetPortColor(const EnvTypeId& typeId)
140 for(size_t iPortColor = 0; iPortColor < CRY_ARRAY_COUNT(PORT_COLORS); ++ iPortColor)
142 if(PORT_COLORS[iPortColor].typeId == typeId)
144 return PORT_COLORS[iPortColor].color;
147 return DEFAULT_PORT_COLOR;
150 struct SAnyWrapper
152 inline SAnyWrapper(const IAnyPtr& _pValue)
153 : pValue(_pValue)
156 void Serialize(Serialization::IArchive& archive)
158 archive(*pValue, "value", "Value");
161 IAnyPtr pValue;
164 struct SOptionalNodeOutput
166 inline SOptionalNodeOutput()
167 : flags(EScriptGraphPortFlags::None)
170 inline SOptionalNodeOutput(const char* _szName, const char* _szFullName, EScriptGraphPortFlags _flags, const CAggregateTypeId& _typeId)
171 : name(_szName)
172 , fullName(_szFullName)
173 , flags(_flags)
174 , typeId(_typeId)
177 string name;
178 string fullName;
179 EScriptGraphPortFlags flags;
180 CAggregateTypeId typeId;
183 typedef std::vector<SOptionalNodeOutput> OptionalNodeOutputs;
185 class COptionalNodeOutputQuickSearchOptions : public Schematyc2::IQuickSearchOptions
187 public:
189 inline COptionalNodeOutputQuickSearchOptions(IScriptGraphNode& scriptGraphNode)
191 m_optionalNodeOutputs.reserve(256);
192 scriptGraphNode.EnumerateOptionalOutputs(ScriptGraphNodeOptionalOutputEnumerator::FromMemberFunction<COptionalNodeOutputQuickSearchOptions, &COptionalNodeOutputQuickSearchOptions::EnumerateOptionalNodeOutput>(*this));
195 // IQuickSearchOptions
197 virtual const char* GetToken() const override
199 return "::";
202 virtual size_t GetCount() const override
204 return m_optionalNodeOutputs.size();
207 virtual const char* GetLabel(size_t iOption) const override
209 return iOption < m_optionalNodeOutputs.size() ? m_optionalNodeOutputs[iOption].fullName.c_str() : "";
212 virtual const char* GetDescription(size_t iOption) const override
214 return nullptr;
217 virtual const char* GetWikiLink(size_t iOption) const override
219 return nullptr;
222 // ~IQuickSearchOptions
224 inline const SOptionalNodeOutput* GetOptionalNodeOutput(size_t iOptionalNodeOutput) const
226 return iOptionalNodeOutput < m_optionalNodeOutputs.size() ? &m_optionalNodeOutputs[iOptionalNodeOutput] : nullptr;
229 private:
231 void EnumerateOptionalNodeOutput(const char* szName, const char* szFullName, EScriptGraphPortFlags flags, const CAggregateTypeId& typeId)
233 m_optionalNodeOutputs.push_back(SOptionalNodeOutput(szName, szFullName, flags, typeId));
236 OptionalNodeOutputs m_optionalNodeOutputs;
239 inline bool AddOptionalNodeOutput(CWnd* pWnd, CPoint point, IScriptGraphNode& scriptGraphNode)
241 SET_LOCAL_RESOURCE_SCOPE
243 COptionalNodeOutputQuickSearchOptions quickSearchOptions(scriptGraphNode);
244 CQuickSearchDlg quickSearchDlg(pWnd, point, "Output", nullptr, nullptr, quickSearchOptions);
245 if(quickSearchDlg.DoModal() == IDOK)
247 const SOptionalNodeOutput* pOptionalNodeOutput = quickSearchOptions.GetOptionalNodeOutput(quickSearchDlg.GetResult());
248 SCHEMATYC2_SYSTEM_ASSERT(pOptionalNodeOutput);
249 if(pOptionalNodeOutput)
251 scriptGraphNode.AddOptionalOutput(pOptionalNodeOutput->name.c_str(), pOptionalNodeOutput->flags, pOptionalNodeOutput->typeId);
252 return true;
255 return false;
258 static const float s_dragAndDropOffset = 10.0f;
261 CDocGraphViewNode::CDocGraphViewNode(const SGraphViewGrid& grid, Gdiplus::PointF pos, TScriptFile& scriptFile, IScriptGraph& scriptGraph, IScriptGraphNode& scriptGraphNode)
262 : CGraphViewNode(grid, pos)
263 , m_scriptFile(scriptFile)
264 , m_scriptGraph(scriptGraph)
265 , m_scriptGraphNode(scriptGraphNode)
268 const char* CDocGraphViewNode::GetName() const
270 return m_scriptGraphNode.GetName();
273 const char* CDocGraphViewNode::GetContents() const
275 return m_scriptGraphNode.GetComment();
278 Gdiplus::Color CDocGraphViewNode::GetHeaderColor() const
280 // Workaround for old nodes where color derived from type.
281 if(m_scriptGraphNode.GetColor() == EScriptGraphColor::NotSet)
283 return DocGraphViewUtils::GetHeaderColor(m_scriptGraphNode.GetType());
285 return DocGraphViewUtils::GetColorValue(m_scriptGraphNode.GetColor());
288 size_t CDocGraphViewNode::GetInputCount() const
290 return m_scriptGraphNode.GetInputCount();
293 size_t CDocGraphViewNode::FindInput(const char* szName) const
295 return DocUtils::FindGraphNodeInput(m_scriptGraphNode, szName);
298 const char* CDocGraphViewNode::GetInputName(size_t inputIdx) const
300 return m_scriptGraphNode.GetInputName(inputIdx);
303 EScriptGraphPortFlags CDocGraphViewNode::GetInputFlags(size_t inputIdx) const
305 return m_scriptGraphNode.GetInputFlags(inputIdx);
308 Gdiplus::Color CDocGraphViewNode::GetInputColor(size_t inputIdx) const
310 return DocGraphViewUtils::GetPortColor(GetInputTypeId(inputIdx).AsEnvTypeId());
313 size_t CDocGraphViewNode::GetOutputCount() const
315 return m_scriptGraphNode.GetOutputCount();
318 size_t CDocGraphViewNode::FindOutput(const char* szName) const
320 return DocUtils::FindGraphNodeOutput(m_scriptGraphNode, szName);
323 const char* CDocGraphViewNode::GetOutputName(size_t outputIdx) const
325 return m_scriptGraphNode.GetOutputName(outputIdx);
328 EScriptGraphPortFlags CDocGraphViewNode::GetOutputFlags(size_t outputIdx) const
330 return m_scriptGraphNode.GetOutputFlags(outputIdx);
333 Gdiplus::Color CDocGraphViewNode::GetOutputColor(size_t outputIdx) const
335 return DocGraphViewUtils::GetPortColor(GetOutputTypeId(outputIdx).AsEnvTypeId());
338 IScriptGraphNode& CDocGraphViewNode::GetScriptGraphNode()
340 return m_scriptGraphNode;
343 EScriptGraphNodeType CDocGraphViewNode::GetType() const
345 return m_scriptGraphNode.GetType();
348 SGUID CDocGraphViewNode::GetGUID() const
350 return m_scriptGraphNode.GetGUID();
353 SGUID CDocGraphViewNode::GetRefGUID() const
355 return m_scriptGraphNode.GetRefGUID();
358 SGUID CDocGraphViewNode::GetGraphGUID() const
360 return m_scriptGraph.GetType() == EScriptGraphType::Transition ? m_scriptGraph.GetElement_New().GetScopeGUID() : m_scriptGraph.GetElement_New().GetGUID();
363 CAggregateTypeId CDocGraphViewNode::GetInputTypeId(size_t inputIdx) const
365 return m_scriptGraphNode.GetInputTypeId(inputIdx);
368 CAggregateTypeId CDocGraphViewNode::GetOutputTypeId(size_t outputIdx) const
370 return m_scriptGraphNode.GetOutputTypeId(outputIdx);
373 void CDocGraphViewNode::Serialize(Serialization::IArchive& archive)
375 m_scriptGraphNode.Serialize(archive);
378 void CDocGraphViewNode::OnMove(Gdiplus::RectF paintRect)
380 m_scriptGraphNode.SetPos(Vec2(paintRect.X, paintRect.Y));
383 SDocGraphViewSelection::SDocGraphViewSelection(const CDocGraphViewNodePtr& _pNode, SGraphViewLink* _pLink)
384 : pNode(_pNode)
385 , pLink(_pLink)
388 BEGIN_MESSAGE_MAP(CDocGraphView, CGraphView)
389 END_MESSAGE_MAP()
391 CDocGraphView::CDocGraphView()
392 : CGraphView(SGraphViewGrid(Gdiplus::PointF(10.0f, 10.0f), Gdiplus::RectF(-5000.0f, -5000.0f, 10000.0f, 10000.0f)))
393 , m_pScriptFile(nullptr)
394 , m_pScriptGraph(nullptr)
395 , m_bRemovingLinks(false)
397 CGraphView::Enable(false);
400 void CDocGraphView::Refresh()
402 if(m_pScriptGraph)
404 if(m_pScriptGraph->GetType() == EScriptGraphType::Property)
406 static_cast<IScriptGraphExtension*>(m_pScriptGraph)->Refresh_New(SScriptRefreshParams(EScriptRefreshReason::EditorSelect)); // #SchematycTODO : Once all graphs are implemented as script extensions we can remove this cast!
408 else
410 m_pScriptGraph->GetElement_New().Refresh(SScriptRefreshParams(EScriptRefreshReason::EditorSelect));
413 CGraphView::Refresh();
416 void CDocGraphView::Load(TScriptFile* pScriptFile, IScriptGraph* pScriptGraph)
418 if(m_pScriptGraph)
420 m_connectionScope.Release();
421 CGraphView::Clear();
423 m_pScriptFile = pScriptFile;
424 m_pScriptGraph = pScriptGraph;
425 if(m_pScriptFile && m_pScriptGraph)
427 CGraphView::Enable(true);
428 const Vec2 pos = m_pScriptGraph->GetPos();
429 CGraphView::SetScrollOffset(Gdiplus::PointF(pos.x, pos.y));
430 if(m_pScriptGraph->GetType() == EScriptGraphType::Property)
432 static_cast<IScriptGraphExtension*>(m_pScriptGraph)->Refresh_New(SScriptRefreshParams(EScriptRefreshReason::EditorSelect)); // #SchematycTODO : Once all graphs are implemented as script extensions we can remove this cast!
434 else
436 m_pScriptGraph->GetElement_New().Refresh(SScriptRefreshParams(EScriptRefreshReason::EditorSelect));
438 m_pScriptGraph->VisitNodes(ScriptGraphNodeVisitor::FromMemberFunction<CDocGraphView, &CDocGraphView::VisitGraphNode>(*this));
439 for(size_t iLink = 0, linkCount = m_pScriptGraph->GetLinkCount(); iLink < linkCount; )
441 if(AddLink(*m_pScriptGraph->GetLink(iLink)))
443 ++ iLink;
445 else
447 // #SchematycTODO : May make more sense to strip out broken links when loading the script file.
448 SCHEMATYC2_SYSTEM_WARNING("Removing broken link from graph : %s::%s", pScriptFile->GetFileName(), pScriptGraph->GetElement_New().GetName());
449 m_bRemovingLinks = true;
450 m_pScriptGraph->RemoveLink(iLink);
451 m_bRemovingLinks = false;
452 -- linkCount;
455 m_pScriptGraph->Signals().linkRemoved.Connect(ScriptGraphLinkRemovedSignal::Delegate::FromMemberFunction<CDocGraphView, &CDocGraphView::OnDocLinkRemoved>(*this), m_connectionScope);
457 else
459 CGraphView::Enable(false);
461 UnrollSequence();
462 __super::Invalidate(TRUE);
465 TScriptFile* CDocGraphView::GetScriptFile() const
467 return m_pScriptFile;
470 IScriptGraph* CDocGraphView::GetScriptGraph() const
472 return m_pScriptGraph;
475 void CDocGraphView::SelectAndFocusNode(const SGUID& nodeGuid)
477 if(nodeGuid)
479 CGraphViewNodePtr pNode = GetNode(nodeGuid);
480 if(pNode)
482 SelectNode(pNode);
483 Gdiplus::RectF rect = pNode->GetPaintRect();
484 Gdiplus::PointF pos(rect.X + (rect.Width / 2), rect.Y + (rect.Height / 2));
485 CenterPosition(pos);
490 SDocGraphViewSignals& CDocGraphView::Signals()
492 return m_signals;
495 void CDocGraphView::OnMove(Gdiplus::PointF scrollOffset)
497 if(m_pScriptGraph)
499 m_pScriptGraph->SetPos(Vec2(scrollOffset.X, scrollOffset.Y));
503 void CDocGraphView::OnSelection(const CGraphViewNodePtr& pSelectedNode, SGraphViewLink* pSelectedLink)
505 m_signals.selection.Send(SDocGraphViewSelection(std::static_pointer_cast<CDocGraphViewNode>(pSelectedNode), pSelectedLink));
508 void CDocGraphView::OnUpArrowPressed()
510 m_signals.gotoSelection.Send();
513 void CDocGraphView::OnDownArrowPressed()
515 m_signals.goBackFromSelection.Send();
518 void CDocGraphView::OnLinkModify(const SGraphViewLink& link) {}
520 void CDocGraphView::OnNodeRemoved(const CGraphViewNode& node)
522 CRY_ASSERT(m_pScriptFile && m_pScriptGraph);
523 if(m_pScriptFile && m_pScriptGraph)
525 m_pScriptGraph->RemoveNode(static_cast<const CDocGraphViewNode&>(node).GetGUID());
526 InvalidateDoc();
530 bool CDocGraphView::CanCreateLink(const CGraphViewNode& srcNode, const char* szSrcOutputName, const CGraphViewNode& dstNode, const char* szDstInputName) const
532 CRY_ASSERT(szSrcOutputName && szDstInputName && m_pScriptGraph);
533 if(szSrcOutputName && szDstInputName && m_pScriptGraph)
535 const CDocGraphViewNode& srcNodeImpl = static_cast<const CDocGraphViewNode&>(srcNode);
536 const CDocGraphViewNode& dstNodeImpl = static_cast<const CDocGraphViewNode&>(dstNode);
537 return m_pScriptGraph->CanAddLink(srcNodeImpl.GetGUID(), szSrcOutputName, dstNodeImpl.GetGUID(), szDstInputName);
539 return false;
542 void CDocGraphView::OnLinkCreated(const SGraphViewLink& link)
544 CRY_ASSERT(m_pScriptFile && m_pScriptGraph);
545 if(m_pScriptFile && m_pScriptGraph)
547 CDocGraphViewNodePtr pSrcNode = std::static_pointer_cast<CDocGraphViewNode>(link.pSrcNode.lock());
548 CDocGraphViewNodePtr pDstNode = std::static_pointer_cast<CDocGraphViewNode>(link.pDstNode.lock());
549 CRY_ASSERT(pSrcNode && pDstNode);
550 if(pSrcNode && pDstNode)
552 m_pScriptGraph->AddLink(pSrcNode->GetGUID(), link.srcOutputName.c_str(), pDstNode->GetGUID(), link.dstInputName.c_str());
553 InvalidateDoc();
558 void CDocGraphView::OnLinkRemoved(const SGraphViewLink& link)
560 if(!m_bRemovingLinks)
562 CRY_ASSERT(m_pScriptFile && m_pScriptGraph);
563 if(m_pScriptFile && m_pScriptGraph)
565 CDocGraphViewNodePtr pSrcNode = std::static_pointer_cast<CDocGraphViewNode>(link.pSrcNode.lock());
566 CDocGraphViewNodePtr pDstNode = std::static_pointer_cast<CDocGraphViewNode>(link.pDstNode.lock());
567 CRY_ASSERT(pSrcNode && pDstNode);
568 if(pSrcNode && pDstNode)
570 const size_t linkIdx = m_pScriptGraph->FindLink(pSrcNode->GetGUID(), link.srcOutputName.c_str(), pDstNode->GetGUID(), link.dstInputName.c_str());
571 if(linkIdx != INVALID_INDEX)
573 m_bRemovingLinks = true;
574 m_pScriptGraph->RemoveLink(linkIdx);
575 m_bRemovingLinks = false;
576 InvalidateDoc();
583 DROPEFFECT CDocGraphView::OnDragOver(CWnd* pWnd, COleDataObject* pDataObject, DWORD dwKeyState, CPoint point)
585 if(m_pScriptFile && m_pScriptGraph)
587 PluginUtils::SDragAndDropData dragAndDropData;
588 if(PluginUtils::GetDragAndDropData(pDataObject, dragAndDropData))
590 switch(dragAndDropData.icon)
592 case BrowserIcon::BRANCH:
594 if(CanAddNode(EScriptGraphNodeType::Branch))
596 return DROPEFFECT_MOVE;
598 break;
600 case BrowserIcon::FOR_LOOP:
602 if(CanAddNode(EScriptGraphNodeType::ForLoop))
604 return DROPEFFECT_MOVE;
606 break;
608 case BrowserIcon::RETURN:
610 if(CanAddNode(EScriptGraphNodeType::Return))
612 return DROPEFFECT_MOVE;
614 break;
616 default:
618 if(CanAddNode(dragAndDropData.guid))
620 return DROPEFFECT_MOVE;
622 break;
627 return DROPEFFECT_NONE;
630 BOOL CDocGraphView::OnDrop(CWnd* pWnd, COleDataObject* pDataObject, DROPEFFECT dropEffect, CPoint point)
632 if(m_pScriptFile && m_pScriptGraph)
634 PluginUtils::SDragAndDropData dragAndDropData;
635 if(PluginUtils::GetDragAndDropData(pDataObject, dragAndDropData))
637 const Gdiplus::PointF graphPos = CGraphView::ClientToGraph(Gdiplus::PointF(static_cast<float>(point.x), static_cast<float>(point.y)));
638 switch(dragAndDropData.icon)
640 case BrowserIcon::BRANCH:
642 AddNode(EScriptGraphNodeType::Branch, SGUID(), SGUID(), Gdiplus::PointF(graphPos.X - DocGraphViewUtils::s_dragAndDropOffset, graphPos.Y - DocGraphViewUtils::s_dragAndDropOffset));
643 InvalidateDoc();
644 return true;
646 case BrowserIcon::FOR_LOOP:
648 AddNode(EScriptGraphNodeType::ForLoop, SGUID(), SGUID(), Gdiplus::PointF(graphPos.X - DocGraphViewUtils::s_dragAndDropOffset, graphPos.Y - DocGraphViewUtils::s_dragAndDropOffset));
649 InvalidateDoc();
650 return true;
652 case BrowserIcon::RETURN:
654 AddNode(EScriptGraphNodeType::Return, SGUID(), SGUID(), Gdiplus::PointF(graphPos.X - DocGraphViewUtils::s_dragAndDropOffset, graphPos.Y - DocGraphViewUtils::s_dragAndDropOffset));
655 InvalidateDoc();
656 return true;
658 default:
660 if(m_pScriptGraph->GetType() == EScriptGraphType::Property)
663 else
665 TSizeTVector availableNodes;
666 m_pScriptGraph->RefreshAvailableNodes(CAggregateTypeId());
667 for(size_t iAvalailableNode = 0, availableNodeCount = m_pScriptGraph->GetAvailableNodeCount(); iAvalailableNode < availableNodeCount; ++ iAvalailableNode)
669 if(m_pScriptGraph->GetAvailableNodeRefGUID(iAvalailableNode) == dragAndDropData.guid)
671 availableNodes.push_back(iAvalailableNode);
674 if(!availableNodes.empty())
676 int nodeSelection = availableNodes.front() + 1;
677 if(availableNodes.size() > 1)
679 CMenu popupMenu;
680 popupMenu.CreatePopupMenu();
681 for(TSizeTVector::const_iterator iAvailableNode = availableNodes.begin(), iEndAvailableNode = availableNodes.end(); iAvailableNode != iEndAvailableNode; ++ iAvailableNode)
683 popupMenu.AppendMenu(MF_STRING, *iAvailableNode + 1, m_pScriptGraph->GetAvailableNodeName(*iAvailableNode));
685 CPoint cursorPos;
686 GetCursorPos(&cursorPos);
687 nodeSelection = popupMenu.TrackPopupMenuEx(TPM_RETURNCMD, cursorPos.x, cursorPos.y, this, NULL);
689 if(nodeSelection > 0)
691 AddNode(m_pScriptGraph->GetAvailableNodeType(nodeSelection - 1), SGUID(), dragAndDropData.guid, Gdiplus::PointF(graphPos.X - DocGraphViewUtils::s_dragAndDropOffset, graphPos.Y - DocGraphViewUtils::s_dragAndDropOffset));
692 InvalidateDoc();
693 return true;
697 break;
702 return false;
705 void CDocGraphView::GetPopupMenuItems(CMenu& popupMenu, const CGraphViewNodePtr& pNode, size_t nodeInputIdx, size_t nodeOutputIdx, CPoint point)
707 if(pNode)
709 CDocGraphViewNodePtr pNodeImpl = std::static_pointer_cast<CDocGraphViewNode>(pNode);
710 IScriptGraphNode& scriptGraphNode = pNodeImpl->GetScriptGraphNode();
712 EScriptGraphNodeType nodeType = scriptGraphNode.GetType();
713 if (nodeType == EScriptGraphNodeType::State && nodeOutputIdx != INVALID_INDEX)
715 stack_string gotoLabel;
716 gotoLabel.Format("Goto %s", pNodeImpl->GetOutputName(nodeOutputIdx));
717 popupMenu.AppendMenu(MF_STRING, EPopupMenuItemEx::DEFINITION, gotoLabel.c_str());
718 popupMenu.AppendMenu(MF_STRING, EPopupMenuItemEx::REFERENCES, "Find references");
721 if (Schematyc2::NodeUtils::CanGoToNodeType(nodeType))
723 popupMenu.AppendMenu(MF_STRING, EPopupMenuItemEx::REFERENCES, "Find references");
724 popupMenu.AppendMenu(MF_MENUBARBREAK);
727 popupMenu.AppendMenu(MF_STRING, EPopupMenuItemEx::ADD_OUTPUT, "Add Output"); // #SchematycTODO : Check for custom/optional outputs first?
728 if(nodeOutputIdx != INVALID_INDEX)
730 if((scriptGraphNode.GetOutputFlags(nodeOutputIdx) & EScriptGraphPortFlags::Removable) != 0)
732 popupMenu.AppendMenu(MF_STRING, EPopupMenuItemEx::REMOVE_OUTPUT, "Remove Output");
736 CGraphView::GetPopupMenuItems(popupMenu, pNode, nodeInputIdx, nodeOutputIdx, point);
739 void CDocGraphView::OnPopupMenuResult(BOOL popupMenuItem, const CGraphViewNodePtr& pNode, size_t nodeInputIdx, size_t nodeOutputIdx, CPoint point)
741 if(m_pScriptFile)
743 switch(popupMenuItem)
745 case EPopupMenuItemEx::ADD_OUTPUT:
747 CRY_ASSERT(pNode);
748 if(pNode)
750 SET_LOCAL_RESOURCE_SCOPE
752 IScriptGraphNode& scriptGraphNode = std::static_pointer_cast<CDocGraphViewNode>(pNode)->GetScriptGraphNode();
753 if(IAnyConstPtr pCustomOutputDefault = scriptGraphNode.GetCustomOutputDefault())
755 DocGraphViewUtils::SAnyWrapper wrapper(pCustomOutputDefault->Clone());
756 CPropertyTreeDlg propertyTreeDlg("Add Graph Node Output", Serialization::SStruct(wrapper));
757 if(propertyTreeDlg.exec())
759 scriptGraphNode.AddCustomOutput(*wrapper.pValue);
762 else
764 DocGraphViewUtils::AddOptionalNodeOutput(this, point, scriptGraphNode);
766 m_signals.modification.Send(*m_pScriptFile);
767 __super::Invalidate(TRUE);
769 break;
771 case EPopupMenuItemEx::REMOVE_OUTPUT:
773 CRY_ASSERT(pNode);
774 if(pNode)
776 CDocGraphViewNodePtr pNodeImpl = std::static_pointer_cast<CDocGraphViewNode>(pNode);
777 string message = "Remove node output named '";
778 message.append(pNodeImpl->GetOutputName(nodeOutputIdx));
779 message.append("'?");
780 if (::MessageBoxA(CView::GetSafeHwnd(), message.c_str(), "Remove Node Output", 1) == IDOK)
782 CGraphView::RemoveLinksConnectedToNodeOutput(pNode, pNode->GetOutputName(nodeOutputIdx));
783 pNodeImpl->GetScriptGraphNode().RemoveOutput(nodeOutputIdx);
784 m_signals.modification.Send(*m_pScriptFile);
785 __super::Invalidate(TRUE);
788 break;
790 case EPopupMenuItemEx::REFERENCES:
792 if (pNode)
794 CDocGraphViewNodePtr pNodeImpl = std::static_pointer_cast<CDocGraphViewNode>(pNode);
795 const TScriptFile& file = pNodeImpl->GetScriptFile();
797 SGUID refGuid = pNodeImpl->GetRefGUID();
798 SGUID refGoBack = pNodeImpl->GetGraphGUID();
800 stack_string name = pNodeImpl->GetName();
802 if (pNodeImpl->GetType() == EScriptGraphNodeType::State && nodeOutputIdx != INVALID_INDEX)
804 refGuid = pNodeImpl->GetOutputTypeId(nodeOutputIdx).AsScriptTypeGUID();
805 name = pNodeImpl->GetOutputName(nodeOutputIdx);
808 stack_string::size_type pos = name.rfind(' ');
809 if (pos != stack_string::npos)
811 name = name.substr(pos);
814 Schematyc2::LibUtils::FindAndLogReferences(refGuid, refGoBack, name.c_str(), &file);
816 break;
818 case EPopupMenuItemEx::DEFINITION:
820 if (pNode)
822 CDocGraphViewNodePtr pNodeImpl = std::static_pointer_cast<CDocGraphViewNode>(pNode);
823 if (pNodeImpl->GetType() == EScriptGraphNodeType::State && nodeOutputIdx != INVALID_INDEX)
825 SGUID refGuid = pNodeImpl->GetOutputTypeId(nodeOutputIdx).AsScriptTypeGUID();
826 SGUID refGoBack = pNodeImpl->GetGraphGUID();
827 m_signals.gotoSelectionChanged.Send(SGotoSelection(refGuid, refGoBack));
828 m_signals.gotoSelection.Send();
832 default:
834 CGraphView::OnPopupMenuResult(popupMenuItem, pNode, nodeInputIdx, nodeOutputIdx, point);
835 break;
841 const IQuickSearchOptions* CDocGraphView::GetQuickSearchOptions(CPoint point, const CGraphViewNodePtr& pNode, size_t nodeOutputIdx)
843 if(m_pScriptFile && m_pScriptGraph)
845 CDocGraphViewNodePtr pNodeImpl = std::static_pointer_cast<CDocGraphViewNode>(pNode);
846 m_quickSearchOptions.Refresh(*m_pScriptGraph, pNode ? pNodeImpl->GetOutputTypeId(nodeOutputIdx) : CAggregateTypeId());
847 return &m_quickSearchOptions;
849 return NULL;
852 void CDocGraphView::OnQuickSearchResult(CPoint point, const CGraphViewNodePtr& pNode, size_t nodeOutputIdx, size_t optionIdx)
854 CRY_ASSERT(m_pScriptFile && (optionIdx < m_quickSearchOptions.GetCount()));
855 if(m_pScriptFile && m_pScriptGraph && (optionIdx < m_quickSearchOptions.GetCount()))
857 CGraphView::ScreenToClient(&point);
858 const Gdiplus::PointF nodePos = CGraphView::ClientToGraph(point.x, point.y);
859 CDocGraphViewNodePtr pNewNode;
860 if(m_pScriptGraph->GetType() == EScriptGraphType::Property)
862 IScriptGraphNodePtr pScriptGraphNode = m_quickSearchOptions.ExecuteCommand(optionIdx, Vec2(nodePos.X, nodePos.Y)); // #SchematycTODO : Once all graphs are implemented as script extensions we can remove this cast!
863 if(pScriptGraphNode)
865 static_cast<IScriptGraphExtension*>(m_pScriptGraph)->AddNode_New(pScriptGraphNode);
866 pScriptGraphNode->Refresh(SScriptRefreshParams(EScriptRefreshReason::EditorAdd));
867 pNewNode = AddNode(*pScriptGraphNode);
870 else
872 pNewNode = AddNode(m_quickSearchOptions.GetNodeType(optionIdx), m_quickSearchOptions.GetNodeContextGUID(optionIdx), m_quickSearchOptions.GetNodeRefGUID(optionIdx), nodePos);
874 if(pNewNode)
876 if(pNode && (nodeOutputIdx != INVALID_INDEX))
878 const EScriptGraphPortFlags outputFlags = pNode->GetOutputFlags(nodeOutputIdx);
879 const CAggregateTypeId outputTypeId = std::static_pointer_cast<CDocGraphViewNode>(pNode)->GetOutputTypeId(nodeOutputIdx);
880 for(size_t nodeInputIdx = 0, nodeInputCount = pNewNode->GetInputCount(); nodeInputIdx < nodeInputCount; ++ nodeInputIdx)
882 const EScriptGraphPortFlags inputFlags = pNewNode->GetInputFlags(nodeInputIdx);
883 const CAggregateTypeId inputTypeId = pNewNode->GetInputTypeId(nodeInputIdx);
884 if((((inputFlags & EScriptGraphPortFlags::Execute) != 0) && ((outputFlags & EScriptGraphPortFlags::Execute) != 0)) || (inputTypeId == outputTypeId))
886 CGraphView::CreateLink(pNode, pNode->GetOutputName(nodeOutputIdx), pNewNode, pNewNode->GetInputName(nodeInputIdx));
887 break;
891 InvalidateDoc();
896 const char* CDocGraphView::CQuickSearchOptions::GetToken() const
898 return "::";
901 size_t CDocGraphView::CQuickSearchOptions::GetCount() const
903 return m_options.size();
906 const char* CDocGraphView::CQuickSearchOptions::GetLabel(size_t optionIdx) const
908 return optionIdx < m_options.size() ? m_options[optionIdx].label.c_str() : "";
911 const char* CDocGraphView::CQuickSearchOptions::GetDescription(size_t optionIdx) const
913 return optionIdx < m_options.size() ? m_options[optionIdx].description.c_str() : "";
916 const char* CDocGraphView::CQuickSearchOptions::GetWikiLink(size_t optionIdx) const
918 return optionIdx < m_options.size() ? m_options[optionIdx].wikiLink.c_str() : "";
921 bool CDocGraphView::CQuickSearchOptions::AddOption(const char* szLabel, const char* szDescription, const char* szWikiLink, const IScriptGraphNodeCreationMenuCommandPtr& pCommand)
923 // #SchematycTODO : Check for duplicate options?
924 m_options.push_back(SOption(szLabel, szDescription, szWikiLink, pCommand));
925 return true;
928 void CDocGraphView::CQuickSearchOptions::Refresh(IScriptGraph& scriptGraph, const CAggregateTypeId& inputTypeId)
930 m_options.clear();
931 if(scriptGraph.GetType() == EScriptGraphType::Property)
933 static_cast<IScriptGraphExtension&>(scriptGraph).PopulateNodeCreationMenu(*this); // #SchematycTODO : Once all graphs are implemented as script extensions we can remove this cast!
935 else
937 scriptGraph.RefreshAvailableNodes(inputTypeId);
938 for(size_t avalailableNodeIdx = 0, availableNodeCount = scriptGraph.GetAvailableNodeCount(); avalailableNodeIdx < availableNodeCount; ++ avalailableNodeIdx)
940 m_options.push_back(SOption(scriptGraph.GetAvailableNodeName(avalailableNodeIdx), scriptGraph.GetAvailableNodeType(avalailableNodeIdx), scriptGraph.GetAvailableNodeContextGUID(avalailableNodeIdx), scriptGraph.GetAvailableNodeRefGUID(avalailableNodeIdx)));
945 EScriptGraphNodeType CDocGraphView::CQuickSearchOptions::GetNodeType(size_t iOption) const
947 return iOption < m_options.size() ? m_options[iOption].nodeType : EScriptGraphNodeType::Unknown;
950 SGUID CDocGraphView::CQuickSearchOptions::GetNodeContextGUID(size_t iOption) const
952 return iOption < m_options.size() ? m_options[iOption].nodeContextGUID : SGUID();
955 SGUID CDocGraphView::CQuickSearchOptions::GetNodeRefGUID(size_t iOption) const
957 return iOption < m_options.size() ? m_options[iOption].nodeRefGUID : SGUID();
960 IScriptGraphNodePtr CDocGraphView::CQuickSearchOptions::ExecuteCommand(size_t optionIdx, const Vec2& pos)
962 if(optionIdx < m_options.size())
964 IScriptGraphNodeCreationMenuCommandPtr& pCommand = m_options[optionIdx].pCommand;
965 if(pCommand)
967 return pCommand->Execute(pos);
970 return IScriptGraphNodePtr();
973 CDocGraphView::CQuickSearchOptions::SOption::SOption(const char* _szLabel, EScriptGraphNodeType _nodeType, const SGUID& _nodeContextGUID, const SGUID& _nodeRefGUID)
974 : label(_szLabel)
975 , nodeType(_nodeType)
976 , nodeContextGUID(_nodeContextGUID)
977 , nodeRefGUID(_nodeRefGUID)
980 CDocGraphView::CQuickSearchOptions::SOption::SOption(const char* _szLabel, const char* _szDescription, const char* _szWikiLink, const IScriptGraphNodeCreationMenuCommandPtr& _pCommand)
981 : label(_szLabel)
982 , description(_szDescription)
983 , wikiLink(_szWikiLink)
984 , pCommand(_pCommand)
987 EVisitStatus CDocGraphView::VisitGraphNode(IScriptGraphNode& graphNode)
989 AddNode(graphNode);
990 return EVisitStatus::Continue;
993 bool CDocGraphView::CanAddNode(EScriptGraphNodeType type) const
995 CRY_ASSERT(m_pScriptGraph);
996 if(m_pScriptGraph)
998 m_pScriptGraph->RefreshAvailableNodes(CAggregateTypeId());
999 for(size_t avalailableNodeIdx = 0, availableNodeCount = m_pScriptGraph->GetAvailableNodeCount(); avalailableNodeIdx < availableNodeCount; ++ avalailableNodeIdx)
1001 if(m_pScriptGraph->GetAvailableNodeType(avalailableNodeIdx) == type)
1003 return true;
1007 return false;
1010 bool CDocGraphView::CanAddNode(const SGUID& refGUID) const
1012 CRY_ASSERT(m_pScriptGraph);
1013 if(m_pScriptGraph)
1015 m_pScriptGraph->RefreshAvailableNodes(CAggregateTypeId());
1016 for(size_t avalailableNodeIdx = 0, availableNodeCount = m_pScriptGraph->GetAvailableNodeCount(); avalailableNodeIdx < availableNodeCount; ++ avalailableNodeIdx)
1018 if(m_pScriptGraph->GetAvailableNodeRefGUID(avalailableNodeIdx) == refGUID)
1020 return true;
1024 return false;
1027 bool CDocGraphView::CanAddNode(EScriptGraphNodeType type, const SGUID& refGUID) const
1029 CRY_ASSERT(m_pScriptGraph);
1030 if(m_pScriptGraph)
1032 m_pScriptGraph->RefreshAvailableNodes(CAggregateTypeId());
1033 for(size_t iAvalailableNode = 0, availableNodeCount = m_pScriptGraph->GetAvailableNodeCount(); iAvalailableNode < availableNodeCount; ++ iAvalailableNode)
1035 if((m_pScriptGraph->GetAvailableNodeType(iAvalailableNode) == type) && (m_pScriptGraph->GetAvailableNodeRefGUID(iAvalailableNode) == refGUID))
1037 return true;
1041 return false;
1044 CDocGraphViewNodePtr CDocGraphView::AddNode(EScriptGraphNodeType type, const SGUID& contextGUID, const SGUID& refGUID, Gdiplus::PointF pos)
1046 CRY_ASSERT(m_pScriptGraph);
1047 if(m_pScriptGraph)
1049 if(IScriptGraphNode* pScriptGraphNode = m_pScriptGraph->AddNode(type, contextGUID, refGUID, Vec2(pos.X, pos.Y)))
1051 CDocGraphViewNodePtr pNode(new CDocGraphViewNode(CGraphView::GetGrid(), pos, *m_pScriptFile, *m_pScriptGraph, *pScriptGraphNode));
1052 CGraphView::AddNode(pNode, true, true);
1053 pScriptGraphNode->Refresh(SScriptRefreshParams(EScriptRefreshReason::EditorAdd));
1054 return pNode;
1057 return CDocGraphViewNodePtr();
1060 CDocGraphViewNodePtr CDocGraphView::AddNode(IScriptGraphNode& scriptGraphNode)
1062 CRY_ASSERT(m_pScriptGraph);
1063 if(m_pScriptGraph)
1065 const Vec2 pos = scriptGraphNode.GetPos();
1066 CDocGraphViewNodePtr pNode(new CDocGraphViewNode(CGraphView::GetGrid(), Gdiplus::PointF(pos.x, pos.y), *m_pScriptFile, *m_pScriptGraph, scriptGraphNode));
1067 CGraphView::AddNode(pNode, false, false);
1068 return pNode;
1070 return CDocGraphViewNodePtr();
1073 CDocGraphViewNodePtr CDocGraphView::GetNode(const SGUID& guid) const
1075 const TGraphViewNodePtrVector& nodes = GetNodes();
1076 for(TGraphViewNodePtrVector::const_iterator iNode = nodes.begin(), iEndNode = nodes.end(); iNode != iEndNode; ++ iNode)
1078 const CDocGraphViewNodePtr& pNode = std::static_pointer_cast<CDocGraphViewNode>(*iNode);
1079 if(pNode->GetGUID() == guid)
1081 return pNode;
1084 return CDocGraphViewNodePtr();
1087 bool CDocGraphView::AddLink(const IScriptGraphLink& scriptGraphLink)
1089 CDocGraphViewNodePtr pSrcNode = std::static_pointer_cast<CDocGraphViewNode>(GetNode(scriptGraphLink.GetSrcNodeGUID()));
1090 CDocGraphViewNodePtr pDstNode = std::static_pointer_cast<CDocGraphViewNode>(GetNode(scriptGraphLink.GetDstNodeGUID()));
1091 if((pSrcNode != NULL) && (pDstNode != NULL))
1093 CGraphView::AddLink(pSrcNode, scriptGraphLink.GetSrcOutputName(), pDstNode, scriptGraphLink.GetDstInputName());
1094 return true;
1096 return false;
1099 void CDocGraphView::InvalidateDoc()
1101 if(m_pScriptFile && m_pScriptGraph)
1103 m_signals.modification.Send(*m_pScriptFile);
1104 UnrollSequence();
1108 void CDocGraphView::UnrollSequence()
1110 m_sequenceNodes.clear();
1111 if(m_pScriptFile && m_pScriptGraph)
1113 TScriptGraphNodeConstVector nodes;
1114 DocUtils::CollectGraphNodes(*m_pScriptGraph, nodes);
1115 for(const IScriptGraphNode* pNode : nodes)
1117 for(size_t outputIdx = 0, outputCount = pNode->GetOutputCount(); outputIdx < outputCount; ++ outputIdx)
1119 if((pNode->GetOutputFlags(outputIdx) & EScriptGraphPortFlags::BeginSequence) != 0)
1121 DocUtils::UnrollGraphSequenceRecursive_Deprecated(*m_pScriptGraph, pNode->GetGUID(), m_sequenceNodes);
1125 for(const CGraphViewNodePtr& pNode : CGraphView::GetNodes())
1127 pNode->Enable(std::find(m_sequenceNodes.begin(), m_sequenceNodes.end(), std::static_pointer_cast<CDocGraphViewNode>(pNode)->GetGUID()) != m_sequenceNodes.end());
1132 void CDocGraphView::OnDocLinkRemoved(const IScriptGraphLink& link)
1134 if(!m_bRemovingLinks)
1136 const size_t linkIdx = CGraphView::FindLink(GetNode(link.GetSrcNodeGUID()), link.GetSrcOutputName(), GetNode(link.GetDstNodeGUID()), link.GetDstInputName());
1137 if(linkIdx != INVALID_INDEX)
1139 m_bRemovingLinks = true;
1140 CGraphView::RemoveLink(linkIdx);
1141 m_bRemovingLinks = false;
1146 CGraphSettingsWidget::CGraphSettingsWidget(QWidget* pParent)
1147 : QWidget(pParent)
1148 , m_pGraphView(nullptr)
1150 m_pLayout = new QBoxLayout(QBoxLayout::TopToBottom);
1151 m_pPropertyTree = new QPropertyTree(this);
1154 void CGraphSettingsWidget::SetGraphView(CGraphView* pGraphView)
1156 m_pGraphView = pGraphView;
1159 void CGraphSettingsWidget::InitLayout()
1161 QWidget::setLayout(m_pLayout);
1162 m_pLayout->setSpacing(1);
1163 m_pLayout->setMargin(0);
1164 m_pLayout->addWidget(m_pPropertyTree, 1);
1166 m_pPropertyTree->setSizeHint(QSize(250, 400));
1167 m_pPropertyTree->setExpandLevels(1);
1168 m_pPropertyTree->setSliderUpdateDelay(5);
1169 m_pPropertyTree->setValueColumnWidth(0.6f);
1170 m_pPropertyTree->attach(Serialization::SStruct(*this));
1173 void CGraphSettingsWidget::Serialize(Serialization::IArchive& archive)
1175 if(m_pGraphView)
1177 archive(m_pGraphView->GetSettings(), "general", "General");
1178 archive(m_pGraphView->GetPainter()->GetSettings(), "painter", "Painter");
1182 CDocGraphWidget::CDocGraphWidget(QWidget* pParent, CWnd* pParentWnd)
1183 : QWidget(pParent)
1185 m_pMainLayout = new QBoxLayout(QBoxLayout::TopToBottom);
1186 m_pSplitter = new QSplitter(Qt::Horizontal, this);
1187 m_pSettings = new CGraphSettingsWidget(this);
1188 m_pGraphViewHost = new QWinHost(this);
1189 m_pGraphView = new CDocGraphView();
1190 m_pControlLayout = new QBoxLayout(QBoxLayout::LeftToRight);
1191 m_pShowHideSettingsButton = new QPushButton(">> Show Settings", this);
1192 m_pShowHideSettingsButton->setFocusPolicy(Qt::FocusPolicy::NoFocus);
1194 m_pGraphView->Create(WS_CHILD, CRect(0, 0, 0, 0), pParentWnd, 0);
1195 m_pGraphViewHost->setWindow(m_pGraphView->GetSafeHwnd());
1197 m_pSettings->SetGraphView(m_pGraphView);
1198 m_pSettings->setVisible(false);
1200 connect(m_pShowHideSettingsButton, SIGNAL(clicked()), this, SLOT(OnShowHideSettingsButtonClicked()));
1203 void CDocGraphWidget::InitLayout()
1205 QWidget::setLayout(m_pMainLayout);
1206 m_pMainLayout->setSpacing(1);
1207 m_pMainLayout->setMargin(0);
1208 m_pMainLayout->addWidget(m_pSplitter, 1);
1209 m_pMainLayout->addLayout(m_pControlLayout, 0);
1211 m_pSplitter->setStretchFactor(0, 1);
1212 m_pSplitter->setStretchFactor(1, 0);
1213 m_pSplitter->addWidget(m_pSettings);
1214 m_pSplitter->addWidget(m_pGraphViewHost);
1216 QList<int> splitterSizes;
1217 splitterSizes.push_back(60);
1218 splitterSizes.push_back(200);
1219 m_pSplitter->setSizes(splitterSizes);
1221 m_pSettings->InitLayout();
1223 m_pControlLayout->setSpacing(2);
1224 m_pControlLayout->setMargin(4);
1225 m_pControlLayout->addWidget(m_pShowHideSettingsButton, 1);
1228 void CDocGraphWidget::LoadSettings(const XmlNodeRef& xml)
1230 Serialization::LoadXmlNode(*m_pSettings, xml);
1233 XmlNodeRef CDocGraphWidget::SaveSettings(const char* szName)
1235 return Serialization::SaveXmlNode(*m_pSettings, szName);
1238 void CDocGraphWidget::Refresh()
1240 m_pGraphView->Refresh();
1243 void CDocGraphWidget::LoadGraph(TScriptFile* pScriptFile, IScriptGraph* pScriptGraph)
1245 m_pGraphView->Load(pScriptFile, pScriptGraph);
1248 TScriptFile* CDocGraphWidget::GetScriptFile() const
1250 return m_pGraphView->GetScriptFile();
1253 IScriptGraph* CDocGraphWidget::GetScriptGraph() const
1255 return m_pGraphView->GetScriptGraph();
1258 void CDocGraphWidget::SelectAndFocusNode(const SGUID& nodeGuid)
1260 m_pGraphView->SelectAndFocusNode(nodeGuid);
1263 SDocGraphViewSignals& CDocGraphWidget::Signals()
1265 return m_pGraphView->Signals();
1268 void CDocGraphWidget::OnShowHideSettingsButtonClicked()
1270 const bool bShowSettings = !m_pSettings->isVisible();
1271 m_pShowHideSettingsButton->setText(bShowSettings ? "<< Hide Settings" : ">> Show Settings");
1272 m_pSettings->setVisible(bShowSettings);
1275 BEGIN_MESSAGE_MAP(CDocGraphWnd, CWnd)
1276 ON_WM_SHOWWINDOW()
1277 ON_WM_SIZE()
1278 END_MESSAGE_MAP()
1280 CDocGraphWnd::CDocGraphWnd()
1281 : m_pParentWndWidget(nullptr)
1282 , m_pDocGraphWidget(nullptr)
1283 , m_pLayout(nullptr)
1286 CDocGraphWnd::~CDocGraphWnd()
1288 SAFE_DELETE(m_pLayout);
1289 SAFE_DELETE(m_pDocGraphWidget);
1290 SAFE_DELETE(m_pParentWndWidget);
1293 void CDocGraphWnd::Init()
1295 LOADING_TIME_PROFILE_SECTION;
1296 m_pParentWndWidget = new QParentWndWidget(CWnd::GetSafeHwnd());
1297 m_pDocGraphWidget = new CDocGraphWidget(m_pParentWndWidget, this);
1298 m_pLayout = new QBoxLayout(QBoxLayout::TopToBottom);
1301 void CDocGraphWnd::InitLayout()
1303 LOADING_TIME_PROFILE_SECTION
1304 m_pLayout->setContentsMargins(0, 0, 0, 0);
1305 m_pLayout->addWidget(m_pDocGraphWidget, 1);
1306 m_pParentWndWidget->setLayout(m_pLayout);
1307 m_pParentWndWidget->show();
1308 m_pDocGraphWidget->InitLayout();
1311 void CDocGraphWnd::LoadSettings(const XmlNodeRef& xml)
1313 m_pDocGraphWidget->LoadSettings(xml);
1316 XmlNodeRef CDocGraphWnd::SaveSettings(const char* szName)
1318 return m_pDocGraphWidget->SaveSettings(szName);
1321 void CDocGraphWnd::Refresh()
1323 m_pDocGraphWidget->Refresh();
1326 void CDocGraphWnd::LoadGraph(TScriptFile* pScriptFile, IScriptGraph* pScriptGraph)
1328 m_pDocGraphWidget->LoadGraph(pScriptFile, pScriptGraph);
1331 TScriptFile* CDocGraphWnd::GetScriptFile() const
1333 return m_pDocGraphWidget->GetScriptFile();
1336 IScriptGraph* CDocGraphWnd::GetScriptGraph() const
1338 return m_pDocGraphWidget->GetScriptGraph();
1341 void CDocGraphWnd::SelectAndFocusNode(const SGUID& nodeGuid)
1343 m_pDocGraphWidget->SelectAndFocusNode(nodeGuid);
1346 SDocGraphViewSignals& CDocGraphWnd::Signals()
1348 return m_pDocGraphWidget->Signals();
1351 void CDocGraphWnd::OnShowWindow(BOOL bShow, UINT nStatus)
1353 if(m_pDocGraphWidget)
1355 m_pDocGraphWidget->setVisible(bShow);
1359 void CDocGraphWnd::OnSize(UINT nType, int cx, int cy)
1361 if(m_pParentWndWidget)
1363 CRect rect;
1364 CWnd::GetClientRect(&rect);
1365 m_pParentWndWidget->setGeometry(0, 0, rect.Width(), rect.Height());