| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392 |
- #include "ProgressBar.h"
- #include "RenderState.h"
- #include <sstream>
- #include "Serialize.h"
- #include "STDRenderer.h"
- namespace oxygine
- {
- void fill_tex_coord(vertexPCT2& vt, unsigned int rgba, const Vector2& pnt, float nu, float nv)
- {
- vt.color = rgba;
- vt.z = 0;
- vt.x = pnt.x;
- vt.y = pnt.y;
- vt.u = nu;
- vt.v = nv;
- }
- void rotateVector(Vector2& v, float rad)
- {
- Vector2 vh;
- vh.x = v.x * cosf(rad) - v.y * sinf(rad);
- vh.y = v.x * sinf(rad) + v.y * cosf(rad);
- v = vh;
- }
- float Angle(const Vector2& current, const Vector2* pRelative)
- {
- if (pRelative)
- {
- Vector2 s = current, t = *pRelative;
- s.normalize(); t.normalize();
- return acosf(s.dot(t));
- }
- else return atan2f(current.y, current.x);
- }
- ProgressBar::ProgressBar(): _progress(1.0f), _direction(dir_0)
- {
- }
- ProgressBar::~ProgressBar()
- {
- }
- void ProgressBar::copyFrom(const ProgressBar& src, cloneOptions opt)
- {
- _Sprite::copyFrom(src, opt);
- _progress = src._progress;
- _direction = src._direction;
- _originalFrame = src._originalFrame;
- }
- void ProgressBar::animFrameChanged(const AnimationFrame& f)
- {
- _originalFrame = f;
- _update();
- }
- void ProgressBar::_update()
- {
- if (!_frame.getDiffuse().base)
- return;
- RectF newSrc = _originalFrame.getSrcRect();
- RectF newDest = _originalFrame.getDestRect();
- float inv_progress = 1.0f - _progress;
- switch (_direction)
- {
- case dir_180:
- newSrc.pos.x += newSrc.size.x * inv_progress;
- newDest.pos.x += newDest.size.x * inv_progress;
- //break; do not break
- case dir_0:
- newSrc.size.x = newSrc.size.x * _progress;
- newDest.size.x = newDest.size.x * _progress;
- break;
- case dir_90:
- newSrc.pos.y += newSrc.size.y * inv_progress;
- newDest.pos.y += newDest.size.y * inv_progress;
- //break; do not break
- case dir_270:
- newSrc.size.y = newSrc.size.y * _progress;
- newDest.size.y = newDest.size.y * _progress;
- break;
- }
- Vector2 newSize = _originalFrame.getSize() * _progress;
- _frame.init(_frame.getResAnim(), _frame.getDiffuse(), newSrc, newDest, newSize);
- //_vstyle._material.srcRect = newSrc;
- }
- void ProgressBar::doRender(const RenderState& rs)
- {
- if (_progress == 0)
- return;
- if (((_direction != __dir_radial_ccw) && (_direction != dir_radial_cw)) || (_progress == 1.0f))
- {
- _Sprite::doRender(rs);
- return;
- }
- STDRenderer* renderer = safeCast<STDRenderer*>(rs.renderer);
- _vstyle._apply(rs);
- const Diffuse& df = _frame.getDiffuse();
- if (df.base)
- {
- renderer->setTexture(df.base, df.alpha, df.premultiplied);
- RectF destRect = _Sprite::getDestRect();
- RectF srcRect = _frame.getSrcRect();
- float u = srcRect.pos.x;
- float v = srcRect.pos.y;
- float du = srcRect.size.x;
- float dv = srcRect.size.y;
- u += du / 2.f;
- v += dv / 2.f;
- Vector2 pos = destRect.pos;
- const Vector2& size = destRect.size;
- pos += size / 2.f;
- Vector2 vecCenter(pos.x, pos.y);
- Vector2 vdiag = Vector2(pos.x + size.x / 2.f, pos.y - size.y / 2.f) - vecCenter;
- Vector2 vdiag2 = Vector2(pos.x + size.x / 2.f, pos.y + size.y / 2.f) - vecCenter;
- float lenDiag = vdiag.length();
- Vector2 vecCircle(pos.x, pos.y - lenDiag);
- Vector2 vecRad = vecCircle - vecCenter;
- float progress = _progress;
- float fP = MATH_PI * 2.f * progress;
- rotateVector(vecRad, fP);
- Vector2 p1(0.f, 0.f);
- Vector2 p2(0.f, 0.f);
- Vector2 p3(0.f, 0.f);
- Vector2 vert(0.f, -1.f);
- float fA1 = Angle(vdiag, &vert);
- float fA2 = Angle(vdiag2, &vdiag);
- const int MAX_TRI = 6;
- float u1, v1, u2, v2, u3, v3;
- float result = 0.f;
- float angles[ 6 ];
- angles[ 0 ] = fA1;
- angles[ 1 ] = fA2;
- angles[ 2 ] = fA1;
- angles[ 3 ] = fA1;
- angles[ 4 ] = fA2;
- angles[ 5 ] = fA1;
- for (int i = 0; i < MAX_TRI; i++)
- {
- float limitLo = 0.f;
- float limitHi = 0.f;
- for (int j = 0; j < i; j++)
- limitLo += angles[ j ];
- limitHi = limitLo + angles[ i ];
- bool bOverHi = fP > limitHi;
- bool bOverLo = fP < limitLo;
- if (i && bOverLo)
- continue;
- vertexPCT2 vertices[4];
- vertexPCT2* pv = vertices;
- switch (i)
- {
- case 0:
- {
- result = bOverHi ? size.x / 2.f : vecRad.x;
- p1 = Vector2(pos.x, pos.y);
- p2 = Vector2(pos.x, pos.y - size.y / 2.f);
- p3 = Vector2(pos.x + result, pos.y - size.y / 2.f);
- float fPercent = result / size.x;
- float fDU = du * fPercent;
- u1 = u;
- v1 = v;
- u2 = u;
- v2 = (v - dv / 2.f);
- u3 = (u + fDU);
- v3 = (v - dv / 2.f);
- }
- break;
- case 1:
- {
- result = bOverHi ? size.y / 2.f : (vecRad.y) ;
- p1 = Vector2(pos.x, pos.y);
- p2 = Vector2(pos.x + size.x / 2.f, pos.y - size.y / 2.f);
- p3 = Vector2(pos.x + size.x / 2.f, pos.y + result);
- float fPercent = result / size.y;
- float fDV = dv * fPercent;
- u2 = u + du / 2.f;
- v2 = (v - dv / 2.f);
- u3 = u + du / 2.f;
- v3 = (v + fDV);
- }
- break;
- case 2:
- {
- result = bOverHi ? 0.f : vecRad.x ;
- p1 = Vector2(pos.x, pos.y);
- p2 = Vector2(pos.x + size.x / 2.f, pos.y + size.y / 2.f);
- p3 = Vector2(pos.x + result, pos.y + size.y / 2.f);
- float fPercent = result / size.x;
- float fDU = du * fPercent;
- u2 = u + du / 2.f;
- v2 = (v + dv / 2.f);
- u3 = u + fDU;
- v3 = (v + dv / 2.f);
- }
- break;
- case 3:
- {
- result = bOverHi ? (-size.x / 2.f) : vecRad.x ;
- p1 = Vector2(pos.x, pos.y);
- p2 = Vector2(pos.x , pos.y + size.y / 2.f);
- p3 = Vector2(pos.x + result, pos.y + size.y / 2.f);
- float fPercent = result / size.x;
- float fDU = du * fPercent;
- u2 = u;
- v2 = (v + dv / 2.f);
- u3 = u + fDU;
- v3 = (v + dv / 2.f);
- }
- break;
- case 4:
- {
- result = bOverHi ? (-size.y / 2.f) : vecRad.y ;
- p1 = Vector2(pos.x, pos.y);
- p2 = Vector2(pos.x - (size.x / 2.f) , pos.y + size.y / 2.f);
- p3 = Vector2(pos.x - (size.x / 2.f), pos.y + result);
- float fPercent = result / size.y;
- float fDV = dv * fPercent;
- u2 = u - du / 2.f;
- v2 = (v + dv / 2.f);
- u3 = u - du / 2.f;
- v3 = (v + fDV);
- }
- break;
- case 5:
- {
- result = bOverHi ? (0.f) : vecRad.x ;
- p1 = Vector2(pos.x, pos.y);
- p2 = Vector2(pos.x - (size.x / 2.f), pos.y - (size.y / 2.f));
- p3 = Vector2(pos.x + result, pos.y - (size.y / 2.f));
- float fPercent = result / size.x;
- float fDU = du * fPercent;
- u2 = u - du / 2.f;
- v2 = (v - dv / 2.f);
- u3 = u + fDU;
- v3 = (v - dv / 2.f);
- }
- break;
- default:
- continue;
- }
- u1 = u;
- v1 = v;
- p1 = rs.transform.transform(p1);
- p2 = rs.transform.transform(p2);
- p3 = rs.transform.transform(p3);
- unsigned int rgba = getColor().rgba();
- fill_tex_coord(*pv, rgba, p1, u1, v1);
- pv++;
- fill_tex_coord(*pv, rgba, p2, u2, v2);
- pv++;
- fill_tex_coord(*pv, rgba, p3, u3, v3);
- pv++;
- fill_tex_coord(*pv, rgba, p2, u2, v2);
- pv++;
- rs.renderer->addVertices(vertices, sizeof(vertices));
- }
- }
- }
- std::string ProgressBar::dump(const dumpOptions& options) const
- {
- std::stringstream stream;
- stream << "{ProgressBar}\n";
- const char* dir = "dir_0";
- switch (_direction)
- {
- case dir_90:
- dir = "dir_90";
- break;
- case dir_180:
- dir = "dir_180";
- break;
- case dir_270:
- dir = "dir_270";
- break;
- case dir_radial_cw:
- dir = "dir_radial_cw";
- break;
- case __dir_radial_ccw:
- dir = "dir_radial_ccw";
- break;
- }
- stream << " direction=" << dir << "";
- stream << "\n" << _Sprite::dump(options);
- return stream.str();
- }
- RectF ProgressBar::getDestRect() const
- {
- return calcDestRectF(_frame.getDestRect(), _frame.getSize());
- }
- void ProgressBar::setProgress(float f)
- {
- _progress = scalar::clamp(f, 0.0f, 1.0f);
- Event ev(PROGRESS_CHANGED);
- dispatchEvent(&ev);
- if (_direction == __dir_radial_ccw || _direction == dir_radial_cw)
- return;
- _update();
- }
- void ProgressBar::setDirection(direction dir)
- {
- _direction = dir;
- if (_direction == __dir_radial_ccw || _direction == dir_radial_cw)
- {
- _frame = _originalFrame;
- return;
- }
- _update();
- }
- float ProgressBar::getProgress() const
- {
- return _progress;
- }
- ProgressBar::direction ProgressBar::getDirection() const
- {
- return _direction;
- }
- void ProgressBar::serialize(serializedata* data)
- {
- _Sprite::serialize(data);
- pugi::xml_node node = data->node;
- data->node.set_name("ProgressBar");
- data->node.append_attribute("progress").set_value(_progress);
- data->node.append_attribute("direction").set_value((int)_direction);
- }
- void ProgressBar::deserialize(const deserializedata* data)
- {
- _Sprite::deserialize(data);
- _direction = (direction)data->node.attribute("direction").as_int();
- _progress = data->node.attribute("progress").as_float(1.0f);
- }
- }
|