MyGUI
3.0.1
|
00001 00007 /* 00008 This file is part of MyGUI. 00009 00010 MyGUI is free software: you can redistribute it and/or modify 00011 it under the terms of the GNU Lesser General Public License as published by 00012 the Free Software Foundation, either version 3 of the License, or 00013 (at your option) any later version. 00014 00015 MyGUI is distributed in the hope that it will be useful, 00016 but WITHOUT ANY WARRANTY; without even the implied warranty of 00017 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00018 GNU Lesser General Public License for more details. 00019 00020 You should have received a copy of the GNU Lesser General Public License 00021 along with MyGUI. If not, see <http://www.gnu.org/licenses/>. 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(/*(int)mVectorTrack.size() * mTrackStep, 0, mTrackWidth, getClientHeight()*/), 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 } // namespace MyGUI