MyGUI 3.0.1

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         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
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines