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