1 /*!
2 	@file
3 	@author		Albert Semenov
4 	@date		01/2009
5 */
6 #ifndef BASE_GRAPH_NODE_H_
7 #define BASE_GRAPH_NODE_H_
8 
9 #include <MyGUI.h>
10 #include "BaseGraphConnection.h"
11 #include "IGraphController.h"
12 
13 namespace wraps
14 {
15 
16 	class BaseGraphNode :
17 		public BaseLayout
18 	{
19 	public:
BaseGraphNode(const std::string & _layout)20 		BaseGraphNode(const std::string& _layout) :
21 			BaseLayout("", nullptr),
22 			mLayout(_layout),
23 			mView(nullptr)
24 		{
25 		}
26 
27 		// энумератор всех точек узла
getConnectionEnumerator()28 		EnumeratorConnection getConnectionEnumerator() const
29 		{
30 			return EnumeratorConnection(mListConnection);
31 		}
32 
isAnyConnection()33 		bool isAnyConnection() const
34 		{
35 			EnumeratorConnection point = getConnectionEnumerator();
36 			while (point.next())
37 			{
38 				if (point->isAnyConnection())
39 					return true;
40 			}
41 			return false;
42 		}
43 
44 		BaseGraphConnection* getConnectionByName(const std::string& _name, const std::string& _type = "")
45 		{
46 			EnumeratorConnection point = getConnectionEnumerator();
47 			while (point.next())
48 			{
49 				if (point->getName() == _name && (_type.empty() || point->getType() == _type))
50 				{
51 					return point.current();
52 				}
53 			}
54 			return nullptr;
55 		}
56 
getCoord()57 		const MyGUI::IntCoord& getCoord()
58 		{
59 			return mMainWidget->getCoord();
60 		}
61 
setCoord(const MyGUI::IntCoord & _coord)62 		void setCoord(const MyGUI::IntCoord& _coord)
63 		{
64 			mMainWidget->setCoord(_coord);
65 			mView->changePosition(this);
66 		}
67 
getPosition()68 		MyGUI::IntPoint getPosition()
69 		{
70 			return mMainWidget->getPosition();
71 		}
72 
setPosition(const MyGUI::IntPoint & _point)73 		void setPosition(const MyGUI::IntPoint& _point)
74 		{
75 			mMainWidget->setPosition(_point);
76 			mView->changePosition(this);
77 		}
78 
getAbsolutePosition()79 		const MyGUI::IntPoint& getAbsolutePosition()
80 		{
81 			return mMainWidget->getAbsolutePosition();
82 		}
83 
setAbsolutePosition(const MyGUI::IntPoint & _point)84 		void setAbsolutePosition(const MyGUI::IntPoint& _point)
85 		{
86 			setPosition(MyGUI::IntPoint(_point.left - mMainWidget->getParent()->getAbsoluteLeft(), _point.top - mMainWidget->getParent()->getAbsoluteTop()));
87 		}
88 
89 	/*internal:*/
_initialise(MyGUI::Widget * _parent,IGraphController * _view)90 		void _initialise(MyGUI::Widget* _parent, IGraphController* _view)
91 		{
92 			mView = _view;
93 			if ( ! mLayout.empty())
94 			{
95 				BaseLayout::initialise(mLayout, _parent);
96 			}
97 			initialise();
98 
99 			MyGUI::Window* window = mMainWidget->castType<MyGUI::Window>(false);
100 			if (window != nullptr)
101 			{
102 				window->eventWindowChangeCoord += MyGUI::newDelegate(this, &BaseGraphNode::notifyWindowChangeCoord);
103 				window->eventWindowButtonPressed += MyGUI::newDelegate(this, &BaseGraphNode::notifyWindowButtonPressed);
104 			}
105 
106 			// перекрывающийся стиль
107 			mMainWidget->setWidgetStyle(MyGUI::WidgetStyle::Overlapped);
108 		}
109 
_shutdown()110 		void _shutdown()
111 		{
112 			BaseLayout::shutdown();
113 			shutdown();
114 		}
115 
116 	protected:
117 		virtual void initialise() = 0;
118 		virtual void shutdown() = 0;
119 
notifyWindowChangeCoord(MyGUI::Window * _sender)120 		void notifyWindowChangeCoord(MyGUI::Window* _sender)
121 		{
122 			MyGUI::IntCoord coord = _sender->getCoord();
123 			if ((coord.left < 0) || (coord.top < 0))
124 			{
125 				if (coord.left < 0) coord.left = 0;
126 				if (coord.top < 0) coord.top = 0;
127 				_sender->setCoord(coord);
128 			}
129 
130 			mView->changePosition(this);
131 		}
132 
notifyWindowButtonPressed(MyGUI::Window * _sender,const std::string & _name)133 		void notifyWindowButtonPressed(MyGUI::Window* _sender, const std::string& _name)
134 		{
135 			if (_name == "close")
136 				mView->close(this);
137 		}
138 
139 		template <typename T>
140 		void assignBase(T * & _widget, const std::string& _name, bool _throw = true)
141 		{
142 			BaseLayout::assignBase<T>(_widget, _name, _throw);
143 			mListConnection.push_back(_widget);
144 			addConnection(_widget);
145 		}
146 
147 	private:
addConnection(BaseGraphConnection * _connection)148 		void addConnection(BaseGraphConnection* _connection)
149 		{
150 			_connection->_setOwnerNode(this);
151 			_connection->_getMainWidget()->eventMouseButtonPressed += MyGUI::newDelegate(this, &BaseGraphNode::notifyMouseButtonPressed);
152 			_connection->_getMainWidget()->eventMouseButtonReleased += MyGUI::newDelegate(this, &BaseGraphNode::notifyMouseButtonReleased);
153 			_connection->_getMainWidget()->eventMouseDrag += MyGUI::newDelegate(this, &BaseGraphNode::notifyMouseDrag);
154 			_connection->_getMainWidget()->setUserData(_connection);
155 		}
156 
notifyMouseButtonPressed(MyGUI::Widget * _sender,int _left,int _top,MyGUI::MouseButton _id)157 		void notifyMouseButtonPressed(MyGUI::Widget* _sender, int _left, int _top, MyGUI::MouseButton _id)
158 		{
159 			if (_id == MyGUI::MouseButton::Left)
160 				mView->startDrag(*_sender->getUserData<BaseGraphConnection*>());
161 		}
162 
notifyMouseButtonReleased(MyGUI::Widget * _sender,int _left,int _top,MyGUI::MouseButton _id)163 		void notifyMouseButtonReleased(MyGUI::Widget* _sender, int _left, int _top, MyGUI::MouseButton _id)
164 		{
165 			mView->stopDrag(*_sender->getUserData<BaseGraphConnection*>());
166 		}
167 
notifyMouseDrag(MyGUI::Widget * _sender,int _left,int _top,MyGUI::MouseButton _id)168 		void notifyMouseDrag(MyGUI::Widget* _sender, int _left, int _top, MyGUI::MouseButton _id)
169 		{
170 			if (_id == MyGUI::MouseButton::Left)
171 				mView->updateDrag(*_sender->getUserData<BaseGraphConnection*>());
172 		}
173 
174 	private:
175 		std::string mLayout;
176 		VectorConnection mListConnection;
177 		IGraphController* mView;
178 	};
179 
180 } // namespace wraps
181 
182 #endif // BASE_GRAPH_NODE_H_
183