MyGUI  3.2.0
MyGUI_ProgressBar.cpp
Go to the documentation of this file.
1 
6 /*
7  This file is part of MyGUI.
8 
9  MyGUI is free software: you can redistribute it and/or modify
10  it under the terms of the GNU Lesser General Public License as published by
11  the Free Software Foundation, either version 3 of the License, or
12  (at your option) any later version.
13 
14  MyGUI is distributed in the hope that it will be useful,
15  but WITHOUT ANY WARRANTY; without even the implied warranty of
16  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  GNU Lesser General Public License for more details.
18 
19  You should have received a copy of the GNU Lesser General Public License
20  along with MyGUI. If not, see <http://www.gnu.org/licenses/>.
21 */
22 #include "MyGUI_Precompiled.h"
23 #include "MyGUI_ProgressBar.h"
24 #include "MyGUI_ResourceSkin.h"
25 #include "MyGUI_Widget.h"
26 #include "MyGUI_Gui.h"
27 #include "MyGUI_SkinManager.h"
28 
29 namespace MyGUI
30 {
31 
32  const size_t PROGRESS_AUTO_WIDTH = 200;
33  const size_t PROGRESS_AUTO_RANGE = 1000;
34  const float PROGRESS_AUTO_COEF = 400;
35 
37  mTrackWidth(1),
38  mTrackStep(0),
39  mTrackMin(0),
40  mRange(0),
41  mStartPosition(0),
42  mEndPosition(0),
43  mAutoPosition(0.0f),
44  mAutoTrack(false),
45  mFillTrack(false),
46  mClient(nullptr)
47  {
48  }
49 
51  {
52  Base::initialiseOverride();
53 
54  assignWidget(mClient, "TrackPlace");
55 
56  if (nullptr == mClient)
57  {
58  //OBSOLETE
59  assignWidget(mClient, "Client");
60 
61  if (nullptr == mClient)
62  mClient = this;
63  }
64 
65  if (isUserString("TrackSkin"))
66  mTrackSkin = getUserString("TrackSkin");
67  if (isUserString("TrackWidth"))
68  mTrackWidth = utility::parseValue<int>(getUserString("TrackWidth"));
69  //OBSOLETE
70  if (isUserString("TrackMin"))
71  mTrackMin = utility::parseValue<int>(getUserString("TrackMin"));
72  else
73  mTrackMin = mTrackWidth;
74  if (isUserString("TrackStep"))
75  mTrackStep = utility::parseValue<int>(getUserString("TrackStep"));
76  if (isUserString("TrackFill"))
77  mFillTrack = utility::parseValue<bool>(getUserString("TrackFill"));
78 
79  if (!isUserString("TrackStep"))
80  mTrackStep = mTrackWidth;
81 
82  if (1 > mTrackWidth)
83  mTrackWidth = 1;
84  }
85 
87  {
88  mClient = nullptr;
89 
90  Base::shutdownOverride();
91  }
92 
93  void ProgressBar::setProgressRange(size_t _range)
94  {
95  if (mAutoTrack) return;
96  mRange = _range;
97  if (mEndPosition > mRange) mEndPosition = mRange;
98  if (mStartPosition > mRange) mStartPosition = mRange;
99  updateTrack();
100  }
101 
103  {
104  if (mAutoTrack) return;
105  mEndPosition = _pos;
106  if (mEndPosition > mRange) mEndPosition = mRange;
107  updateTrack();
108  }
109 
111  {
112  if (mAutoTrack == _auto) return;
113  mAutoTrack = _auto;
114 
115  if (mAutoTrack)
116  {
117  Gui::getInstance().eventFrameStart += newDelegate(this, &ProgressBar::frameEntered);
118  mRange = PROGRESS_AUTO_RANGE;
119  mEndPosition = mStartPosition = 0;
120  mAutoPosition = 0.0f;
121  }
122  else
123  {
124  Gui::getInstance().eventFrameStart -= newDelegate(this, &ProgressBar::frameEntered);
125  mRange = mEndPosition = mStartPosition = 0;
126  }
127  updateTrack();
128  }
129 
130  void ProgressBar::frameEntered(float _time)
131  {
132  if (!mAutoTrack) return;
133  mAutoPosition += (PROGRESS_AUTO_COEF * _time);
134  size_t pos = (size_t)mAutoPosition;
135 
136  if (pos > (mRange + PROGRESS_AUTO_WIDTH)) mAutoPosition = 0.0f;
137 
138  if (pos > mRange) mEndPosition = mRange;
139  else mEndPosition = size_t(mAutoPosition);
140 
141  if (pos < PROGRESS_AUTO_WIDTH) mStartPosition = 0;
142  else mStartPosition = pos - PROGRESS_AUTO_WIDTH;
143 
144  updateTrack();
145  }
146 
147  void ProgressBar::setPosition(const IntPoint& _point)
148  {
149  Base::setPosition(_point);
150  }
151 
152  void ProgressBar::setSize(const IntSize& _size)
153  {
154  Base::setSize(_size);
155 
156  updateTrack();
157  }
158 
159  void ProgressBar::setCoord(const IntCoord& _coord)
160  {
161  Base::setCoord(_coord);
162 
163  updateTrack();
164  }
165 
166  void ProgressBar::updateTrack()
167  {
168  // все скрыто
169  if ((0 == mRange) || (0 == mEndPosition))
170  {
171  for (VectorWidgetPtr::iterator iter = mVectorTrack.begin(); iter != mVectorTrack.end(); ++iter)
172  {
173  (*iter)->setVisible(false);
174  }
175  return;
176  }
177 
178  // тут попроще расчеты
179  if (mFillTrack)
180  {
181  if (mVectorTrack.empty())
182  {
183  Widget* widget = mClient->createWidget<Widget>(mTrackSkin, IntCoord(), Align::Left | Align::VStretch);
184  mVectorTrack.push_back(widget);
185  }
186  else
187  {
188  // первый показываем и ставим норм альфу
189  VectorWidgetPtr::iterator iter = mVectorTrack.begin();
190  (*iter)->setVisible(true);
191  (*iter)->setAlpha(ALPHA_MAX);
192 
193  // все начиная со второго скрываем
194  ++iter;
195  for (; iter != mVectorTrack.end(); ++iter)
196  {
197  (*iter)->setVisible(false);
198  }
199  }
200 
201  Widget* wid = mVectorTrack.front();
202 
203  // полностью виден
204  if ((0 == mStartPosition) && (mRange == mEndPosition))
205  {
206  setTrackPosition(wid, 0, 0, getClientWidth(), getClientHeight());
207  }
208  // эх
209  else
210  {
211  int pos = (int)mStartPosition * (getClientWidth() - mTrackMin) / (int)mRange;
212  setTrackPosition(wid, pos, 0, ((int)mEndPosition * (getClientWidth() - mTrackMin) / (int)mRange) - pos + mTrackMin, getClientHeight());
213  }
214 
215  return;
216  }
217 
218  // сначала проверяем виджеты для трека
219  int width = getClientWidth() - mTrackWidth + mTrackStep;
220  int count = width / mTrackStep;
221  int ost = (width % mTrackStep);
222  if (ost > 0)
223  {
224  width += mTrackStep - ost;
225  count ++;
226  }
227 
228  while ((int)mVectorTrack.size() < count)
229  {
230  Widget* widget = mClient->createWidget<Widget>(mTrackSkin, IntCoord(/*(int)mVectorTrack.size() * mTrackStep, 0, mTrackWidth, getClientHeight()*/), Align::Left | Align::VStretch);
231  widget->setVisible(false);
232  mVectorTrack.push_back(widget);
233  }
234 
235  // все видно
236  if ((0 == mStartPosition) && (mRange == mEndPosition))
237  {
238  int pos = 0;
239  for (VectorWidgetPtr::iterator iter = mVectorTrack.begin(); iter != mVectorTrack.end(); ++iter)
240  {
241  (*iter)->setAlpha(ALPHA_MAX);
242  (*iter)->setVisible(true);
243  setTrackPosition(*iter, pos * mTrackStep, 0, mTrackWidth, getClientHeight());
244  pos++;
245  }
246  }
247  // эх, придется считать
248  else
249  {
250  // сколько не видно
251  int hide_pix = (width * (int)mStartPosition / (int)mRange);
252  int hide_count = hide_pix / mTrackStep;
253  // сколько видно
254  int show_pix = (width * (int)mEndPosition / (int)mRange);
255  int show_count = show_pix / mTrackStep;
256 
257  int pos = 0;
258  for (VectorWidgetPtr::iterator iter = mVectorTrack.begin(); iter != mVectorTrack.end(); ++iter)
259  {
260  if (0 > show_count)
261  {
262  (*iter)->setVisible(false);
263  }
264  else if (0 == show_count)
265  {
266  (*iter)->setAlpha((float)(show_pix % mTrackStep) / (float)mTrackStep);
267  (*iter)->setVisible(true);
268  setTrackPosition(*iter, pos * mTrackStep, 0, mTrackWidth, getClientHeight());
269  }
270  else
271  {
272  if (0 < hide_count)
273  {
274  (*iter)->setVisible(false);
275  }
276  else if (0 == hide_count)
277  {
278  (*iter)->setAlpha(1.0f - ((float)(hide_pix % mTrackStep) / (float)mTrackStep));
279  (*iter)->setVisible(true);
280  setTrackPosition(*iter, pos * mTrackStep, 0, mTrackWidth, getClientHeight());
281  }
282  else
283  {
284  (*iter)->setAlpha(ALPHA_MAX);
285  (*iter)->setVisible(true);
286  setTrackPosition(*iter, pos * mTrackStep, 0, mTrackWidth, getClientHeight());
287  }
288  }
289  hide_count --;
290  show_count --;
291  pos ++;
292  }
293  }
294  }
295 
296  void ProgressBar::setTrackPosition(Widget* _widget, int _left, int _top, int _width, int _height)
297  {
298  if (mFlowDirection == FlowDirection::LeftToRight) _widget->setCoord(_left, _top, _width, _height);
299  else if (mFlowDirection == FlowDirection::RightToLeft) _widget->setCoord(mClient->getWidth() - _left - _width, _top, _width, _height);
300  else if (mFlowDirection == FlowDirection::TopToBottom) _widget->setCoord(_top, _left, _height, _width);
301  else if (mFlowDirection == FlowDirection::BottomToTop) _widget->setCoord(_top, mClient->getHeight() - _left - _width, _height, _width);
302  }
303 
304  int ProgressBar::getClientWidth()
305  {
306  return mFlowDirection.isHorizontal() ? mClient->getWidth() : mClient->getHeight();
307  }
308 
309  int ProgressBar::getClientHeight()
310  {
311  return mFlowDirection.isHorizontal() ? mClient->getHeight() : mClient->getWidth();
312  }
313 
315  {
316  mFlowDirection = _value;
317  updateTrack();
318  }
319 
320  void ProgressBar::setPropertyOverride(const std::string& _key, const std::string& _value)
321  {
322  if (_key == "Range")
323  setProgressRange(utility::parseValue<size_t>(_value));
324  else if (_key == "RangePosition")
325  setProgressPosition(utility::parseValue<size_t>(_value));
326  else if (_key == "AutoTrack")
327  setProgressAutoTrack(utility::parseValue<bool>(_value));
328  else if (_key == "FlowDirection")
329  setFlowDirection(utility::parseValue<FlowDirection>(_value));
330  else
331  {
332  Base::setPropertyOverride(_key, _value);
333  return;
334  }
335  eventChangeProperty(this, _key, _value);
336  }
337 
339  {
340  return mRange;
341  }
342 
344  {
345  return mEndPosition;
346  }
347 
349  {
350  return mAutoTrack;
351  }
352 
354  {
355  return mFlowDirection;
356  }
357 
358  void ProgressBar::setPosition(int _left, int _top)
359  {
360  setPosition(IntPoint(_left, _top));
361  }
362 
363  void ProgressBar::setSize(int _width, int _height)
364  {
365  setSize(IntSize(_width, _height));
366  }
367 
368  void ProgressBar::setCoord(int _left, int _top, int _width, int _height)
369  {
370  setCoord(IntCoord(_left, _top, _width, _height));
371  }
372 
373 } // namespace MyGUI