MyGUI
3.2.1
|
00001 /* 00002 * This source file is part of MyGUI. For the latest info, see http://mygui.info/ 00003 * Distributed under the MIT License 00004 * (See accompanying file COPYING.MIT or copy at http://opensource.org/licenses/MIT) 00005 */ 00006 00007 #include "MyGUI_Precompiled.h" 00008 #include "MyGUI_ProgressBar.h" 00009 #include "MyGUI_ResourceSkin.h" 00010 #include "MyGUI_Widget.h" 00011 #include "MyGUI_Gui.h" 00012 #include "MyGUI_SkinManager.h" 00013 00014 namespace MyGUI 00015 { 00016 00017 const size_t PROGRESS_AUTO_WIDTH = 200; 00018 const size_t PROGRESS_AUTO_RANGE = 1000; 00019 const float PROGRESS_AUTO_COEF = 400; 00020 00021 ProgressBar::ProgressBar() : 00022 mTrackWidth(1), 00023 mTrackStep(0), 00024 mTrackMin(0), 00025 mRange(0), 00026 mStartPosition(0), 00027 mEndPosition(0), 00028 mAutoPosition(0.0f), 00029 mAutoTrack(false), 00030 mFillTrack(false), 00031 mClient(nullptr) 00032 { 00033 } 00034 00035 void ProgressBar::initialiseOverride() 00036 { 00037 Base::initialiseOverride(); 00038 00040 assignWidget(mClient, "TrackPlace"); 00041 00042 if (nullptr == mClient) 00043 { 00044 //OBSOLETE 00045 assignWidget(mClient, "Client"); 00046 00047 if (nullptr == mClient) 00048 mClient = this; 00049 } 00050 00051 if (isUserString("TrackSkin")) 00052 mTrackSkin = getUserString("TrackSkin"); 00053 00054 if (isUserString("TrackWidth")) 00055 mTrackWidth = utility::parseValue<int>(getUserString("TrackWidth")); 00056 00057 //OBSOLETE 00058 if (isUserString("TrackMin")) 00059 mTrackMin = utility::parseValue<int>(getUserString("TrackMin")); 00060 00061 else 00062 mTrackMin = mTrackWidth; 00063 00064 if (isUserString("TrackStep")) 00065 mTrackStep = utility::parseValue<int>(getUserString("TrackStep")); 00066 00067 if (isUserString("TrackFill")) 00068 mFillTrack = utility::parseValue<bool>(getUserString("TrackFill")); 00069 00070 if (!isUserString("TrackStep")) 00071 mTrackStep = mTrackWidth; 00072 00073 if (1 > mTrackWidth) 00074 mTrackWidth = 1; 00075 } 00076 00077 void ProgressBar::shutdownOverride() 00078 { 00079 mClient = nullptr; 00080 00081 Base::shutdownOverride(); 00082 } 00083 00084 void ProgressBar::setProgressRange(size_t _range) 00085 { 00086 if (mAutoTrack) return; 00087 mRange = _range; 00088 if (mEndPosition > mRange) mEndPosition = mRange; 00089 if (mStartPosition > mRange) mStartPosition = mRange; 00090 updateTrack(); 00091 } 00092 00093 void ProgressBar::setProgressPosition(size_t _pos) 00094 { 00095 if (mAutoTrack) return; 00096 mEndPosition = _pos; 00097 if (mEndPosition > mRange) mEndPosition = mRange; 00098 updateTrack(); 00099 } 00100 00101 void ProgressBar::setProgressAutoTrack(bool _auto) 00102 { 00103 if (mAutoTrack == _auto) return; 00104 mAutoTrack = _auto; 00105 00106 if (mAutoTrack) 00107 { 00108 Gui::getInstance().eventFrameStart += newDelegate(this, &ProgressBar::frameEntered); 00109 mRange = PROGRESS_AUTO_RANGE; 00110 mEndPosition = mStartPosition = 0; 00111 mAutoPosition = 0.0f; 00112 } 00113 else 00114 { 00115 Gui::getInstance().eventFrameStart -= newDelegate(this, &ProgressBar::frameEntered); 00116 mRange = mEndPosition = mStartPosition = 0; 00117 } 00118 updateTrack(); 00119 } 00120 00121 void ProgressBar::frameEntered(float _time) 00122 { 00123 if (!mAutoTrack) return; 00124 mAutoPosition += (PROGRESS_AUTO_COEF * _time); 00125 size_t pos = (size_t)mAutoPosition; 00126 00127 if (pos > (mRange + PROGRESS_AUTO_WIDTH)) mAutoPosition = 0.0f; 00128 00129 if (pos > mRange) mEndPosition = mRange; 00130 else mEndPosition = size_t(mAutoPosition); 00131 00132 if (pos < PROGRESS_AUTO_WIDTH) mStartPosition = 0; 00133 else mStartPosition = pos - PROGRESS_AUTO_WIDTH; 00134 00135 updateTrack(); 00136 } 00137 00138 void ProgressBar::setPosition(const IntPoint& _point) 00139 { 00140 Base::setPosition(_point); 00141 } 00142 00143 void ProgressBar::setSize(const IntSize& _size) 00144 { 00145 Base::setSize(_size); 00146 00147 updateTrack(); 00148 } 00149 00150 void ProgressBar::setCoord(const IntCoord& _coord) 00151 { 00152 Base::setCoord(_coord); 00153 00154 updateTrack(); 00155 } 00156 00157 void ProgressBar::updateTrack() 00158 { 00159 // все скрыто 00160 if ((0 == mRange) || (0 == mEndPosition)) 00161 { 00162 for (VectorWidgetPtr::iterator iter = mVectorTrack.begin(); iter != mVectorTrack.end(); ++iter) 00163 { 00164 (*iter)->setVisible(false); 00165 } 00166 return; 00167 } 00168 00169 // тут попроще расчеты 00170 if (mFillTrack) 00171 { 00172 if (mVectorTrack.empty()) 00173 { 00174 Widget* widget = mClient->createWidget<Widget>(mTrackSkin, IntCoord(), Align::Left | Align::VStretch); 00175 mVectorTrack.push_back(widget); 00176 } 00177 else 00178 { 00179 // первый показываем и ставим норм альфу 00180 VectorWidgetPtr::iterator iter = mVectorTrack.begin(); 00181 (*iter)->setVisible(true); 00182 (*iter)->setAlpha(ALPHA_MAX); 00183 00184 // все начиная со второго скрываем 00185 ++iter; 00186 for (; iter != mVectorTrack.end(); ++iter) 00187 { 00188 (*iter)->setVisible(false); 00189 } 00190 } 00191 00192 Widget* wid = mVectorTrack.front(); 00193 00194 // полностью виден 00195 if ((0 == mStartPosition) && (mRange == mEndPosition)) 00196 { 00197 setTrackPosition(wid, 0, 0, getClientWidth(), getClientHeight()); 00198 } 00199 // эх 00200 else 00201 { 00202 int pos = (int)mStartPosition * (getClientWidth() - mTrackMin) / (int)mRange; 00203 setTrackPosition(wid, pos, 0, ((int)mEndPosition * (getClientWidth() - mTrackMin) / (int)mRange) - pos + mTrackMin, getClientHeight()); 00204 } 00205 00206 return; 00207 } 00208 00209 // сначала проверяем виджеты для трека 00210 int width = getClientWidth() - mTrackWidth + mTrackStep; 00211 int count = width / mTrackStep; 00212 int ost = (width % mTrackStep); 00213 if (ost > 0) 00214 { 00215 width += mTrackStep - ost; 00216 count ++; 00217 } 00218 00219 while ((int)mVectorTrack.size() < count) 00220 { 00221 Widget* widget = mClient->createWidget<Widget>(mTrackSkin, IntCoord(/*(int)mVectorTrack.size() * mTrackStep, 0, mTrackWidth, getClientHeight()*/), Align::Left | Align::VStretch); 00222 widget->setVisible(false); 00223 mVectorTrack.push_back(widget); 00224 } 00225 00226 // все видно 00227 if ((0 == mStartPosition) && (mRange == mEndPosition)) 00228 { 00229 int pos = 0; 00230 for (VectorWidgetPtr::iterator iter = mVectorTrack.begin(); iter != mVectorTrack.end(); ++iter) 00231 { 00232 (*iter)->setAlpha(ALPHA_MAX); 00233 (*iter)->setVisible(true); 00234 setTrackPosition(*iter, pos * mTrackStep, 0, mTrackWidth, getClientHeight()); 00235 pos++; 00236 } 00237 } 00238 // эх, придется считать 00239 else 00240 { 00241 // сколько не видно 00242 int hide_pix = (width * (int)mStartPosition / (int)mRange); 00243 int hide_count = hide_pix / mTrackStep; 00244 // сколько видно 00245 int show_pix = (width * (int)mEndPosition / (int)mRange); 00246 int show_count = show_pix / mTrackStep; 00247 00248 int pos = 0; 00249 for (VectorWidgetPtr::iterator iter = mVectorTrack.begin(); iter != mVectorTrack.end(); ++iter) 00250 { 00251 if (0 > show_count) 00252 { 00253 (*iter)->setVisible(false); 00254 } 00255 else if (0 == show_count) 00256 { 00257 (*iter)->setAlpha((float)(show_pix % mTrackStep) / (float)mTrackStep); 00258 (*iter)->setVisible(true); 00259 setTrackPosition(*iter, pos * mTrackStep, 0, mTrackWidth, getClientHeight()); 00260 } 00261 else 00262 { 00263 if (0 < hide_count) 00264 { 00265 (*iter)->setVisible(false); 00266 } 00267 else if (0 == hide_count) 00268 { 00269 (*iter)->setAlpha(1.0f - ((float)(hide_pix % mTrackStep) / (float)mTrackStep)); 00270 (*iter)->setVisible(true); 00271 setTrackPosition(*iter, pos * mTrackStep, 0, mTrackWidth, getClientHeight()); 00272 } 00273 else 00274 { 00275 (*iter)->setAlpha(ALPHA_MAX); 00276 (*iter)->setVisible(true); 00277 setTrackPosition(*iter, pos * mTrackStep, 0, mTrackWidth, getClientHeight()); 00278 } 00279 } 00280 hide_count --; 00281 show_count --; 00282 pos ++; 00283 } 00284 } 00285 } 00286 00287 void ProgressBar::setTrackPosition(Widget* _widget, int _left, int _top, int _width, int _height) 00288 { 00289 if (mFlowDirection == FlowDirection::LeftToRight) _widget->setCoord(_left, _top, _width, _height); 00290 else if (mFlowDirection == FlowDirection::RightToLeft) _widget->setCoord(mClient->getWidth() - _left - _width, _top, _width, _height); 00291 else if (mFlowDirection == FlowDirection::TopToBottom) _widget->setCoord(_top, _left, _height, _width); 00292 else if (mFlowDirection == FlowDirection::BottomToTop) _widget->setCoord(_top, mClient->getHeight() - _left - _width, _height, _width); 00293 } 00294 00295 int ProgressBar::getClientWidth() 00296 { 00297 return mFlowDirection.isHorizontal() ? mClient->getWidth() : mClient->getHeight(); 00298 } 00299 00300 int ProgressBar::getClientHeight() 00301 { 00302 return mFlowDirection.isHorizontal() ? mClient->getHeight() : mClient->getWidth(); 00303 } 00304 00305 void ProgressBar::setFlowDirection(FlowDirection _value) 00306 { 00307 mFlowDirection = _value; 00308 updateTrack(); 00309 } 00310 00311 void ProgressBar::setPropertyOverride(const std::string& _key, const std::string& _value) 00312 { 00314 if (_key == "Range") 00315 setProgressRange(utility::parseValue<size_t>(_value)); 00316 00318 else if (_key == "RangePosition") 00319 setProgressPosition(utility::parseValue<size_t>(_value)); 00320 00322 else if (_key == "AutoTrack") 00323 setProgressAutoTrack(utility::parseValue<bool>(_value)); 00324 00326 else if (_key == "FlowDirection") 00327 setFlowDirection(utility::parseValue<FlowDirection>(_value)); 00328 00329 else 00330 { 00331 Base::setPropertyOverride(_key, _value); 00332 return; 00333 } 00334 00335 eventChangeProperty(this, _key, _value); 00336 } 00337 00338 size_t ProgressBar::getProgressRange() const 00339 { 00340 return mRange; 00341 } 00342 00343 size_t ProgressBar::getProgressPosition() const 00344 { 00345 return mEndPosition; 00346 } 00347 00348 bool ProgressBar::getProgressAutoTrack() const 00349 { 00350 return mAutoTrack; 00351 } 00352 00353 FlowDirection ProgressBar::getFlowDirection() const 00354 { 00355 return mFlowDirection; 00356 } 00357 00358 void ProgressBar::setPosition(int _left, int _top) 00359 { 00360 setPosition(IntPoint(_left, _top)); 00361 } 00362 00363 void ProgressBar::setSize(int _width, int _height) 00364 { 00365 setSize(IntSize(_width, _height)); 00366 } 00367 00368 void ProgressBar::setCoord(int _left, int _top, int _width, int _height) 00369 { 00370 setCoord(IntCoord(_left, _top, _width, _height)); 00371 } 00372 00373 } // namespace MyGUI