• Main Page
  • Related Pages
  • Namespaces
  • Data Structures
  • Files
  • Examples
  • File List
  • Globals

MyGUI_Progress.cpp

Go to the documentation of this file.
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         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     /*void Progress::setProgressFillTrack(bool _fill)
00175     {
00176         mFillTrack = _fill;
00177         updateTrack();
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(/*(int)mVectorTrack.size() * mTrackStep, 0, mTrackWidth, getClientHeight()*/), 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 } // namespace MyGUI

Generated on Sun Jan 30 2011 for MyGUI by  doxygen 1.7.1