MyGUI 3.4.1
MyGUI_ProgressBar.cpp
Go to the documentation of this file.
1/*
2 * This source file is part of MyGUI. For the latest info, see http://mygui.info/
3 * Distributed under the MIT License
4 * (See accompanying file COPYING.MIT or copy at http://opensource.org/licenses/MIT)
5 */
6
7#include "MyGUI_Precompiled.h"
8#include "MyGUI_ProgressBar.h"
10#include "MyGUI_Widget.h"
11#include "MyGUI_Gui.h"
12#include "MyGUI_SkinManager.h"
13
14namespace MyGUI
15{
16
17 const size_t PROGRESS_AUTO_WIDTH = 200;
18 const size_t PROGRESS_AUTO_RANGE = 1000;
19 const float PROGRESS_AUTO_COEF = 400;
20
22 mTrackWidth(1),
23 mTrackStep(0),
24 mTrackMin(0),
25 mRange(0),
26 mStartPosition(0),
27 mEndPosition(0),
28 mAutoPosition(0.0f),
29 mAutoTrack(false),
30 mFillTrack(false),
31 mTrackPlace(nullptr)
32 {
33 }
34
36 {
37 Base::initialiseOverride();
38
40 assignWidget(mTrackPlace, "TrackPlace");
41
42 if (nullptr == mTrackPlace)
43 {
44 //OBSOLETE
45 assignWidget(mTrackPlace, "Client");
46
47 if (nullptr == mTrackPlace)
48 mTrackPlace = this;
49 }
50
51 if (isUserString("TrackSkin"))
52 mTrackSkin = getUserString("TrackSkin");
53
54 if (isUserString("TrackWidth"))
55 mTrackWidth = utility::parseValue<int>(getUserString("TrackWidth"));
56
57 //OBSOLETE
58 if (isUserString("TrackMin"))
59 mTrackMin = utility::parseValue<int>(getUserString("TrackMin"));
60
61 else
62 mTrackMin = mTrackWidth;
63
64 if (isUserString("TrackStep"))
65 mTrackStep = utility::parseValue<int>(getUserString("TrackStep"));
66
67 if (isUserString("TrackFill"))
68 mFillTrack = utility::parseValue<bool>(getUserString("TrackFill"));
69
70 if (!isUserString("TrackStep"))
71 mTrackStep = mTrackWidth;
72
73 if (1 > mTrackWidth)
74 mTrackWidth = 1;
75 }
76
78 {
79 mTrackPlace = nullptr;
80
81 Base::shutdownOverride();
82 }
83
85 {
86 if (mAutoTrack) return;
87 mRange = _range;
88 if (mEndPosition > mRange) mEndPosition = mRange;
89 if (mStartPosition > mRange) mStartPosition = mRange;
90 updateTrack();
91 }
92
94 {
95 if (mAutoTrack) return;
96 mEndPosition = _pos;
97 if (mEndPosition > mRange) mEndPosition = mRange;
98 updateTrack();
99 }
100
102 {
103 if (mAutoTrack == _auto) return;
104 mAutoTrack = _auto;
105
106 if (mAutoTrack)
107 {
108 Gui::getInstance().eventFrameStart += newDelegate(this, &ProgressBar::frameEntered);
109 mRange = PROGRESS_AUTO_RANGE;
110 mEndPosition = mStartPosition = 0;
111 mAutoPosition = 0.0f;
112 }
113 else
114 {
115 Gui::getInstance().eventFrameStart -= newDelegate(this, &ProgressBar::frameEntered);
116 mRange = mEndPosition = mStartPosition = 0;
117 }
118 updateTrack();
119 }
120
121 void ProgressBar::frameEntered(float _time)
122 {
123 if (!mAutoTrack) return;
124 mAutoPosition += (PROGRESS_AUTO_COEF * _time);
125 size_t pos = (size_t)mAutoPosition;
126
127 if (pos > (mRange + PROGRESS_AUTO_WIDTH)) mAutoPosition = 0.0f;
128
129 if (pos > mRange) mEndPosition = mRange;
130 else mEndPosition = size_t(mAutoPosition);
131
132 if (pos < PROGRESS_AUTO_WIDTH) mStartPosition = 0;
133 else mStartPosition = pos - PROGRESS_AUTO_WIDTH;
134
135 updateTrack();
136 }
137
139 {
140 Base::setPosition(_point);
141 }
142
143 void ProgressBar::setSize(const IntSize& _size)
144 {
145 Base::setSize(_size);
146
147 updateTrack();
148 }
149
150 void ProgressBar::setCoord(const IntCoord& _coord)
151 {
152 Base::setCoord(_coord);
153
154 updateTrack();
155 }
156
157 void ProgressBar::updateTrack()
158 {
159 // все скрыто
160 if ((0 == mRange) || (0 == mEndPosition))
161 {
162 for (VectorWidgetPtr::iterator iter = mVectorTrack.begin(); iter != mVectorTrack.end(); ++iter)
163 {
164 (*iter)->setVisible(false);
165 }
166 return;
167 }
168
169 // тут попроще расчеты
170 if (mFillTrack)
171 {
172 if (mVectorTrack.empty())
173 {
174 Widget* widget = mTrackPlace->createWidget<Widget>(mTrackSkin, IntCoord(), Align::Left | Align::VStretch);
175 mVectorTrack.push_back(widget);
176 }
177 else
178 {
179 // первый показываем и ставим норм альфу
180 VectorWidgetPtr::iterator iter = mVectorTrack.begin();
181 (*iter)->setVisible(true);
182 (*iter)->setAlpha(ALPHA_MAX);
183
184 // все начиная со второго скрываем
185 ++iter;
186 for (; iter != mVectorTrack.end(); ++iter)
187 {
188 (*iter)->setVisible(false);
189 }
190 }
191
192 Widget* wid = mVectorTrack.front();
193
194 // полностью виден
195 if ((0 == mStartPosition) && (mRange == mEndPosition))
196 {
197 setTrackPosition(wid, 0, 0, getClientWidth(), getClientHeight());
198 }
199 // эх
200 else
201 {
202 int pos = (int)mStartPosition * (getClientWidth() - mTrackMin) / (int)mRange;
203 setTrackPosition(wid, pos, 0, ((int)mEndPosition * (getClientWidth() - mTrackMin) / (int)mRange) - pos + mTrackMin, getClientHeight());
204 }
205
206 return;
207 }
208
209 // сначала проверяем виджеты для трека
210 int width = getClientWidth() - mTrackWidth + mTrackStep;
211 int count = width / mTrackStep;
212 int ost = (width % mTrackStep);
213 if (ost > 0)
214 {
215 width += mTrackStep - ost;
216 count ++;
217 }
218
219 while ((int)mVectorTrack.size() < count)
220 {
221 Widget* widget = mTrackPlace->createWidget<Widget>(mTrackSkin, IntCoord(/*(int)mVectorTrack.size() * mTrackStep, 0, mTrackWidth, getClientHeight()*/), Align::Left | Align::VStretch);
222 widget->setVisible(false);
223 mVectorTrack.push_back(widget);
224 }
225
226 // все видно
227 if ((0 == mStartPosition) && (mRange == mEndPosition))
228 {
229 int pos = 0;
230 for (VectorWidgetPtr::iterator iter = mVectorTrack.begin(); iter != mVectorTrack.end(); ++iter)
231 {
232 (*iter)->setAlpha(ALPHA_MAX);
233 (*iter)->setVisible(true);
234 setTrackPosition(*iter, pos * mTrackStep, 0, mTrackWidth, getClientHeight());
235 pos++;
236 }
237 }
238 // эх, придется считать
239 else
240 {
241 // сколько не видно
242 int hide_pix = (width * (int)mStartPosition / (int)mRange);
243 int hide_count = hide_pix / mTrackStep;
244 // сколько видно
245 int show_pix = (width * (int)mEndPosition / (int)mRange);
246 int show_count = show_pix / mTrackStep;
247
248 int pos = 0;
249 for (VectorWidgetPtr::iterator iter = mVectorTrack.begin(); iter != mVectorTrack.end(); ++iter)
250 {
251 if (0 > show_count)
252 {
253 (*iter)->setVisible(false);
254 }
255 else if (0 == show_count)
256 {
257 (*iter)->setAlpha((float)(show_pix % mTrackStep) / (float)mTrackStep);
258 (*iter)->setVisible(true);
259 setTrackPosition(*iter, pos * mTrackStep, 0, mTrackWidth, getClientHeight());
260 }
261 else
262 {
263 if (0 < hide_count)
264 {
265 (*iter)->setVisible(false);
266 }
267 else if (0 == hide_count)
268 {
269 (*iter)->setAlpha(1.0f - ((float)(hide_pix % mTrackStep) / (float)mTrackStep));
270 (*iter)->setVisible(true);
271 setTrackPosition(*iter, pos * mTrackStep, 0, mTrackWidth, getClientHeight());
272 }
273 else
274 {
275 (*iter)->setAlpha(ALPHA_MAX);
276 (*iter)->setVisible(true);
277 setTrackPosition(*iter, pos * mTrackStep, 0, mTrackWidth, getClientHeight());
278 }
279 }
280 hide_count --;
281 show_count --;
282 pos ++;
283 }
284 }
285 }
286
287 void ProgressBar::setTrackPosition(Widget* _widget, int _left, int _top, int _width, int _height)
288 {
289 if (mFlowDirection == FlowDirection::LeftToRight) _widget->setCoord(_left, _top, _width, _height);
290 else if (mFlowDirection == FlowDirection::RightToLeft) _widget->setCoord(mTrackPlace->getWidth() - _left - _width, _top, _width, _height);
291 else if (mFlowDirection == FlowDirection::TopToBottom) _widget->setCoord(_top, _left, _height, _width);
292 else if (mFlowDirection == FlowDirection::BottomToTop) _widget->setCoord(_top, mTrackPlace->getHeight() - _left - _width, _height, _width);
293 }
294
295 int ProgressBar::getClientWidth() const
296 {
297 return mFlowDirection.isHorizontal() ? mTrackPlace->getWidth() : mTrackPlace->getHeight();
298 }
299
300 int ProgressBar::getClientHeight() const
301 {
302 return mFlowDirection.isHorizontal() ? mTrackPlace->getHeight() : mTrackPlace->getWidth();
303 }
304
306 {
307 mFlowDirection = _value;
308 updateTrack();
309 }
310
311 void ProgressBar::setPropertyOverride(const std::string& _key, const std::string& _value)
312 {
314 if (_key == "Range")
315 setProgressRange(utility::parseValue<size_t>(_value));
316
318 else if (_key == "RangePosition")
319 setProgressPosition(utility::parseValue<size_t>(_value));
320
322 else if (_key == "AutoTrack")
323 setProgressAutoTrack(utility::parseValue<bool>(_value));
324
326 else if (_key == "FlowDirection")
327 setFlowDirection(utility::parseValue<FlowDirection>(_value));
328
329 else
330 {
331 Base::setPropertyOverride(_key, _value);
332 return;
333 }
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} // namespace MyGUI
static Gui & getInstance()
EventHandle_FrameEventDelegate eventFrameStart
Definition: MyGUI_Gui.h:150
void shutdownOverride() override
size_t getProgressRange() const
FlowDirection getFlowDirection() const
void setCoord(const IntCoord &_value) override
void setFlowDirection(FlowDirection _value)
void initialiseOverride() override
bool getProgressAutoTrack() const
void setPropertyOverride(const std::string &_key, const std::string &_value) override
void setSize(const IntSize &_value) override
void setProgressRange(size_t _value)
void setProgressPosition(size_t _value)
void setProgressAutoTrack(bool _value)
void setPosition(const IntPoint &_value) override
size_t getProgressPosition() const
bool isUserString(const std::string &_key) const
const std::string & getUserString(const std::string &_key) const
T * createWidget(const std::string &_skin, const IntCoord &_coord, Align _align, const std::string &_name="")
Definition: MyGUI_Widget.h:67
EventHandle_WidgetStringString eventChangeProperty
Definition: MyGUI_Widget.h:267
void assignWidget(T *&_widget, const std::string &_name)
Definition: MyGUI_Widget.h:335
const size_t PROGRESS_AUTO_WIDTH
const float PROGRESS_AUTO_COEF
types::TCoord< int > IntCoord
Definition: MyGUI_Types.h:35
const size_t PROGRESS_AUTO_RANGE
const float ALPHA_MAX
Definition: MyGUI_Macros.h:19
delegates::DelegateFunction< Args... > * newDelegate(void(*_func)(Args... args))