MyGUI 3.4.3
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 {
24
26 assignWidget(mTrackPlace, "TrackPlace");
27
28 if (nullptr == mTrackPlace)
29 {
30 //OBSOLETE
31 assignWidget(mTrackPlace, "Client");
32
33 if (nullptr == mTrackPlace)
34 mTrackPlace = this;
35 }
36
37 if (isUserString("TrackSkin"))
38 mTrackSkin = getUserString("TrackSkin");
39
40 if (isUserString("TrackWidth"))
41 mTrackWidth = utility::parseValue<int>(getUserString("TrackWidth"));
42
43 //OBSOLETE
44 if (isUserString("TrackMin"))
45 mTrackMin = utility::parseValue<int>(getUserString("TrackMin"));
46
47 else
48 mTrackMin = mTrackWidth;
49
50 if (isUserString("TrackStep"))
51 mTrackStep = utility::parseValue<int>(getUserString("TrackStep"));
52
53 if (isUserString("TrackFill"))
54 mFillTrack = utility::parseValue<bool>(getUserString("TrackFill"));
55
56 if (!isUserString("TrackStep"))
57 mTrackStep = mTrackWidth;
58
59 if (1 > mTrackWidth)
60 mTrackWidth = 1;
61 }
62
64 {
65 mTrackPlace = nullptr;
66
68 }
69
71 {
72 if (mAutoTrack)
73 return;
74 mRange = _range;
75 if (mEndPosition > mRange)
76 mEndPosition = mRange;
77 if (mStartPosition > mRange)
78 mStartPosition = mRange;
79 updateTrack();
80 }
81
83 {
84 if (mAutoTrack)
85 return;
86 mEndPosition = _pos;
87 if (mEndPosition > mRange)
88 mEndPosition = mRange;
89 updateTrack();
90 }
91
93 {
94 if (mAutoTrack == _auto)
95 return;
96 mAutoTrack = _auto;
97
98 if (mAutoTrack)
99 {
100 Gui::getInstance().eventFrameStart += newDelegate(this, &ProgressBar::frameEntered);
101 mRange = PROGRESS_AUTO_RANGE;
102 mEndPosition = mStartPosition = 0;
103 mAutoPosition = 0.0f;
104 }
105 else
106 {
107 Gui::getInstance().eventFrameStart -= newDelegate(this, &ProgressBar::frameEntered);
108 mRange = mEndPosition = mStartPosition = 0;
109 }
110 updateTrack();
111 }
112
113 void ProgressBar::frameEntered(float _time)
114 {
115 if (!mAutoTrack)
116 return;
117 mAutoPosition += (PROGRESS_AUTO_COEF * _time);
118 size_t pos = (size_t)mAutoPosition;
119
120 if (pos > (mRange + PROGRESS_AUTO_WIDTH))
121 mAutoPosition = 0.0f;
122
123 if (pos > mRange)
124 mEndPosition = mRange;
125 else
126 mEndPosition = size_t(mAutoPosition);
127
128 if (pos < PROGRESS_AUTO_WIDTH)
129 mStartPosition = 0;
130 else
131 mStartPosition = pos - PROGRESS_AUTO_WIDTH;
132
133 updateTrack();
134 }
135
137 {
138 Base::setPosition(_point);
139 }
140
141 void ProgressBar::setSize(const IntSize& _size)
142 {
143 Base::setSize(_size);
144
145 updateTrack();
146 }
147
148 void ProgressBar::setCoord(const IntCoord& _coord)
149 {
150 Base::setCoord(_coord);
151
152 updateTrack();
153 }
154
155 void ProgressBar::updateTrack()
156 {
157 // все скрыто
158 if ((0 == mRange) || (0 == mEndPosition))
159 {
160 for (auto& iter : mVectorTrack)
161 {
162 iter->setVisible(false);
163 }
164 return;
165 }
166
167 // тут попроще расчеты
168 if (mFillTrack)
169 {
170 if (mVectorTrack.empty())
171 {
172 Widget* widget =
173 mTrackPlace->createWidget<Widget>(mTrackSkin, IntCoord(), Align::Left | Align::VStretch);
174 mVectorTrack.push_back(widget);
175 }
176 else
177 {
178 // первый показываем и ставим норм альфу
179 VectorWidgetPtr::iterator iter = mVectorTrack.begin();
180 (*iter)->setVisible(true);
181 (*iter)->setAlpha(ALPHA_MAX);
182
183 // все начиная со второго скрываем
184 ++iter;
185 for (; iter != mVectorTrack.end(); ++iter)
186 {
187 (*iter)->setVisible(false);
188 }
189 }
190
191 Widget* wid = mVectorTrack.front();
192
193 // полностью виден
194 if ((0 == mStartPosition) && (mRange == mEndPosition))
195 {
196 setTrackPosition(wid, 0, 0, getClientWidth(), getClientHeight());
197 }
198 // эх
199 else
200 {
201 int pos = (int)mStartPosition * (getClientWidth() - mTrackMin) / (int)mRange;
202 setTrackPosition(
203 wid,
204 pos,
205 0,
206 ((int)mEndPosition * (getClientWidth() - mTrackMin) / (int)mRange) - pos + mTrackMin,
207 getClientHeight());
208 }
209
210 return;
211 }
212
213 // сначала проверяем виджеты для трека
214 int width = getClientWidth() - mTrackWidth + mTrackStep;
215 int count = width / mTrackStep;
216 int ost = (width % mTrackStep);
217 if (ost > 0)
218 {
219 width += mTrackStep - ost;
220 count++;
221 }
222
223 while ((int)mVectorTrack.size() < count)
224 {
225 Widget* widget = mTrackPlace->createWidget<Widget>(
226 mTrackSkin,
227 IntCoord(/*(int)mVectorTrack.size() * mTrackStep, 0, mTrackWidth, getClientHeight()*/),
229 widget->setVisible(false);
230 mVectorTrack.push_back(widget);
231 }
232
233 // все видно
234 if ((0 == mStartPosition) && (mRange == mEndPosition))
235 {
236 int pos = 0;
237 for (auto& iter : mVectorTrack)
238 {
239 iter->setAlpha(ALPHA_MAX);
240 iter->setVisible(true);
241 setTrackPosition(iter, pos * mTrackStep, 0, mTrackWidth, getClientHeight());
242 pos++;
243 }
244 }
245 // эх, придется считать
246 else
247 {
248 // сколько не видно
249 int hide_pix = (width * (int)mStartPosition / (int)mRange);
250 int hide_count = hide_pix / mTrackStep;
251 // сколько видно
252 int show_pix = (width * (int)mEndPosition / (int)mRange);
253 int show_count = show_pix / mTrackStep;
254
255 int pos = 0;
256 for (auto& iter : mVectorTrack)
257 {
258 if (0 > show_count)
259 {
260 iter->setVisible(false);
261 }
262 else if (0 == show_count)
263 {
264 iter->setAlpha((float)(show_pix % mTrackStep) / (float)mTrackStep);
265 iter->setVisible(true);
266 setTrackPosition(iter, pos * mTrackStep, 0, mTrackWidth, getClientHeight());
267 }
268 else
269 {
270 if (0 < hide_count)
271 {
272 iter->setVisible(false);
273 }
274 else if (0 == hide_count)
275 {
276 iter->setAlpha(1.0f - ((float)(hide_pix % mTrackStep) / (float)mTrackStep));
277 iter->setVisible(true);
278 setTrackPosition(iter, pos * mTrackStep, 0, mTrackWidth, getClientHeight());
279 }
280 else
281 {
282 iter->setAlpha(ALPHA_MAX);
283 iter->setVisible(true);
284 setTrackPosition(iter, pos * mTrackStep, 0, mTrackWidth, getClientHeight());
285 }
286 }
287 hide_count--;
288 show_count--;
289 pos++;
290 }
291 }
292 }
293
294 void ProgressBar::setTrackPosition(Widget* _widget, int _left, int _top, int _width, int _height)
295 {
296 if (mFlowDirection == FlowDirection::LeftToRight)
297 _widget->setCoord(_left, _top, _width, _height);
298 else if (mFlowDirection == FlowDirection::RightToLeft)
299 _widget->setCoord(mTrackPlace->getWidth() - _left - _width, _top, _width, _height);
300 else if (mFlowDirection == FlowDirection::TopToBottom)
301 _widget->setCoord(_top, _left, _height, _width);
302 else if (mFlowDirection == FlowDirection::BottomToTop)
303 _widget->setCoord(_top, mTrackPlace->getHeight() - _left - _width, _height, _width);
304 }
305
306 int ProgressBar::getClientWidth() const
307 {
308 return mFlowDirection.isHorizontal() ? mTrackPlace->getWidth() : mTrackPlace->getHeight();
309 }
310
311 int ProgressBar::getClientHeight() const
312 {
313 return mFlowDirection.isHorizontal() ? mTrackPlace->getHeight() : mTrackPlace->getWidth();
314 }
315
317 {
318 mFlowDirection = _value;
319 updateTrack();
320 }
321
322 void ProgressBar::setPropertyOverride(std::string_view _key, std::string_view _value)
323 {
325 if (_key == "Range")
327
329 else if (_key == "RangePosition")
331
333 else if (_key == "AutoTrack")
335
337 else if (_key == "FlowDirection")
339
340 else
341 {
342 Base::setPropertyOverride(_key, _value);
343 return;
344 }
345
346 eventChangeProperty(this, _key, _value);
347 }
348
350 {
351 return mRange;
352 }
353
355 {
356 return mEndPosition;
357 }
358
360 {
361 return mAutoTrack;
362 }
363
365 {
366 return mFlowDirection;
367 }
368
369} // namespace MyGUI
static Gui & getInstance()
Definition MyGUI_Gui.cpp:34
EventHandle_FrameEventDelegate eventFrameStart
Definition MyGUI_Gui.h:215
void shutdownOverride() override
void setSize(const IntSize &_size) override
size_t getProgressRange() const
FlowDirection getFlowDirection() const
void setFlowDirection(FlowDirection _value)
void setCoord(const IntCoord &_coord) override
void setProgressRange(size_t _range)
void initialiseOverride() override
bool getProgressAutoTrack() const
void setPropertyOverride(std::string_view _key, std::string_view _value) override
void setPosition(const IntPoint &_point) override
void setProgressPosition(size_t _pos)
void setProgressAutoTrack(bool _auto)
size_t getProgressPosition() const
bool isUserString(std::string_view _key) const
std::string_view getUserString(std::string_view _key) const
widget description should be here.
EventHandle_WidgetStringString eventChangeProperty
void assignWidget(T *&_widget, std::string_view _name)
T parseValue(std::string_view _value)
constexpr float ALPHA_MAX
types::TPoint< int > IntPoint
Definition MyGUI_Types.h:27
const size_t PROGRESS_AUTO_WIDTH
const float PROGRESS_AUTO_COEF
types::TCoord< int > IntCoord
Definition MyGUI_Types.h:36
types::TSize< int > IntSize
Definition MyGUI_Types.h:30
const size_t PROGRESS_AUTO_RANGE
delegates::DelegateFunction< Args... > * newDelegate(void(*_func)(Args... args))