00001
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include "MyGUI_Precompiled.h"
00024 #include "MyGUI_Progress.h"
00025 #include "MyGUI_ResourceSkin.h"
00026 #include "MyGUI_Widget.h"
00027 #include "MyGUI_Gui.h"
00028 #include "MyGUI_SkinManager.h"
00029
00030 namespace MyGUI
00031 {
00032
00033 const size_t PROGRESS_AUTO_WIDTH = 200;
00034 const size_t PROGRESS_AUTO_RANGE = 1000;
00035 const float PROGRESS_AUTO_COEF = 400;
00036
00037 Progress::Progress() :
00038 mTrackWidth(1),
00039 mTrackStep(0),
00040 mTrackMin(0),
00041 mRange(0),
00042 mStartPosition(0),
00043 mEndPosition(0),
00044 mAutoPosition(0.0f),
00045 mAutoTrack(false),
00046 mFillTrack(false),
00047 mStartPoint(Align::Left),
00048 mClient(nullptr)
00049 {
00050 }
00051
00052 void Progress::_initialise(WidgetStyle _style, const IntCoord& _coord, Align _align, ResourceSkin* _info, Widget* _parent, ICroppedRectangle * _croppedParent, IWidgetCreator * _creator, const std::string& _name)
00053 {
00054 Base::_initialise(_style, _coord, _align, _info, _parent, _croppedParent, _creator, _name);
00055
00056 initialiseWidgetSkin(_info);
00057 }
00058
00059 Progress::~Progress()
00060 {
00061 shutdownWidgetSkin();
00062 }
00063
00064 void Progress::baseChangeWidgetSkin(ResourceSkin* _info)
00065 {
00066 shutdownWidgetSkin();
00067 Base::baseChangeWidgetSkin(_info);
00068 initialiseWidgetSkin(_info);
00069 }
00070
00071 void Progress::initialiseWidgetSkin(ResourceSkin* _info)
00072 {
00073 for (VectorWidgetPtr::iterator iter=mWidgetChildSkin.begin(); iter!=mWidgetChildSkin.end(); ++iter)
00074 {
00075 if (*(*iter)->_getInternalData<std::string>() == "Client")
00076 {
00077 MYGUI_DEBUG_ASSERT( ! mClient, "widget already assigned");
00078 mClient = (*iter);
00079 }
00080 }
00081 if (nullptr == mClient) mClient = this;
00082
00083 const MapString& properties = _info->getProperties();
00084 MapString::const_iterator iterS = properties.find("TrackSkin");
00085 if (iterS != properties.end()) mTrackSkin = iterS->second;
00086 iterS = properties.find("TrackWidth");
00087 if (iterS != properties.end()) mTrackWidth = utility::parseInt(iterS->second);
00088 iterS = properties.find("TrackMin");
00089 if (iterS != properties.end()) mTrackMin = utility::parseInt(iterS->second);
00090 if (1 > mTrackWidth) mTrackWidth = 1;
00091 iterS = properties.find("TrackStep");
00092 if (iterS != properties.end()) mTrackStep = utility::parseInt(iterS->second);
00093 else mTrackStep = mTrackWidth;
00094 iterS = properties.find("TrackFill");
00095 if (iterS != properties.end()) mFillTrack = utility::parseBool(iterS->second);
00096 iterS = properties.find("StartPoint");
00097 if (iterS != properties.end()) setProgressStartPoint(Align::parse(iterS->second));
00098
00099 }
00100
00101 void Progress::shutdownWidgetSkin()
00102 {
00103 mClient = nullptr;
00104 }
00105
00106 void Progress::setProgressRange(size_t _range)
00107 {
00108 if (mAutoTrack) return;
00109 mRange = _range;
00110 if (mEndPosition > mRange) mEndPosition = mRange;
00111 if (mStartPosition > mRange) mStartPosition = mRange;
00112 updateTrack();
00113 }
00114
00115 void Progress::setProgressPosition(size_t _pos)
00116 {
00117 if (mAutoTrack) return;
00118 mEndPosition = _pos;
00119 if (mEndPosition > mRange) mEndPosition = mRange;
00120 updateTrack();
00121 }
00122
00123 void Progress::setProgressAutoTrack(bool _auto)
00124 {
00125 if (mAutoTrack == _auto) return;
00126 mAutoTrack = _auto;
00127
00128 if (mAutoTrack)
00129 {
00130 Gui::getInstance().eventFrameStart += newDelegate(this, &Progress::frameEntered);
00131 mRange = PROGRESS_AUTO_RANGE;
00132 mEndPosition = mStartPosition = 0;
00133 mAutoPosition = 0.0f;
00134 }
00135 else
00136 {
00137 Gui::getInstance().eventFrameStart -= newDelegate(this, &Progress::frameEntered);
00138 mRange = mEndPosition = mStartPosition = 0;
00139 }
00140 updateTrack();
00141 }
00142
00143 void Progress::frameEntered(float _time)
00144 {
00145 if (!mAutoTrack) return;
00146 mAutoPosition += (PROGRESS_AUTO_COEF * _time);
00147 size_t pos = (size_t)mAutoPosition;
00148
00149 if (pos > (mRange + PROGRESS_AUTO_WIDTH)) mAutoPosition = 0.0f;
00150
00151 if (pos > mRange) mEndPosition = mRange;
00152 else mEndPosition = size_t(mAutoPosition);
00153
00154 if (pos < PROGRESS_AUTO_WIDTH) mStartPosition = 0;
00155 else mStartPosition = pos - PROGRESS_AUTO_WIDTH;
00156
00157 updateTrack();
00158 }
00159
00160 void Progress::setPosition(const IntPoint& _point)
00161 {
00162 Base::setPosition(_point);
00163 }
00164
00165 void Progress::setSize(const IntSize& _size)
00166 {
00167 updateTrack();
00168
00169 Base::setSize(_size);
00170 }
00171
00172 void Progress::setCoord(const IntCoord& _coord)
00173 {
00174 updateTrack();
00175
00176 Base::setCoord(_coord);
00177 }
00178
00179 void Progress::updateTrack()
00180 {
00181
00182 if ((0 == mRange) || (0 == mEndPosition))
00183 {
00184 for (VectorWidgetPtr::iterator iter=mVectorTrack.begin(); iter!=mVectorTrack.end(); ++iter)
00185 {
00186 (*iter)->setVisible(false);
00187 }
00188 return;
00189 }
00190
00191
00192 if (mFillTrack)
00193 {
00194 if (mVectorTrack.empty())
00195 {
00196 Widget* widget = mClient->createWidget<Widget>(mTrackSkin, IntCoord(), Align::Left | Align::VStretch);
00197 mVectorTrack.push_back(widget);
00198 }
00199 else
00200 {
00201
00202 VectorWidgetPtr::iterator iter=mVectorTrack.begin();
00203 (*iter)->setVisible(true);
00204 (*iter)->setAlpha(ALPHA_MAX);
00205
00206
00207 ++iter;
00208 for (; iter!=mVectorTrack.end(); ++iter)
00209 {
00210 (*iter)->setVisible(false);
00211 }
00212 }
00213
00214 Widget* wid = mVectorTrack.front();
00215
00216
00217 if ((0 == mStartPosition) && (mRange == mEndPosition))
00218 {
00219 setTrackPosition(wid, 0, 0, getClientWidth(), getClientHeight());
00220 }
00221
00222 else
00223 {
00224 int pos = (int)mStartPosition * (getClientWidth() - mTrackMin) / (int)mRange;
00225 setTrackPosition(wid, pos, 0, ((int)mEndPosition * (getClientWidth() - mTrackMin) / (int)mRange) - pos + mTrackMin, getClientHeight());
00226 }
00227
00228 return;
00229 }
00230
00231
00232 int width = getClientWidth() - mTrackWidth + mTrackStep;
00233 int count = width / mTrackStep;
00234 int ost = (width % mTrackStep);
00235 if (ost > 0)
00236 {
00237 width += mTrackStep - ost;
00238 count ++;
00239 }
00240
00241 while ((int)mVectorTrack.size() < count)
00242 {
00243 Widget* widget = mClient->createWidget<Widget>(mTrackSkin, IntCoord(), Align::Left | Align::VStretch);
00244 widget->setVisible(false);
00245 mVectorTrack.push_back(widget);
00246 }
00247
00248
00249 if ((0 == mStartPosition) && (mRange == mEndPosition))
00250 {
00251 int pos = 0;
00252 for (VectorWidgetPtr::iterator iter=mVectorTrack.begin(); iter!=mVectorTrack.end(); ++iter)
00253 {
00254 (*iter)->setAlpha(ALPHA_MAX);
00255 (*iter)->setVisible(true);
00256 setTrackPosition(*iter, pos * mTrackStep, 0, mTrackWidth, getClientHeight());
00257 pos++;
00258 }
00259 }
00260
00261 else
00262 {
00263
00264 int hide_pix = (width * (int)mStartPosition / (int)mRange);
00265 int hide_count = hide_pix / mTrackStep;
00266
00267 int show_pix = (width * (int)mEndPosition / (int)mRange);
00268 int show_count = show_pix / mTrackStep;
00269
00270 int pos = 0;
00271 for (VectorWidgetPtr::iterator iter=mVectorTrack.begin(); iter!=mVectorTrack.end(); ++iter)
00272 {
00273 if (0 > show_count)
00274 {
00275 (*iter)->setVisible(false);
00276 }
00277 else if (0 == show_count)
00278 {
00279 (*iter)->setAlpha((float)(show_pix % mTrackStep) / (float)mTrackStep);
00280 (*iter)->setVisible(true);
00281 setTrackPosition(*iter, pos * mTrackStep, 0, mTrackWidth, getClientHeight());
00282 }
00283 else
00284 {
00285 if (0 < hide_count)
00286 {
00287 (*iter)->setVisible(false);
00288 }
00289 else if (0 == hide_count)
00290 {
00291 (*iter)->setAlpha(1.0f - ((float)(hide_pix % mTrackStep) / (float)mTrackStep));
00292 (*iter)->setVisible(true);
00293 setTrackPosition(*iter, pos * mTrackStep, 0, mTrackWidth, getClientHeight());
00294 }
00295 else
00296 {
00297 (*iter)->setAlpha(ALPHA_MAX);
00298 (*iter)->setVisible(true);
00299 setTrackPosition(*iter, pos * mTrackStep, 0, mTrackWidth, getClientHeight());
00300 }
00301 }
00302 hide_count --;
00303 show_count --;
00304 pos ++;
00305 }
00306 }
00307 }
00308
00309 void Progress::setTrackPosition(Widget* _widget, int _left, int _top, int _width, int _height)
00310 {
00311 if (mStartPoint.isLeft()) _widget->setCoord(_left, _top, _width, _height);
00312 else if (mStartPoint.isRight()) _widget->setCoord(mClient->getWidth() - _left - _width, _top, _width, _height);
00313 else if (mStartPoint.isTop()) _widget->setCoord(_top, _left, _height, _width);
00314 else if (mStartPoint.isBottom()) _widget->setCoord(_top, mClient->getHeight() - _left - _width, _height, _width);
00315 }
00316
00317 void Progress::setProgressStartPoint(Align _align)
00318 {
00319 if ((_align == Align::Left) || (_align == Align::Right) || (_align == Align::Top) || (_align == Align::Bottom))
00320 {
00321 mStartPoint = _align;
00322 }
00323 else
00324 {
00325 mStartPoint = Align::Left;
00326 MYGUI_LOG(Warning, "Progress bar support only Left, Right, Top or Bottom align values");
00327 }
00328 updateTrack();
00329 }
00330
00331 void Progress::setProperty(const std::string& _key, const std::string& _value)
00332 {
00333 if (_key == "Progress_Range") setProgressRange(utility::parseValue<size_t>(_value));
00334 else if (_key == "Progress_Position") setProgressPosition(utility::parseValue<size_t>(_value));
00335 else if (_key == "Progress_AutoTrack") setProgressAutoTrack(utility::parseValue<bool>(_value));
00336 else if (_key == "Progress_StartPoint") setProgressStartPoint(utility::parseValue<Align>(_value));
00337 else
00338 {
00339 Base::setProperty(_key, _value);
00340 return;
00341 }
00342 eventChangeProperty(this, _key, _value);
00343 }
00344
00345 }