1 /*!
2 	@file
3 	@author		Albert Semenov
4 	@date		08/2012
5 */
6 
7 #include "Precompiled.h"
8 #include "SeparatePanel.h"
9 #include "FactoryManager.h"
10 #include "SettingsManager.h"
11 
12 namespace tools
13 {
14 
FACTORY_ITEM_ATTRIBUTE(SeparatePanel)15 	FACTORY_ITEM_ATTRIBUTE(SeparatePanel)
16 
17 	SeparatePanel::SeparatePanel() :
18 		mFirstPanel(),
19 		mSecondPanel(),
20 		mSeparatorH(),
21 		mSeparatorV(),
22 		mMinSize(),
23 		mPanelAlign(MyGUI::Align::Left)
24 	{
25 	}
26 
~SeparatePanel()27 	SeparatePanel::~SeparatePanel()
28 	{
29 		saveDefaultSize();
30 	}
31 
OnInitialise(Control * _parent,MyGUI::Widget * _place,const std::string & _layoutName)32 	void SeparatePanel::OnInitialise(Control* _parent, MyGUI::Widget* _place, const std::string& _layoutName)
33 	{
34 		Control::OnInitialise(_parent, _place, _layoutName);
35 
36 		assignWidget(mFirstPanel, "FirstPanel");
37 		assignWidget(mSecondPanel, "SecondPanel");
38 		assignWidget(mSeparatorH, "SeparatorH");
39 		assignWidget(mSeparatorV, "SeparatorV");
40 
41 		mMinSize = MyGUI::utility::parseValue<int>(mMainWidget->getUserString("MinSize"));
42 
43 		mMainWidget->eventChangeCoord += MyGUI::newDelegate(this, &SeparatePanel::notifyChangeCoord);
44 		mSeparatorH->eventMouseButtonPressed += MyGUI::newDelegate(this, &SeparatePanel::notifyMouseButtonPressed);
45 		mSeparatorV->eventMouseButtonPressed += MyGUI::newDelegate(this, &SeparatePanel::notifyMouseButtonPressed);
46 		mSeparatorH->eventMouseDrag += MyGUI::newDelegate(this, &SeparatePanel::notifyMouseDrag);
47 		mSeparatorV->eventMouseDrag += MyGUI::newDelegate(this, &SeparatePanel::notifyMouseDrag);
48 
49 		mSaveAs = mMainWidget->getUserString("SaveAs");
50 		loadDefaultSize();
51 
52 		if (mMainWidget->isUserString("PanelAlign"))
53 			mPanelAlign = MyGUI::utility::parseValue<MyGUI::Align>(mMainWidget->getUserString("PanelAlign"));
54 
55 		setPanelAlign(mPanelAlign);
56 	}
57 
notifyChangeCoord(MyGUI::Widget * _sender)58 	void SeparatePanel::notifyChangeCoord(MyGUI::Widget* _sender)
59 	{
60 		invalidateSize(mFirstPanel->getCoord(), mSeparatorH->getCoord(), mSeparatorV->getCoord(), mSecondPanel->getCoord());
61 	}
62 
invalidateSize(const MyGUI::IntCoord & _firstPanel,const MyGUI::IntCoord & _separatorH,const MyGUI::IntCoord & _separatorV,const MyGUI::IntCoord & _secondPanel)63 	void SeparatePanel::invalidateSize(const MyGUI::IntCoord& _firstPanel, const MyGUI::IntCoord& _separatorH, const MyGUI::IntCoord& _separatorV, const MyGUI::IntCoord& _secondPanel)
64 	{
65 		if (mMainWidget->getWidth() <= 0 ||
66 			mMainWidget->getHeight() <= 0)
67 			return;
68 
69 		MyGUI::IntCoord firstPanel = _firstPanel;
70 		MyGUI::IntCoord separatorH = _separatorH;
71 		MyGUI::IntCoord separatorV = _separatorV;
72 		MyGUI::IntCoord secondPanel = _secondPanel;
73 
74 		if (mPanelAlign.isLeft())
75 		{
76 			updateSize(firstPanel.width, secondPanel.width, separatorH.width, mMainWidget->getWidth(), mDefaultPanelSize.width);
77 			firstPanel.top = separatorH.top = secondPanel.top = 0;
78 			firstPanel.height = separatorH.height = secondPanel.height = mMainWidget->getHeight();
79 			firstPanel.left = 0;
80 			separatorH.left = firstPanel.right();
81 			secondPanel.left = separatorH.right();
82 		}
83 		else if (mPanelAlign.isRight())
84 		{
85 			updateSize(firstPanel.width, secondPanel.width, separatorH.width, mMainWidget->getWidth(), mDefaultPanelSize.width);
86 			firstPanel.top = separatorH.top = secondPanel.top = 0;
87 			firstPanel.height = separatorH.height = secondPanel.height = mMainWidget->getHeight();
88 			secondPanel.left = 0;
89 			separatorH.left = secondPanel.right();
90 			firstPanel.left = separatorH.right();
91 		}
92 		else if (mPanelAlign.isTop())
93 		{
94 			updateSize(firstPanel.height, secondPanel.height, separatorV.height, mMainWidget->getHeight(), mDefaultPanelSize.height);
95 			firstPanel.left = separatorV.left = secondPanel.left = 0;
96 			firstPanel.width = separatorV.width = secondPanel.width = mMainWidget->getWidth();
97 			firstPanel.top = 0;
98 			separatorV.top = firstPanel.bottom();
99 			secondPanel.top = separatorV.bottom();
100 		}
101 		else if (mPanelAlign.isBottom())
102 		{
103 			updateSize(firstPanel.height, secondPanel.height, separatorV.height, mMainWidget->getHeight(), mDefaultPanelSize.height);
104 			firstPanel.left = separatorV.left = secondPanel.left = 0;
105 			firstPanel.width = separatorV.width = secondPanel.width = mMainWidget->getWidth();
106 			secondPanel.top = 0;
107 			separatorV.top = secondPanel.bottom();
108 			firstPanel.top = separatorV.bottom();
109 		}
110 
111 		if (firstPanel != mFirstPanel->getCoord())
112 			mFirstPanel->setCoord(firstPanel);
113 
114 		if (separatorH != mSeparatorH->getCoord())
115 			mSeparatorH->setCoord(separatorH);
116 
117 		if (separatorV != mSeparatorV->getCoord())
118 			mSeparatorV->setCoord(separatorV);
119 
120 		if (secondPanel != mSecondPanel->getCoord())
121 			mSecondPanel->setCoord(secondPanel);
122 	}
123 
setPanelAlign(MyGUI::Align _value)124 	void SeparatePanel::setPanelAlign(MyGUI::Align _value)
125 	{
126 		mPanelAlign = _value;
127 
128 		if (mPanelAlign.isLeft() || mPanelAlign.isRight())
129 		{
130 			mSeparatorH->setVisible(true);
131 			mSeparatorV->setVisible(false);
132 		}
133 		else if (mPanelAlign.isTop() || mPanelAlign.isBottom())
134 		{
135 			mSeparatorH->setVisible(false);
136 			mSeparatorV->setVisible(true);
137 		}
138 
139 		invalidateSize(mFirstPanel->getCoord(), mSeparatorH->getCoord(), mSeparatorV->getCoord(), mSecondPanel->getCoord());
140 	}
141 
getPanelAlign() const142 	MyGUI::Align SeparatePanel::getPanelAlign() const
143 	{
144 		return mPanelAlign;
145 	}
146 
updateSize(int & _firstWidth,int & _secondWidth,int _separatorWidth,int _mainWidth,int _defaultSize)147 	void SeparatePanel::updateSize(int& _firstWidth, int& _secondWidth, int _separatorWidth, int _mainWidth, int _defaultSize)
148 	{
149 		if (_firstWidth < _defaultSize)
150 			_firstWidth = _defaultSize;
151 
152 		if (_firstWidth < mMinSize)
153 			_firstWidth = mMinSize;
154 
155 		if (_secondWidth < mMinSize)
156 			_secondWidth = mMinSize;
157 
158 		if (_firstWidth + _secondWidth + _separatorWidth > _mainWidth)
159 		{
160 			_secondWidth = _mainWidth - _firstWidth - _separatorWidth;
161 
162 			if (_secondWidth < mMinSize)
163 				_secondWidth = mMinSize;
164 
165 			if (_firstWidth + _secondWidth + _separatorWidth > _mainWidth)
166 			{
167 				_firstWidth = _mainWidth - _secondWidth - _separatorWidth;
168 
169 				if (_firstWidth < mMinSize)
170 					_firstWidth = mMinSize;
171 
172 				if (_firstWidth + _secondWidth + _separatorWidth > _mainWidth)
173 				{
174 					_secondWidth = _mainWidth - _firstWidth - _separatorWidth;
175 
176 					if (_secondWidth < 0)
177 						_secondWidth = 0;
178 
179 					if (_firstWidth + _secondWidth + _separatorWidth > _mainWidth)
180 					{
181 						_firstWidth = _mainWidth - _secondWidth - _separatorWidth;
182 
183 						if (_firstWidth < 0)
184 							_firstWidth = 0;
185 					}
186 				}
187 			}
188 		}
189 
190 		if (_firstWidth + _secondWidth + _separatorWidth < _mainWidth)
191 			_secondWidth = _mainWidth - _firstWidth - _separatorWidth;
192 	}
193 
notifyMouseButtonPressed(MyGUI::Widget * _sender,int _left,int _top,MyGUI::MouseButton _id)194 	void SeparatePanel::notifyMouseButtonPressed(MyGUI::Widget* _sender, int _left, int _top, MyGUI::MouseButton _id)
195 	{
196 		if (_id != MyGUI::MouseButton::Left)
197 			return;
198 
199 		mMousePressedOffset = MyGUI::IntPoint(_left, _top) - _sender->getAbsolutePosition();
200 	}
201 
notifyMouseDrag(MyGUI::Widget * _sender,int _left,int _top,MyGUI::MouseButton _id)202 	void SeparatePanel::notifyMouseDrag(MyGUI::Widget* _sender, int _left, int _top, MyGUI::MouseButton _id)
203 	{
204 		if (_id != MyGUI::MouseButton::Left)
205 			return;
206 
207 		SeparatePanel::moveSeparator(MyGUI::IntPoint(_left, _top));
208 	}
209 
moveSeparator(const MyGUI::IntPoint & _mousePosition)210 	void SeparatePanel::moveSeparator(const MyGUI::IntPoint& _mousePosition)
211 	{
212 		MyGUI::IntPoint offset = _mousePosition - mMousePressedOffset - mMainWidget->getAbsolutePosition();
213 
214 		// сбрасываем дефолтный размер панели
215 		mDefaultPanelSize.clear();
216 
217 		MyGUI::IntCoord firstPanel = mFirstPanel->getCoord();
218 		MyGUI::IntCoord separatorH = mSeparatorH->getCoord();
219 		MyGUI::IntCoord separatorV = mSeparatorV->getCoord();
220 		MyGUI::IntCoord secondPanel = mSecondPanel->getCoord();
221 
222 		if (mPanelAlign.isLeft())
223 		{
224 			firstPanel.width = offset.left - firstPanel.left;
225 			separatorH.left = offset.left;
226 			secondPanel.width = secondPanel.right() - (offset.left + separatorH.width);
227 			secondPanel.left = offset.left + separatorH.width;
228 		}
229 		else if (mPanelAlign.isRight())
230 		{
231 			secondPanel.width = offset.left - secondPanel.left;
232 			separatorH.left = offset.left;
233 			firstPanel.width = firstPanel.right() - (offset.left + separatorH.width);
234 			firstPanel.left = offset.left + separatorH.width;
235 		}
236 		else if (mPanelAlign.isTop())
237 		{
238 			firstPanel.height = offset.top - firstPanel.top;
239 			separatorV.top = offset.top;
240 			secondPanel.height = secondPanel.bottom() - (offset.top + separatorV.height);
241 			secondPanel.top = offset.top + separatorV.height;
242 		}
243 		else if (mPanelAlign.isBottom())
244 		{
245 			secondPanel.height = offset.top - secondPanel.top;
246 			separatorV.top = offset.top;
247 			firstPanel.height = firstPanel.bottom() - (offset.top + separatorV.height);
248 			firstPanel.top = offset.top + separatorV.height;
249 		}
250 
251 		invalidateSize(firstPanel, separatorH, separatorV, secondPanel);
252 
253 		// запоминаем дефолтный размер панели
254 		mDefaultPanelSize = mFirstPanel->getSize();
255 	}
256 
loadDefaultSize()257 	void SeparatePanel::loadDefaultSize()
258 	{
259 		if (mSaveAs != "")
260 			mDefaultPanelSize = SettingsManager::getInstance().getValue<MyGUI::IntSize>("Controls/SeparateControl/" + mSaveAs);
261 
262 		if (mDefaultPanelSize.empty())
263 		{
264 			if (mMainWidget->isUserString("DefaultSize"))
265 			{
266 				int size = MyGUI::utility::parseValue<int>(mMainWidget->getUserString("DefaultSize"));
267 				mDefaultPanelSize = MyGUI::IntSize(size, size);
268 			}
269 			else
270 			{
271 				mDefaultPanelSize = MyGUI::IntSize(
272 					(mMainWidget->getWidth() - mSeparatorH->getWidth()) / 2,
273 					(mMainWidget->getHeight() - mSeparatorV->getHeight()) / 2);
274 			}
275 		}
276 	}
277 
saveDefaultSize()278 	void SeparatePanel::saveDefaultSize()
279 	{
280 		if (mSaveAs != "")
281 			SettingsManager::getInstance().setValue("Controls/SeparateControl/" + mSaveAs, mDefaultPanelSize);
282 	}
283 
284 }
285