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