mirror of
https://github.com/telegramdesktop/tdesktop
synced 2025-08-31 14:38:15 +00:00
animations refactored
This commit is contained in:
@@ -26,7 +26,7 @@ Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
|
||||
#include "window.h"
|
||||
|
||||
namespace {
|
||||
AnimationManager *manager = 0;
|
||||
AnimationManager *_manager = 0;
|
||||
};
|
||||
|
||||
namespace anim {
|
||||
@@ -78,34 +78,34 @@ namespace anim {
|
||||
return delta * (t2 * t2 * t + 1);
|
||||
}
|
||||
|
||||
void start(Animated *obj) {
|
||||
if (!manager) return;
|
||||
manager->start(obj);
|
||||
}
|
||||
|
||||
void step(Animated *obj) {
|
||||
if (!manager) return;
|
||||
manager->step(obj);
|
||||
}
|
||||
|
||||
void stop(Animated *obj) {
|
||||
if (!manager) return;
|
||||
manager->stop(obj);
|
||||
}
|
||||
|
||||
void startManager() {
|
||||
delete manager;
|
||||
manager = new AnimationManager();
|
||||
delete _manager;
|
||||
_manager = new AnimationManager();
|
||||
}
|
||||
|
||||
void stopManager() {
|
||||
delete manager;
|
||||
manager = 0;
|
||||
delete _manager;
|
||||
_manager = 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
bool AnimatedGif::animStep(float64 ms) {
|
||||
void Animation::start() {
|
||||
if (!_manager) return;
|
||||
|
||||
_cb->start();
|
||||
_manager->start(this);
|
||||
_animating = true;
|
||||
}
|
||||
|
||||
void Animation::stop() {
|
||||
if (!_manager) return;
|
||||
|
||||
_animating = false;
|
||||
_manager->stop(this);
|
||||
}
|
||||
|
||||
void AnimatedGif::step_frame(float64 ms, bool timer) {
|
||||
int32 f = frame;
|
||||
while (f < images.size() && ms > delays[f]) {
|
||||
++f;
|
||||
@@ -152,13 +152,14 @@ bool AnimatedGif::animStep(float64 ms) {
|
||||
}
|
||||
if (frame != f) {
|
||||
frame = f;
|
||||
if (msg && App::main()) {
|
||||
App::main()->msgUpdated(msg);
|
||||
} else {
|
||||
emit updated();
|
||||
if (timer) {
|
||||
if (msg && App::main()) {
|
||||
App::main()->msgUpdated(msg);
|
||||
} else {
|
||||
emit updated();
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void AnimatedGif::start(HistoryItem *row, const FileLocation &f) {
|
||||
@@ -205,7 +206,7 @@ void AnimatedGif::start(HistoryItem *row, const FileLocation &f) {
|
||||
|
||||
msg = row;
|
||||
|
||||
anim::start(this);
|
||||
_a_frames.start();
|
||||
if (msg) {
|
||||
msg->initDimensions();
|
||||
if (App::main()) App::main()->itemResized(msg, true);
|
||||
@@ -233,7 +234,7 @@ void AnimatedGif::stop(bool onItemRemoved) {
|
||||
delays.clear();
|
||||
w = h = frame = framesCount = duration = 0;
|
||||
|
||||
anim::stop(this);
|
||||
_a_frames.stop();
|
||||
if (row && !onItemRemoved) {
|
||||
row->initDimensions();
|
||||
if (App::main()) App::main()->itemResized(row, true);
|
||||
|
@@ -24,8 +24,6 @@ Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
|
||||
#include <QtCore/QTimer>
|
||||
#include <QtGui/QColor>
|
||||
|
||||
class Animated;
|
||||
|
||||
namespace anim {
|
||||
|
||||
typedef float64 (*transition)(const float64 &delta, const float64 &dt);
|
||||
@@ -187,216 +185,203 @@ namespace anim {
|
||||
float64 _from_r, _from_g, _from_b, _from_a, _delta_r, _delta_g, _delta_b, _delta_a;
|
||||
};
|
||||
|
||||
void start(Animated *obj);
|
||||
void step(Animated *obj);
|
||||
void stop(Animated *obj);
|
||||
|
||||
void startManager();
|
||||
void stopManager();
|
||||
|
||||
};
|
||||
|
||||
class Animated {
|
||||
class Animation;
|
||||
|
||||
class AnimationCallbacks {
|
||||
public:
|
||||
virtual void start() {
|
||||
}
|
||||
|
||||
virtual void step(Animation *a, uint64 ms, bool timer) = 0;
|
||||
|
||||
virtual ~AnimationCallbacks() {
|
||||
}
|
||||
};
|
||||
|
||||
class Animation {
|
||||
public:
|
||||
|
||||
Animated() : animStarted(0), animInProcess(false) {
|
||||
Animation(AnimationCallbacks *cb) : _cb(cb), _animating(false) {
|
||||
}
|
||||
|
||||
virtual bool animStep(float64 ms) = 0;
|
||||
void start();
|
||||
void stop();
|
||||
|
||||
void animReset() {
|
||||
animStarted = float64(getms());
|
||||
void step(uint64 ms, bool timer = false) {
|
||||
_cb->step(this, ms, timer);
|
||||
}
|
||||
|
||||
virtual ~Animated() {
|
||||
if (animating()) {
|
||||
anim::stop(this);
|
||||
}
|
||||
void step() {
|
||||
step(getms(), false);
|
||||
}
|
||||
|
||||
bool animating() const {
|
||||
return animInProcess;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
float64 animStarted;
|
||||
bool animInProcess;
|
||||
friend class AnimationManager;
|
||||
|
||||
};
|
||||
|
||||
class AnimationFunc {
|
||||
public:
|
||||
virtual bool animStep(float64 ms) = 0;
|
||||
virtual ~AnimationFunc() {
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Type>
|
||||
class AnimationFuncOwned : public AnimationFunc {
|
||||
public:
|
||||
typedef bool (Type::*Method)(float64);
|
||||
|
||||
AnimationFuncOwned(Type *obj, Method method) : _obj(obj), _method(method) {
|
||||
}
|
||||
|
||||
bool animStep(float64 ms) {
|
||||
return (_obj->*_method)(ms);
|
||||
}
|
||||
|
||||
private:
|
||||
Type *_obj;
|
||||
Method _method;
|
||||
|
||||
};
|
||||
|
||||
template <typename Type>
|
||||
AnimationFunc *animFunc(Type *obj, typename AnimationFuncOwned<Type>::Method method) {
|
||||
return new AnimationFuncOwned<Type>(obj, method);
|
||||
}
|
||||
|
||||
class Animation : public Animated {
|
||||
public:
|
||||
|
||||
Animation(AnimationFunc *func) : _func(func) {
|
||||
}
|
||||
|
||||
void start() {
|
||||
anim::start(this);
|
||||
}
|
||||
void stop() {
|
||||
anim::stop(this);
|
||||
}
|
||||
|
||||
//Animation
|
||||
bool animStep(float64 ms) {
|
||||
return _func->animStep(ms);
|
||||
return _animating;
|
||||
}
|
||||
|
||||
~Animation() {
|
||||
delete _func;
|
||||
if (_animating) stop();
|
||||
delete _cb;
|
||||
}
|
||||
|
||||
private:
|
||||
AnimationFunc *_func;
|
||||
AnimationCallbacks *_cb;
|
||||
bool _animating;
|
||||
|
||||
};
|
||||
|
||||
template <typename Type>
|
||||
class AnimationCallbacksRelative : public AnimationCallbacks {
|
||||
public:
|
||||
typedef void (Type::*Method)(float64, bool);
|
||||
|
||||
AnimationCallbacksRelative(Type *obj, Method method) : _started(0), _obj(obj), _method(method) {
|
||||
}
|
||||
|
||||
void start() {
|
||||
_started = float64(getms());
|
||||
}
|
||||
|
||||
void step(Animation *a, uint64 ms, bool timer) {
|
||||
(_obj->*_method)(ms - _started, timer);
|
||||
}
|
||||
|
||||
private:
|
||||
float64 _started;
|
||||
Type *_obj;
|
||||
Method _method;
|
||||
|
||||
};
|
||||
template <typename Type>
|
||||
AnimationCallbacks *animation(Type *obj, typename AnimationCallbacksRelative<Type>::Method method) {
|
||||
return new AnimationCallbacksRelative<Type>(obj, method);
|
||||
}
|
||||
|
||||
template <typename Type>
|
||||
class AnimationCallbacksAbsolute : public AnimationCallbacks {
|
||||
public:
|
||||
typedef void (Type::*Method)(uint64, bool);
|
||||
|
||||
AnimationCallbacksAbsolute(Type *obj, Method method) : _obj(obj), _method(method) {
|
||||
}
|
||||
|
||||
void step(Animation *a, uint64 ms, bool timer) {
|
||||
(_obj->*_method)(ms, timer);
|
||||
}
|
||||
|
||||
private:
|
||||
Type *_obj;
|
||||
Method _method;
|
||||
|
||||
};
|
||||
template <typename Type>
|
||||
AnimationCallbacks *animation(Type *obj, typename AnimationCallbacksAbsolute<Type>::Method method) {
|
||||
return new AnimationCallbacksAbsolute<Type>(obj, method);
|
||||
}
|
||||
|
||||
class AnimationManager : public QObject {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
|
||||
AnimationManager() : timer(this), iterating(false) {
|
||||
timer.setSingleShot(false);
|
||||
connect(&timer, SIGNAL(timeout()), this, SLOT(timeout()));
|
||||
AnimationManager() : _timer(this), _iterating(false) {
|
||||
_timer.setSingleShot(false);
|
||||
connect(&_timer, SIGNAL(timeout()), this, SLOT(timeout()));
|
||||
}
|
||||
|
||||
void start(Animated *obj) {
|
||||
obj->animReset();
|
||||
if (iterating) {
|
||||
toStart.insert(obj);
|
||||
if (!toStop.isEmpty()) {
|
||||
toStop.remove(obj);
|
||||
void start(Animation *obj) {
|
||||
if (_iterating) {
|
||||
_starting.insert(obj, NullType());
|
||||
if (!_stopping.isEmpty()) {
|
||||
_stopping.remove(obj);
|
||||
}
|
||||
} else {
|
||||
if (!objs.size()) {
|
||||
timer.start(AnimationTimerDelta);
|
||||
}
|
||||
objs.insert(obj);
|
||||
}
|
||||
obj->animInProcess = true;
|
||||
}
|
||||
|
||||
void step(Animated *obj) {
|
||||
if (iterating) return;
|
||||
|
||||
float64 ms = float64(getms());
|
||||
AnimObjs::iterator i = objs.find(obj);
|
||||
if (i != objs.cend()) {
|
||||
Animated *obj = *i;
|
||||
if (!obj->animStep(ms - obj->animStarted)) {
|
||||
objs.erase(i);
|
||||
if (!objs.size()) {
|
||||
timer.stop();
|
||||
}
|
||||
obj->animInProcess = false;
|
||||
if (_objects.isEmpty()) {
|
||||
_timer.start(AnimationTimerDelta);
|
||||
}
|
||||
_objects.insert(obj, NullType());
|
||||
}
|
||||
}
|
||||
|
||||
void stop(Animated *obj) {
|
||||
if (iterating) {
|
||||
toStop.insert(obj);
|
||||
if (!toStart.isEmpty()) {
|
||||
toStart.insert(obj);
|
||||
void stop(Animation *obj) {
|
||||
if (_iterating) {
|
||||
_stopping.insert(obj, NullType());
|
||||
if (!_starting.isEmpty()) {
|
||||
_starting.insert(obj, NullType());
|
||||
}
|
||||
} else {
|
||||
AnimObjs::iterator i = objs.find(obj);
|
||||
if (i != objs.cend()) {
|
||||
objs.erase(i);
|
||||
if (!objs.size()) {
|
||||
timer.stop();
|
||||
AnimatingObjects::iterator i = _objects.find(obj);
|
||||
if (i != _objects.cend()) {
|
||||
_objects.erase(i);
|
||||
if (_objects.isEmpty()) {
|
||||
_timer.stop();
|
||||
}
|
||||
}
|
||||
}
|
||||
obj->animInProcess = false;
|
||||
}
|
||||
|
||||
public slots:
|
||||
|
||||
void timeout() {
|
||||
iterating = true;
|
||||
float64 ms = float64(getms());
|
||||
for (AnimObjs::iterator i = objs.begin(), e = objs.end(); i != e; ) {
|
||||
Animated *obj = *i;
|
||||
if (!obj->animStep(ms - obj->animStarted)) {
|
||||
i = objs.erase(i);
|
||||
obj->animInProcess = false;
|
||||
} else {
|
||||
++i;
|
||||
}
|
||||
_iterating = true;
|
||||
uint64 ms = getms();
|
||||
for (AnimatingObjects::const_iterator i = _objects.begin(), e = _objects.end(); i != e; ++i) {
|
||||
i.key()->step(ms, true);
|
||||
}
|
||||
iterating = false;
|
||||
if (!toStart.isEmpty()) {
|
||||
for (AnimObjs::iterator i = toStart.begin(), e = toStart.end(); i != e; ++i) {
|
||||
objs.insert(*i);
|
||||
_iterating = false;
|
||||
|
||||
if (!_starting.isEmpty()) {
|
||||
for (AnimatingObjects::iterator i = _starting.begin(), e = _starting.end(); i != e; ++i) {
|
||||
_objects.insert(i.key(), NullType());
|
||||
}
|
||||
toStart.clear();
|
||||
_starting.clear();
|
||||
}
|
||||
if (!toStop.isEmpty()) {
|
||||
for (AnimObjs::iterator i = toStop.begin(), e = toStop.end(); i != e; ++i) {
|
||||
objs.remove(*i);
|
||||
if (!_stopping.isEmpty()) {
|
||||
for (AnimatingObjects::iterator i = _stopping.begin(), e = _stopping.end(); i != e; ++i) {
|
||||
_objects.remove(i.key());
|
||||
}
|
||||
toStop.clear();
|
||||
_stopping.clear();
|
||||
}
|
||||
if (!objs.size()) {
|
||||
timer.stop();
|
||||
if (!_objects.size()) {
|
||||
_timer.stop();
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
typedef QSet<Animated*> AnimObjs;
|
||||
AnimObjs objs;
|
||||
AnimObjs toStart;
|
||||
AnimObjs toStop;
|
||||
QTimer timer;
|
||||
bool iterating;
|
||||
typedef QMap<Animation*, NullType> AnimatingObjects;
|
||||
AnimatingObjects _objects, _starting, _stopping;
|
||||
QTimer _timer;
|
||||
bool _iterating;
|
||||
|
||||
};
|
||||
|
||||
class HistoryItem;
|
||||
class FileLocation;
|
||||
class AnimatedGif : public QObject, public Animated {
|
||||
class AnimatedGif : public QObject {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
|
||||
AnimatedGif() : msg(0), file(0), access(false), reader(0), w(0), h(0), frame(0), framesCount(0), duration(0) {
|
||||
AnimatedGif() : QObject()
|
||||
, msg(0)
|
||||
, file(0)
|
||||
, access(false)
|
||||
, reader(0)
|
||||
, w(0)
|
||||
, h(0)
|
||||
, frame(0)
|
||||
, framesCount(0)
|
||||
, duration(0)
|
||||
, _a_frames(animation(this, &AnimatedGif::step_frame)) {
|
||||
}
|
||||
|
||||
bool animStep(float64 ms);
|
||||
void step_frame(float64 ms, bool timer);
|
||||
|
||||
void start(HistoryItem *row, const FileLocation &file);
|
||||
void stop(bool onItemRemoved = false);
|
||||
@@ -430,4 +415,7 @@ private:
|
||||
QVector<QImage> images;
|
||||
QVector<int64> delays;
|
||||
int32 framesCount, duration;
|
||||
|
||||
Animation _a_frames;
|
||||
|
||||
};
|
||||
|
@@ -21,10 +21,14 @@ Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
|
||||
#include "stdafx.h"
|
||||
#include "gui/flatbutton.h"
|
||||
|
||||
FlatButton::FlatButton(QWidget *parent, const QString &text, const style::flatButton &st) : Button(parent),
|
||||
_text(text),
|
||||
_st(st), _autoFontPadding(0),
|
||||
a_bg(st.bgColor->c), a_text(st.color->c), _opacity(1) {
|
||||
FlatButton::FlatButton(QWidget *parent, const QString &text, const style::flatButton &st) : Button(parent)
|
||||
, _text(text)
|
||||
, _st(st)
|
||||
, _autoFontPadding(0)
|
||||
, a_bg(st.bgColor->c)
|
||||
, a_text(st.color->c)
|
||||
, _a_appearance(animation(this, &FlatButton::step_appearance))
|
||||
, _opacity(1) {
|
||||
if (_st.width < 0) {
|
||||
_st.width = textWidth() - _st.width;
|
||||
} else if (!_st.width) {
|
||||
@@ -88,19 +92,17 @@ void FlatButton::resizeEvent(QResizeEvent *e) {
|
||||
return Button::resizeEvent(e);
|
||||
}
|
||||
|
||||
bool FlatButton::animStep(float64 ms) {
|
||||
void FlatButton::step_appearance(float64 ms, bool timer) {
|
||||
float64 dt = ms / _st.duration;
|
||||
bool res = true;
|
||||
if (dt >= 1) {
|
||||
_a_appearance.stop();
|
||||
a_bg.finish();
|
||||
a_text.finish();
|
||||
res = false;
|
||||
} else {
|
||||
a_bg.update(dt, anim::linear);
|
||||
a_text.update(dt, anim::linear);
|
||||
}
|
||||
update();
|
||||
return res;
|
||||
if (timer) update();
|
||||
}
|
||||
|
||||
void FlatButton::onStateChange(int oldState, ButtonStateChangeSource source) {
|
||||
@@ -110,12 +112,12 @@ void FlatButton::onStateChange(int oldState, ButtonStateChangeSource source) {
|
||||
a_bg.start(bgColorTo->c);
|
||||
a_text.start(colorTo->c);
|
||||
if (source == ButtonByUser || source == ButtonByPress) {
|
||||
anim::stop(this);
|
||||
_a_appearance.stop();
|
||||
a_bg.finish();
|
||||
a_text.finish();
|
||||
update();
|
||||
} else {
|
||||
anim::start(this);
|
||||
_a_appearance.start();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -164,8 +166,14 @@ void LinkButton::onStateChange(int oldState, ButtonStateChangeSource source) {
|
||||
LinkButton::~LinkButton() {
|
||||
}
|
||||
|
||||
IconedButton::IconedButton(QWidget *parent, const style::iconedButton &st, const QString &text) : Button(parent),
|
||||
_text(text), _st(st), _width(_st.width), a_opacity(_st.opacity), a_bg(_st.bgColor->c), _opacity(1) {
|
||||
IconedButton::IconedButton(QWidget *parent, const style::iconedButton &st, const QString &text) : Button(parent)
|
||||
, _text(text)
|
||||
, _st(st)
|
||||
, _width(_st.width)
|
||||
, a_opacity(_st.opacity)
|
||||
, a_bg(_st.bgColor->c)
|
||||
, _a_appearance(animation(this, &IconedButton::step_appearance))
|
||||
, _opacity(1) {
|
||||
|
||||
if (_width < 0) {
|
||||
_width = _st.font->width(text) - _width;
|
||||
@@ -199,25 +207,23 @@ QString IconedButton::getText() const {
|
||||
return _text;
|
||||
}
|
||||
|
||||
bool IconedButton::animStep(float64 ms) {
|
||||
bool res = true;
|
||||
void IconedButton::step_appearance(float64 ms, bool timer) {
|
||||
if (_st.duration <= 1) {
|
||||
_a_appearance.stop();
|
||||
a_opacity.finish();
|
||||
a_bg.finish();
|
||||
res = false;
|
||||
} else {
|
||||
float64 dt = ms / _st.duration;
|
||||
if (dt >= 1) {
|
||||
_a_appearance.stop();
|
||||
a_opacity.finish();
|
||||
a_bg.finish();
|
||||
res = false;
|
||||
} else {
|
||||
a_opacity.update(dt, anim::linear);
|
||||
a_bg.update(dt, anim::linear);
|
||||
}
|
||||
}
|
||||
update();
|
||||
return res;
|
||||
if (timer) update();
|
||||
}
|
||||
|
||||
void IconedButton::onStateChange(int oldState, ButtonStateChangeSource source) {
|
||||
@@ -225,12 +231,12 @@ void IconedButton::onStateChange(int oldState, ButtonStateChangeSource source) {
|
||||
a_bg.start(((_state & (StateOver | StateDown)) ? _st.overBgColor : _st.bgColor)->c);
|
||||
|
||||
if (source == ButtonByUser || source == ButtonByPress) {
|
||||
anim::stop(this);
|
||||
_a_appearance.stop();
|
||||
a_opacity.finish();
|
||||
a_bg.finish();
|
||||
update();
|
||||
} else {
|
||||
anim::start(this);
|
||||
_a_appearance.start();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -283,10 +289,14 @@ void MaskedButton::paintEvent(QPaintEvent *e) {
|
||||
}
|
||||
}
|
||||
|
||||
BoxButton::BoxButton(QWidget *parent, const QString &text, const style::BoxButton &st) : Button(parent),
|
||||
_text(text.toUpper()), _fullText(text.toUpper()), _textWidth(st.font->width(_text)),
|
||||
_st(st),
|
||||
a_textBgOverOpacity(0), a_textFg(st.textFg->c), _a_over(animFunc(this, &BoxButton::animStep_over)) {
|
||||
BoxButton::BoxButton(QWidget *parent, const QString &text, const style::BoxButton &st) : Button(parent)
|
||||
, _text(text.toUpper())
|
||||
, _fullText(text.toUpper())
|
||||
, _textWidth(st.font->width(_text))
|
||||
, _st(st)
|
||||
, a_textBgOverOpacity(0)
|
||||
, a_textFg(st.textFg->c)
|
||||
, _a_over(animation(this, &BoxButton::step_over)) {
|
||||
if (_st.width <= 0) {
|
||||
resize(_textWidth - _st.width, _st.height);
|
||||
} else {
|
||||
@@ -322,19 +332,17 @@ void BoxButton::paintEvent(QPaintEvent *e) {
|
||||
p.drawText((width() - _textWidth) / 2, _st.textTop + _st.font->ascent, _text);
|
||||
}
|
||||
|
||||
bool BoxButton::animStep_over(float64 ms) {
|
||||
void BoxButton::step_over(float64 ms, bool timer) {
|
||||
float64 dt = ms / _st.duration;
|
||||
bool res = true;
|
||||
if (dt >= 1) {
|
||||
_a_over.stop();
|
||||
a_textFg.finish();
|
||||
a_textBgOverOpacity.finish();
|
||||
res = false;
|
||||
} else {
|
||||
a_textFg.update(dt, anim::linear);
|
||||
a_textBgOverOpacity.update(dt, anim::linear);
|
||||
}
|
||||
update();
|
||||
return res;
|
||||
if (timer) update();
|
||||
}
|
||||
|
||||
void BoxButton::onStateChange(int oldState, ButtonStateChangeSource source) {
|
||||
|
@@ -25,7 +25,7 @@ Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
|
||||
#include "gui/animation.h"
|
||||
#include "style.h"
|
||||
|
||||
class FlatButton : public Button, public Animated {
|
||||
class FlatButton : public Button {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
@@ -34,7 +34,7 @@ public:
|
||||
|
||||
void resizeEvent(QResizeEvent *e);
|
||||
|
||||
bool animStep(float64 ms);
|
||||
void step_appearance(float64 ms, bool timer);
|
||||
void paintEvent(QPaintEvent *e);
|
||||
void setOpacity(float64 o);
|
||||
float64 opacity() const;
|
||||
@@ -63,7 +63,10 @@ private:
|
||||
style::font _autoFont;
|
||||
|
||||
anim::cvalue a_bg, a_text;
|
||||
Animation _a_appearance;
|
||||
|
||||
float64 _opacity;
|
||||
|
||||
};
|
||||
|
||||
class LinkButton : public Button {
|
||||
@@ -89,14 +92,14 @@ private:
|
||||
style::linkButton _st;
|
||||
};
|
||||
|
||||
class IconedButton : public Button, public Animated {
|
||||
class IconedButton : public Button {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
|
||||
IconedButton(QWidget *parent, const style::iconedButton &st, const QString &text = QString());
|
||||
|
||||
bool animStep(float64 ms);
|
||||
void step_appearance(float64 ms, bool timer);
|
||||
void paintEvent(QPaintEvent *e);
|
||||
|
||||
void setOpacity(float64 o);
|
||||
@@ -117,6 +120,7 @@ protected:
|
||||
|
||||
anim::fvalue a_opacity;
|
||||
anim::cvalue a_bg;
|
||||
Animation _a_appearance;
|
||||
|
||||
float64 _opacity;
|
||||
};
|
||||
@@ -141,7 +145,7 @@ public:
|
||||
|
||||
void paintEvent(QPaintEvent *e);
|
||||
|
||||
bool animStep_over(float64 ms);
|
||||
void step_over(float64 ms, bool timer);
|
||||
|
||||
public slots:
|
||||
|
||||
|
@@ -24,8 +24,13 @@ Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
|
||||
|
||||
#include "flatcheckbox.h"
|
||||
|
||||
FlatCheckbox::FlatCheckbox(QWidget *parent, const QString &text, bool checked, const style::flatCheckbox &st) : Button(parent),
|
||||
_st(st), a_over(0, 0), _text(text), _opacity(1), _checked(checked) {
|
||||
FlatCheckbox::FlatCheckbox(QWidget *parent, const QString &text, bool checked, const style::flatCheckbox &st) : Button(parent)
|
||||
, _st(st)
|
||||
, a_over(0, 0)
|
||||
, _a_appearance(animation(this, &FlatCheckbox::step_appearance))
|
||||
, _text(text)
|
||||
, _opacity(1)
|
||||
, _checked(checked) {
|
||||
connect(this, SIGNAL(clicked()), this, SLOT(onClicked()));
|
||||
connect(this, SIGNAL(stateChanged(int, ButtonStateChangeSource)), this, SLOT(onStateChange(int, ButtonStateChangeSource)));
|
||||
setCursor(_st.cursor);
|
||||
@@ -60,17 +65,17 @@ void FlatCheckbox::onClicked() {
|
||||
void FlatCheckbox::onStateChange(int oldState, ButtonStateChangeSource source) {
|
||||
if ((_state & StateOver) && !(oldState & StateOver)) {
|
||||
a_over.start(1);
|
||||
anim::start(this);
|
||||
_a_appearance.start();
|
||||
} else if (!(_state & StateOver) && (oldState & StateOver)) {
|
||||
a_over.start(0);
|
||||
anim::start(this);
|
||||
_a_appearance.start();
|
||||
}
|
||||
if ((_state & StateDisabled) && !(oldState & StateDisabled)) {
|
||||
setCursor(_st.disabledCursor);
|
||||
anim::start(this);
|
||||
_a_appearance.start();
|
||||
} else if (!(_state & StateDisabled) && (oldState & StateDisabled)) {
|
||||
setCursor(_st.cursor);
|
||||
anim::start(this);
|
||||
_a_appearance.start();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -114,17 +119,15 @@ void FlatCheckbox::paintEvent(QPaintEvent *e) {
|
||||
}
|
||||
}
|
||||
|
||||
bool FlatCheckbox::animStep(float64 ms) {
|
||||
void FlatCheckbox::step_appearance(float64 ms, bool timer) {
|
||||
float64 dt = ms / _st.duration;
|
||||
bool res = true;
|
||||
if (dt >= 1) {
|
||||
_a_appearance.stop();
|
||||
a_over.finish();
|
||||
res = false;
|
||||
} else {
|
||||
a_over.update(dt, _st.bgFunc);
|
||||
}
|
||||
update();
|
||||
return res;
|
||||
if (timer) update();
|
||||
}
|
||||
|
||||
template <typename Type>
|
||||
@@ -135,7 +138,8 @@ public:
|
||||
TemplateRadiobuttonsGroup(const QString &name) : _name(name), _val(0) {
|
||||
}
|
||||
|
||||
void remove(Type * const &radio);
|
||||
void remove(Type * const &radio) {
|
||||
}
|
||||
int32 val() const {
|
||||
return _val;
|
||||
}
|
||||
@@ -232,12 +236,16 @@ FlatRadiobutton::~FlatRadiobutton() {
|
||||
reinterpret_cast<FlatRadiobuttonGroup*>(_group)->remove(this);
|
||||
}
|
||||
|
||||
Checkbox::Checkbox(QWidget *parent, const QString &text, bool checked, const style::Checkbox &st) : Button(parent),
|
||||
_st(st),
|
||||
a_over(0), a_checked(checked ? 1 : 0),
|
||||
_a_over(animFunc(this, &Checkbox::animStep_over)), _a_checked(animFunc(this, &Checkbox::animStep_checked)),
|
||||
_text(text), _fullText(text), _textWidth(st.font->width(text)),
|
||||
_checked(checked) {
|
||||
Checkbox::Checkbox(QWidget *parent, const QString &text, bool checked, const style::Checkbox &st) : Button(parent)
|
||||
, _st(st)
|
||||
, a_over(0)
|
||||
, a_checked(checked ? 1 : 0)
|
||||
, _a_over(animation(this, &Checkbox::step_over))
|
||||
, _a_checked(animation(this, &Checkbox::step_checked))
|
||||
, _text(text)
|
||||
, _fullText(text)
|
||||
, _textWidth(st.font->width(text))
|
||||
, _checked(checked) {
|
||||
if (_st.width <= 0) {
|
||||
resize(_textWidth - _st.width, _st.height);
|
||||
} else {
|
||||
@@ -275,30 +283,26 @@ void Checkbox::setChecked(bool checked) {
|
||||
}
|
||||
}
|
||||
|
||||
bool Checkbox::animStep_over(float64 ms) {
|
||||
void Checkbox::step_over(float64 ms, bool timer) {
|
||||
float64 dt = ms / _st.duration;
|
||||
bool res = true;
|
||||
if (dt >= 1) {
|
||||
_a_over.stop();
|
||||
a_over.finish();
|
||||
res = false;
|
||||
} else {
|
||||
a_over.update(dt, anim::linear);
|
||||
}
|
||||
update(_checkRect);
|
||||
return res;
|
||||
if (timer) update(_checkRect);
|
||||
}
|
||||
|
||||
bool Checkbox::animStep_checked(float64 ms) {
|
||||
void Checkbox::step_checked(float64 ms, bool timer) {
|
||||
float64 dt = ms / _st.duration;
|
||||
bool res = true;
|
||||
if (dt >= 1) {
|
||||
a_checked.finish();
|
||||
res = false;
|
||||
_a_checked.stop();
|
||||
} else {
|
||||
a_checked.update(dt, anim::linear);
|
||||
}
|
||||
update(_checkRect);
|
||||
return res;
|
||||
if (timer) update(_checkRect);
|
||||
}
|
||||
|
||||
void Checkbox::paintEvent(QPaintEvent *e) {
|
||||
@@ -372,12 +376,18 @@ void Checkbox::onStateChange(int oldState, ButtonStateChangeSource source) {
|
||||
}
|
||||
}
|
||||
|
||||
Radiobutton::Radiobutton(QWidget *parent, const QString &group, int32 value, const QString &text, bool checked, const style::Radiobutton &st) : Button(parent),
|
||||
_st(st),
|
||||
a_over(0), a_checked(checked ? 1 : 0),
|
||||
_a_over(animFunc(this, &Radiobutton::animStep_over)), _a_checked(animFunc(this, &Radiobutton::animStep_checked)),
|
||||
_text(text), _fullText(text), _textWidth(st.font->width(text)),
|
||||
_checked(checked), _group(radiobuttons.reg(group)), _value(value) {
|
||||
Radiobutton::Radiobutton(QWidget *parent, const QString &group, int32 value, const QString &text, bool checked, const style::Radiobutton &st) : Button(parent)
|
||||
, _st(st)
|
||||
, a_over(0)
|
||||
, a_checked(checked ? 1 : 0)
|
||||
, _a_over(animation(this, &Radiobutton::step_over))
|
||||
, _a_checked(animation(this, &Radiobutton::step_checked))
|
||||
, _text(text)
|
||||
, _fullText(text)
|
||||
, _textWidth(st.font->width(text))
|
||||
, _checked(checked)
|
||||
, _group(radiobuttons.reg(group))
|
||||
, _value(value) {
|
||||
if (_st.width <= 0) {
|
||||
resize(_textWidth - _st.width, _st.height);
|
||||
} else {
|
||||
@@ -419,30 +429,26 @@ void Radiobutton::setChecked(bool checked) {
|
||||
}
|
||||
}
|
||||
|
||||
bool Radiobutton::animStep_over(float64 ms) {
|
||||
void Radiobutton::step_over(float64 ms, bool timer) {
|
||||
float64 dt = ms / _st.duration;
|
||||
bool res = true;
|
||||
if (dt >= 1) {
|
||||
_a_over.stop();
|
||||
a_over.finish();
|
||||
res = false;
|
||||
} else {
|
||||
a_over.update(dt, anim::linear);
|
||||
}
|
||||
update(_checkRect);
|
||||
return res;
|
||||
if (timer) update(_checkRect);
|
||||
}
|
||||
|
||||
bool Radiobutton::animStep_checked(float64 ms) {
|
||||
void Radiobutton::step_checked(float64 ms, bool timer) {
|
||||
float64 dt = ms / _st.duration;
|
||||
bool res = true;
|
||||
if (dt >= 1) {
|
||||
a_checked.finish();
|
||||
res = false;
|
||||
_a_checked.stop();
|
||||
} else {
|
||||
a_checked.update(dt, anim::linear);
|
||||
}
|
||||
update(_checkRect);
|
||||
return res;
|
||||
if (timer) update(_checkRect);
|
||||
}
|
||||
|
||||
void Radiobutton::paintEvent(QPaintEvent *e) {
|
||||
|
@@ -22,7 +22,7 @@ Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
|
||||
|
||||
#include "gui/button.h"
|
||||
|
||||
class FlatCheckbox : public Button, public Animated {
|
||||
class FlatCheckbox : public Button {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
@@ -32,7 +32,7 @@ public:
|
||||
bool checked() const;
|
||||
void setChecked(bool checked);
|
||||
|
||||
bool animStep(float64 ms);
|
||||
void step_appearance(float64 ms, bool timer);
|
||||
void paintEvent(QPaintEvent *e);
|
||||
|
||||
void setOpacity(float64 o);
|
||||
@@ -50,6 +50,8 @@ private:
|
||||
|
||||
style::flatCheckbox _st;
|
||||
anim::fvalue a_over;
|
||||
Animation _a_appearance;
|
||||
|
||||
QString _text;
|
||||
style::font _font;
|
||||
|
||||
@@ -91,8 +93,8 @@ public:
|
||||
bool checked() const;
|
||||
void setChecked(bool checked);
|
||||
|
||||
bool animStep_over(float64 ms);
|
||||
bool animStep_checked(float64 ms);
|
||||
void step_over(float64 ms, bool timer);
|
||||
void step_checked(float64 ms, bool timer);
|
||||
|
||||
void paintEvent(QPaintEvent *e);
|
||||
|
||||
@@ -133,8 +135,8 @@ public:
|
||||
return _value;
|
||||
}
|
||||
|
||||
bool animStep_over(float64 ms);
|
||||
bool animStep_checked(float64 ms);
|
||||
void step_over(float64 ms, bool timer);
|
||||
void step_checked(float64 ms, bool timer);
|
||||
|
||||
void paintEvent(QPaintEvent *e);
|
||||
|
||||
|
@@ -51,10 +51,20 @@ namespace {
|
||||
InputStyle<MaskedInputField> _inputFieldStyle;
|
||||
}
|
||||
|
||||
FlatInput::FlatInput(QWidget *parent, const style::flatInput &st, const QString &pholder, const QString &v) : QLineEdit(v, parent),
|
||||
_oldtext(v), _fullph(pholder), _fastph(false), _customUpDown(false), _phVisible(!v.length()),
|
||||
a_phLeft(_phVisible ? 0 : st.phShift), a_phAlpha(_phVisible ? 1 : 0), a_phColor(st.phColor->c),
|
||||
a_borderColor(st.borderColor->c), a_bgColor(st.bgColor->c), _notingBene(0), _st(st) {
|
||||
FlatInput::FlatInput(QWidget *parent, const style::flatInput &st, const QString &pholder, const QString &v) : QLineEdit(v, parent)
|
||||
, _oldtext(v)
|
||||
, _fullph(pholder)
|
||||
, _fastph(false)
|
||||
, _customUpDown(false)
|
||||
, _phVisible(!v.length())
|
||||
, a_phLeft(_phVisible ? 0 : st.phShift)
|
||||
, a_phAlpha(_phVisible ? 1 : 0)
|
||||
, a_phColor(st.phColor->c)
|
||||
, a_borderColor(st.borderColor->c)
|
||||
, a_bgColor(st.bgColor->c)
|
||||
, _a_appearance(animation(this, &FlatInput::step_appearance))
|
||||
, _notingBene(0)
|
||||
, _st(st) {
|
||||
resize(_st.width, _st.height);
|
||||
|
||||
setFont(_st.font->f);
|
||||
@@ -158,7 +168,7 @@ void FlatInput::paintEvent(QPaintEvent *e) {
|
||||
}
|
||||
|
||||
bool phDraw = _phVisible;
|
||||
if (animating()) {
|
||||
if (_a_appearance.animating()) {
|
||||
p.setOpacity(a_phAlpha.current());
|
||||
phDraw = true;
|
||||
}
|
||||
@@ -180,7 +190,7 @@ void FlatInput::focusInEvent(QFocusEvent *e) {
|
||||
a_borderColor.start(_st.borderActive->c);
|
||||
}
|
||||
a_bgColor.start(_st.bgActive->c);
|
||||
anim::start(this);
|
||||
_a_appearance.start();
|
||||
QLineEdit::focusInEvent(e);
|
||||
emit focused();
|
||||
}
|
||||
@@ -191,7 +201,7 @@ void FlatInput::focusOutEvent(QFocusEvent *e) {
|
||||
a_borderColor.start(_st.borderColor->c);
|
||||
}
|
||||
a_bgColor.start(_st.bgColor->c);
|
||||
anim::start(this);
|
||||
_a_appearance.start();
|
||||
QLineEdit::focusOutEvent(e);
|
||||
emit blurred();
|
||||
}
|
||||
@@ -224,11 +234,10 @@ QSize FlatInput::minimumSizeHint() const {
|
||||
return geometry().size();
|
||||
}
|
||||
|
||||
bool FlatInput::animStep(float64 ms) {
|
||||
void FlatInput::step_appearance(float64 ms, bool timer) {
|
||||
float dt = ms / _st.phDuration;
|
||||
bool res = true;
|
||||
if (dt >= 1) {
|
||||
res = false;
|
||||
_a_appearance.stop();
|
||||
a_phLeft.finish();
|
||||
a_phAlpha.finish();
|
||||
a_phColor.finish();
|
||||
@@ -236,8 +245,8 @@ bool FlatInput::animStep(float64 ms) {
|
||||
if (_notingBene > 0) {
|
||||
_notingBene = -1;
|
||||
a_borderColor.start((hasFocus() ? _st.borderActive : _st.borderColor)->c);
|
||||
anim::start(this);
|
||||
return true;
|
||||
_a_appearance.start();
|
||||
return;
|
||||
} else if (_notingBene) {
|
||||
_notingBene = 0;
|
||||
}
|
||||
@@ -249,8 +258,7 @@ bool FlatInput::animStep(float64 ms) {
|
||||
a_bgColor.update(dt, _st.phColorFunc);
|
||||
a_borderColor.update(dt, _st.phColorFunc);
|
||||
}
|
||||
update();
|
||||
return res;
|
||||
if (timer) update();
|
||||
}
|
||||
|
||||
void FlatInput::setPlaceholder(const QString &ph) {
|
||||
@@ -279,7 +287,7 @@ void FlatInput::updatePlaceholder() {
|
||||
} else {
|
||||
a_phLeft.start(vis ? 0 : _st.phShift);
|
||||
a_phAlpha.start(vis ? 1 : 0);
|
||||
anim::start(this);
|
||||
_a_appearance.start();
|
||||
}
|
||||
_phVisible = vis;
|
||||
}
|
||||
@@ -345,11 +353,11 @@ void FlatInput::notaBene() {
|
||||
_notingBene = 1;
|
||||
setFocus();
|
||||
a_borderColor.start(_st.borderError->c);
|
||||
anim::start(this);
|
||||
_a_appearance.start();
|
||||
}
|
||||
|
||||
CountryCodeInput::CountryCodeInput(QWidget *parent, const style::flatInput &st) : FlatInput(parent, st), _nosignal(false) {
|
||||
|
||||
CountryCodeInput::CountryCodeInput(QWidget *parent, const style::flatInput &st) : FlatInput(parent, st)
|
||||
, _nosignal(false) {
|
||||
}
|
||||
|
||||
void CountryCodeInput::startErasing(QKeyEvent *e) {
|
||||
@@ -541,38 +549,39 @@ void PhonePartInput::onChooseCode(const QString &code) {
|
||||
updatePlaceholder();
|
||||
}
|
||||
|
||||
InputArea::InputArea(QWidget *parent, const style::InputArea &st, const QString &ph, const QString &val) : TWidget(parent),
|
||||
_maxLength(-1),
|
||||
_inner(this),
|
||||
_oldtext(val),
|
||||
InputArea::InputArea(QWidget *parent, const style::InputArea &st, const QString &ph, const QString &val) : TWidget(parent)
|
||||
, _maxLength(-1)
|
||||
, _inner(this)
|
||||
, _oldtext(val)
|
||||
|
||||
_ctrlEnterSubmit(CtrlEnterSubmitCtrlEnter),
|
||||
_undoAvailable(false),
|
||||
_redoAvailable(false),
|
||||
_inHeightCheck(false),
|
||||
, _ctrlEnterSubmit(CtrlEnterSubmitCtrlEnter)
|
||||
, _undoAvailable(false)
|
||||
, _redoAvailable(false)
|
||||
, _inHeightCheck(false)
|
||||
|
||||
_customUpDown(false),
|
||||
, _customUpDown(false)
|
||||
|
||||
_placeholderFull(ph),
|
||||
_placeholderVisible(val.isEmpty()),
|
||||
a_placeholderLeft(_placeholderVisible ? 0 : st.placeholderShift),
|
||||
a_placeholderOpacity(_placeholderVisible ? 1 : 0),
|
||||
a_placeholderFg(st.placeholderFg->c),
|
||||
_a_placeholderFg(animFunc(this, &InputArea::animStep_placeholderFg)),
|
||||
_a_placeholderShift(animFunc(this, &InputArea::animStep_placeholderShift)),
|
||||
, _placeholderFull(ph)
|
||||
, _placeholderVisible(val.isEmpty())
|
||||
, a_placeholderLeft(_placeholderVisible ? 0 : st.placeholderShift)
|
||||
, a_placeholderOpacity(_placeholderVisible ? 1 : 0)
|
||||
, a_placeholderFg(st.placeholderFg->c)
|
||||
, _a_placeholderFg(animation(this, &InputArea::step_placeholderFg))
|
||||
, _a_placeholderShift(animation(this, &InputArea::step_placeholderShift))
|
||||
|
||||
a_borderOpacityActive(0),
|
||||
a_borderFg(st.borderFg->c),
|
||||
_a_border(animFunc(this, &InputArea::animStep_border)),
|
||||
, a_borderOpacityActive(0)
|
||||
, a_borderFg(st.borderFg->c)
|
||||
, _a_border(animation(this, &InputArea::step_border))
|
||||
|
||||
_focused(false), _error(false),
|
||||
, _focused(false)
|
||||
, _error(false)
|
||||
|
||||
_st(st),
|
||||
, _st(st)
|
||||
|
||||
_touchPress(false),
|
||||
_touchRightButton(false),
|
||||
_touchMove(false),
|
||||
_correcting(false) {
|
||||
, _touchPress(false)
|
||||
, _touchRightButton(false)
|
||||
, _touchMove(false)
|
||||
, _correcting(false) {
|
||||
_inner.setAcceptRichText(false);
|
||||
resize(_st.width, _st.heightMin);
|
||||
|
||||
@@ -1106,47 +1115,42 @@ void InputArea::onRedoAvailable(bool avail) {
|
||||
if (App::wnd()) App::wnd()->updateGlobalMenu();
|
||||
}
|
||||
|
||||
bool InputArea::animStep_placeholderFg(float64 ms) {
|
||||
float dt = ms / _st.duration;
|
||||
bool res = true;
|
||||
void InputArea::step_placeholderFg(float64 ms, bool timer) {
|
||||
float64 dt = ms / _st.duration;
|
||||
if (dt >= 1) {
|
||||
res = false;
|
||||
_a_placeholderFg.stop();
|
||||
a_placeholderFg.finish();
|
||||
} else {
|
||||
a_placeholderFg.update(dt, anim::linear);
|
||||
}
|
||||
update();
|
||||
return res;
|
||||
if (timer) update();
|
||||
}
|
||||
|
||||
bool InputArea::animStep_placeholderShift(float64 ms) {
|
||||
float dt = ms / _st.duration;
|
||||
bool res = true;
|
||||
void InputArea::step_placeholderShift(float64 ms, bool timer) {
|
||||
float64 dt = ms / _st.duration;
|
||||
if (dt >= 1) {
|
||||
res = false;
|
||||
_a_placeholderShift.stop();
|
||||
a_placeholderLeft.finish();
|
||||
a_placeholderOpacity.finish();
|
||||
} else {
|
||||
a_placeholderLeft.update(dt, anim::linear);
|
||||
a_placeholderOpacity.update(dt, anim::linear);
|
||||
}
|
||||
update();
|
||||
return res;
|
||||
if (timer) update();
|
||||
}
|
||||
|
||||
bool InputArea::animStep_border(float64 ms) {
|
||||
float dt = ms / _st.duration;
|
||||
void InputArea::step_border(float64 ms, bool timer) {
|
||||
float64 dt = ms / _st.duration;
|
||||
bool res = true;
|
||||
if (dt >= 1) {
|
||||
res = false;
|
||||
_a_border.stop();
|
||||
a_borderFg.finish();
|
||||
a_borderOpacityActive.finish();
|
||||
} else {
|
||||
a_borderFg.update(dt, anim::linear);
|
||||
a_borderOpacityActive.update(dt, anim::linear);
|
||||
}
|
||||
update();
|
||||
return res;
|
||||
if (timer) update();
|
||||
}
|
||||
|
||||
void InputArea::updatePlaceholder() {
|
||||
@@ -1261,36 +1265,37 @@ void InputArea::showError() {
|
||||
}
|
||||
}
|
||||
|
||||
InputField::InputField(QWidget *parent, const style::InputField &st, const QString &ph, const QString &val) : TWidget(parent),
|
||||
_maxLength(-1),
|
||||
_inner(this),
|
||||
_oldtext(val),
|
||||
InputField::InputField(QWidget *parent, const style::InputField &st, const QString &ph, const QString &val) : TWidget(parent)
|
||||
, _maxLength(-1)
|
||||
, _inner(this)
|
||||
, _oldtext(val)
|
||||
|
||||
_undoAvailable(false),
|
||||
_redoAvailable(false),
|
||||
, _undoAvailable(false)
|
||||
, _redoAvailable(false)
|
||||
|
||||
_customUpDown(true),
|
||||
, _customUpDown(true)
|
||||
|
||||
_placeholderFull(ph),
|
||||
_placeholderVisible(val.isEmpty()),
|
||||
a_placeholderLeft(_placeholderVisible ? 0 : st.placeholderShift),
|
||||
a_placeholderOpacity(_placeholderVisible ? 1 : 0),
|
||||
a_placeholderFg(st.placeholderFg->c),
|
||||
_a_placeholderFg(animFunc(this, &InputField::animStep_placeholderFg)),
|
||||
_a_placeholderShift(animFunc(this, &InputField::animStep_placeholderShift)),
|
||||
, _placeholderFull(ph)
|
||||
, _placeholderVisible(val.isEmpty())
|
||||
, a_placeholderLeft(_placeholderVisible ? 0 : st.placeholderShift)
|
||||
, a_placeholderOpacity(_placeholderVisible ? 1 : 0)
|
||||
, a_placeholderFg(st.placeholderFg->c)
|
||||
, _a_placeholderFg(animation(this, &InputField::step_placeholderFg))
|
||||
, _a_placeholderShift(animation(this, &InputField::step_placeholderShift))
|
||||
|
||||
a_borderOpacityActive(0),
|
||||
a_borderFg(st.borderFg->c),
|
||||
_a_border(animFunc(this, &InputField::animStep_border)),
|
||||
, a_borderOpacityActive(0)
|
||||
, a_borderFg(st.borderFg->c)
|
||||
, _a_border(animation(this, &InputField::step_border))
|
||||
|
||||
_focused(false), _error(false),
|
||||
, _focused(false)
|
||||
, _error(false)
|
||||
|
||||
_st(st),
|
||||
, _st(st)
|
||||
|
||||
_touchPress(false),
|
||||
_touchRightButton(false),
|
||||
_touchMove(false),
|
||||
_correcting(false) {
|
||||
, _touchPress(false)
|
||||
, _touchRightButton(false)
|
||||
, _touchMove(false)
|
||||
, _correcting(false) {
|
||||
_inner.setAcceptRichText(false);
|
||||
resize(_st.width, _st.height);
|
||||
|
||||
@@ -1834,47 +1839,41 @@ void InputField::selectAll() {
|
||||
_inner.setTextCursor(c);
|
||||
}
|
||||
|
||||
bool InputField::animStep_placeholderFg(float64 ms) {
|
||||
float dt = ms / _st.duration;
|
||||
bool res = true;
|
||||
void InputField::step_placeholderFg(float64 ms, bool timer) {
|
||||
float64 dt = ms / _st.duration;
|
||||
if (dt >= 1) {
|
||||
res = false;
|
||||
_a_placeholderFg.stop();
|
||||
a_placeholderFg.finish();
|
||||
} else {
|
||||
a_placeholderFg.update(dt, anim::linear);
|
||||
}
|
||||
update();
|
||||
return res;
|
||||
if (timer) update();
|
||||
}
|
||||
|
||||
bool InputField::animStep_placeholderShift(float64 ms) {
|
||||
float dt = ms / _st.duration;
|
||||
bool res = true;
|
||||
void InputField::step_placeholderShift(float64 ms, bool timer) {
|
||||
float64 dt = ms / _st.duration;
|
||||
if (dt >= 1) {
|
||||
res = false;
|
||||
_a_placeholderShift.stop();
|
||||
a_placeholderLeft.finish();
|
||||
a_placeholderOpacity.finish();
|
||||
} else {
|
||||
a_placeholderLeft.update(dt, anim::linear);
|
||||
a_placeholderOpacity.update(dt, anim::linear);
|
||||
}
|
||||
update();
|
||||
return res;
|
||||
if (timer) update();
|
||||
}
|
||||
|
||||
bool InputField::animStep_border(float64 ms) {
|
||||
float dt = ms / _st.duration;
|
||||
bool res = true;
|
||||
void InputField::step_border(float64 ms, bool timer) {
|
||||
float64 dt = ms / _st.duration;
|
||||
if (dt >= 1) {
|
||||
res = false;
|
||||
_a_border.stop();
|
||||
a_borderFg.finish();
|
||||
a_borderOpacityActive.finish();
|
||||
} else {
|
||||
a_borderFg.update(dt, anim::linear);
|
||||
a_borderOpacityActive.update(dt, anim::linear);
|
||||
}
|
||||
update();
|
||||
return res;
|
||||
if (timer) update();
|
||||
}
|
||||
|
||||
void InputField::updatePlaceholder() {
|
||||
@@ -1981,34 +1980,35 @@ void InputField::showError() {
|
||||
}
|
||||
}
|
||||
|
||||
MaskedInputField::MaskedInputField(QWidget *parent, const style::InputField &st, const QString &placeholder, const QString &val) : QLineEdit(val, parent),
|
||||
_st(st),
|
||||
_maxLength(-1),
|
||||
_oldtext(val),
|
||||
MaskedInputField::MaskedInputField(QWidget *parent, const style::InputField &st, const QString &placeholder, const QString &val) : QLineEdit(val, parent)
|
||||
, _st(st)
|
||||
, _maxLength(-1)
|
||||
, _oldtext(val)
|
||||
|
||||
_undoAvailable(false),
|
||||
_redoAvailable(false),
|
||||
, _undoAvailable(false)
|
||||
, _redoAvailable(false)
|
||||
|
||||
_customUpDown(false),
|
||||
, _customUpDown(false)
|
||||
|
||||
_placeholderFull(placeholder),
|
||||
_placeholderVisible(val.isEmpty()),
|
||||
_placeholderFast(false),
|
||||
a_placeholderLeft(_placeholderVisible ? 0 : st.placeholderShift),
|
||||
a_placeholderOpacity(_placeholderVisible ? 1 : 0),
|
||||
a_placeholderFg(st.placeholderFg->c),
|
||||
_a_placeholderFg(animFunc(this, &MaskedInputField::animStep_placeholderFg)),
|
||||
_a_placeholderShift(animFunc(this, &MaskedInputField::animStep_placeholderShift)),
|
||||
, _placeholderFull(placeholder)
|
||||
, _placeholderVisible(val.isEmpty())
|
||||
, _placeholderFast(false)
|
||||
, a_placeholderLeft(_placeholderVisible ? 0 : st.placeholderShift)
|
||||
, a_placeholderOpacity(_placeholderVisible ? 1 : 0)
|
||||
, a_placeholderFg(st.placeholderFg->c)
|
||||
, _a_placeholderFg(animation(this, &MaskedInputField::step_placeholderFg))
|
||||
, _a_placeholderShift(animation(this, &MaskedInputField::step_placeholderShift))
|
||||
|
||||
a_borderOpacityActive(0),
|
||||
a_borderFg(st.borderFg->c),
|
||||
_a_border(animFunc(this, &MaskedInputField::animStep_border)),
|
||||
, a_borderOpacityActive(0)
|
||||
, a_borderFg(st.borderFg->c)
|
||||
, _a_border(animation(this, &MaskedInputField::step_border))
|
||||
|
||||
_focused(false), _error(false),
|
||||
, _focused(false)
|
||||
, _error(false)
|
||||
|
||||
_touchPress(false),
|
||||
_touchRightButton(false),
|
||||
_touchMove(false) {
|
||||
, _touchPress(false)
|
||||
, _touchRightButton(false)
|
||||
, _touchMove(false) {
|
||||
resize(_st.width, _st.height);
|
||||
|
||||
setFont(_st.font->f);
|
||||
@@ -2188,47 +2188,41 @@ QSize MaskedInputField::minimumSizeHint() const {
|
||||
return geometry().size();
|
||||
}
|
||||
|
||||
bool MaskedInputField::animStep_placeholderFg(float64 ms) {
|
||||
float dt = ms / _st.duration;
|
||||
bool res = true;
|
||||
void MaskedInputField::step_placeholderFg(float64 ms, bool timer) {
|
||||
float64 dt = ms / _st.duration;
|
||||
if (dt >= 1) {
|
||||
res = false;
|
||||
_a_placeholderFg.stop();
|
||||
a_placeholderFg.finish();
|
||||
} else {
|
||||
a_placeholderFg.update(dt, anim::linear);
|
||||
}
|
||||
update();
|
||||
return res;
|
||||
if (timer) update();
|
||||
}
|
||||
|
||||
bool MaskedInputField::animStep_placeholderShift(float64 ms) {
|
||||
float dt = ms / _st.duration;
|
||||
bool res = true;
|
||||
void MaskedInputField::step_placeholderShift(float64 ms, bool timer) {
|
||||
float64 dt = ms / _st.duration;
|
||||
if (dt >= 1) {
|
||||
res = false;
|
||||
_a_placeholderShift.stop();
|
||||
a_placeholderLeft.finish();
|
||||
a_placeholderOpacity.finish();
|
||||
} else {
|
||||
a_placeholderLeft.update(dt, anim::linear);
|
||||
a_placeholderOpacity.update(dt, anim::linear);
|
||||
}
|
||||
update();
|
||||
return res;
|
||||
if (timer) update();
|
||||
}
|
||||
|
||||
bool MaskedInputField::animStep_border(float64 ms) {
|
||||
float dt = ms / _st.duration;
|
||||
bool res = true;
|
||||
void MaskedInputField::step_border(float64 ms, bool timer) {
|
||||
float64 dt = ms / _st.duration;
|
||||
if (dt >= 1) {
|
||||
res = false;
|
||||
_a_border.stop();
|
||||
a_borderFg.finish();
|
||||
a_borderOpacityActive.finish();
|
||||
} else {
|
||||
a_borderFg.update(dt, anim::linear);
|
||||
a_borderOpacityActive.update(dt, anim::linear);
|
||||
}
|
||||
update();
|
||||
return res;
|
||||
if (timer) update();
|
||||
}
|
||||
|
||||
bool MaskedInputField::setPlaceholder(const QString &placeholder) {
|
||||
|
@@ -23,7 +23,7 @@ Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
|
||||
#include "style.h"
|
||||
#include "animation.h"
|
||||
|
||||
class FlatInput : public QLineEdit, public Animated {
|
||||
class FlatInput : public QLineEdit {
|
||||
Q_OBJECT
|
||||
T_WIDGET
|
||||
|
||||
@@ -50,7 +50,7 @@ public:
|
||||
|
||||
QRect getTextRect() const;
|
||||
|
||||
bool animStep(float64 ms);
|
||||
void step_appearance(float64 ms, bool timer);
|
||||
|
||||
QSize sizeHint() const;
|
||||
QSize minimumSizeHint() const;
|
||||
@@ -98,6 +98,7 @@ private:
|
||||
anim::ivalue a_phLeft;
|
||||
anim::fvalue a_phAlpha;
|
||||
anim::cvalue a_phColor, a_borderColor, a_bgColor;
|
||||
Animation _a_appearance;
|
||||
|
||||
int _notingBene;
|
||||
style::flatInput _st;
|
||||
@@ -196,9 +197,9 @@ public:
|
||||
}
|
||||
void updatePlaceholder();
|
||||
|
||||
bool animStep_placeholderFg(float64 ms);
|
||||
bool animStep_placeholderShift(float64 ms);
|
||||
bool animStep_border(float64 ms);
|
||||
void step_placeholderFg(float64 ms, bool timer);
|
||||
void step_placeholderShift(float64 ms, bool timer);
|
||||
void step_border(float64 ms, bool timer);
|
||||
|
||||
QSize sizeHint() const;
|
||||
QSize minimumSizeHint() const;
|
||||
@@ -354,9 +355,9 @@ public:
|
||||
}
|
||||
void updatePlaceholder();
|
||||
|
||||
bool animStep_placeholderFg(float64 ms);
|
||||
bool animStep_placeholderShift(float64 ms);
|
||||
bool animStep_border(float64 ms);
|
||||
void step_placeholderFg(float64 ms, bool timer);
|
||||
void step_placeholderShift(float64 ms, bool timer);
|
||||
void step_border(float64 ms, bool timer);
|
||||
|
||||
QSize sizeHint() const;
|
||||
QSize minimumSizeHint() const;
|
||||
@@ -523,9 +524,9 @@ public:
|
||||
|
||||
QRect getTextRect() const;
|
||||
|
||||
bool animStep_placeholderFg(float64 ms);
|
||||
bool animStep_placeholderShift(float64 ms);
|
||||
bool animStep_border(float64 ms);
|
||||
void step_placeholderFg(float64 ms, bool timer);
|
||||
void step_placeholderShift(float64 ms, bool timer);
|
||||
void step_border(float64 ms, bool timer);
|
||||
|
||||
QSize sizeHint() const;
|
||||
QSize minimumSizeHint() const;
|
||||
|
@@ -24,12 +24,27 @@ Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
|
||||
#include "flattextarea.h"
|
||||
#include "window.h"
|
||||
|
||||
FlatTextarea::FlatTextarea(QWidget *parent, const style::flatTextarea &st, const QString &pholder, const QString &v) : QTextEdit(parent),
|
||||
_minHeight(-1), _maxHeight(-1), _maxLength(-1), _ctrlEnterSubmit(true),
|
||||
_oldtext(v), _phVisible(!v.length()),
|
||||
a_phLeft(_phVisible ? 0 : st.phShift), a_phAlpha(_phVisible ? 1 : 0), a_phColor(st.phColor->c),
|
||||
_st(st), _undoAvailable(false), _redoAvailable(false), _inDrop(false), _inHeightCheck(false), _fakeMargin(0),
|
||||
_touchPress(false), _touchRightButton(false), _touchMove(false), _correcting(false) {
|
||||
FlatTextarea::FlatTextarea(QWidget *parent, const style::flatTextarea &st, const QString &pholder, const QString &v) : QTextEdit(parent)
|
||||
, _minHeight(-1)
|
||||
, _maxHeight(-1)
|
||||
, _maxLength(-1)
|
||||
, _ctrlEnterSubmit(true)
|
||||
, _oldtext(v)
|
||||
, _phVisible(!v.length())
|
||||
, a_phLeft(_phVisible ? 0 : st.phShift)
|
||||
, a_phAlpha(_phVisible ? 1 : 0)
|
||||
, a_phColor(st.phColor->c)
|
||||
, _a_appearance(animation(this, &FlatTextarea::step_appearance))
|
||||
, _st(st)
|
||||
, _undoAvailable(false)
|
||||
, _redoAvailable(false)
|
||||
, _inDrop(false)
|
||||
, _inHeightCheck(false)
|
||||
, _fakeMargin(0)
|
||||
, _touchPress(false)
|
||||
, _touchRightButton(false)
|
||||
, _touchMove(false)
|
||||
, _correcting(false) {
|
||||
setAcceptRichText(false);
|
||||
resize(_st.width, _st.font->height);
|
||||
|
||||
@@ -74,10 +89,10 @@ _touchPress(false), _touchRightButton(false), _touchMove(false), _correcting(fal
|
||||
|
||||
void FlatTextarea::setTextFast(const QString &text) {
|
||||
setPlainText(text);
|
||||
if (animating()) {
|
||||
if (_a_appearance.animating()) {
|
||||
a_phLeft.finish();
|
||||
a_phAlpha.finish();
|
||||
anim::stop(this);
|
||||
_a_appearance.stop();
|
||||
update();
|
||||
}
|
||||
}
|
||||
@@ -184,7 +199,7 @@ void FlatTextarea::paintEvent(QPaintEvent *e) {
|
||||
QRect r(rect().intersected(e->rect()));
|
||||
p.fillRect(r, _st.bgColor->b);
|
||||
bool phDraw = _phVisible;
|
||||
if (animating()) {
|
||||
if (_a_appearance.animating()) {
|
||||
p.setOpacity(a_phAlpha.current());
|
||||
phDraw = true;
|
||||
}
|
||||
@@ -203,13 +218,13 @@ void FlatTextarea::paintEvent(QPaintEvent *e) {
|
||||
|
||||
void FlatTextarea::focusInEvent(QFocusEvent *e) {
|
||||
a_phColor.start(_st.phFocusColor->c);
|
||||
anim::start(this);
|
||||
_a_appearance.start();
|
||||
QTextEdit::focusInEvent(e);
|
||||
}
|
||||
|
||||
void FlatTextarea::focusOutEvent(QFocusEvent *e) {
|
||||
a_phColor.start(_st.phColor->c);
|
||||
anim::start(this);
|
||||
_a_appearance.start();
|
||||
QTextEdit::focusOutEvent(e);
|
||||
}
|
||||
|
||||
@@ -807,11 +822,10 @@ void FlatTextarea::onRedoAvailable(bool avail) {
|
||||
if (App::wnd()) App::wnd()->updateGlobalMenu();
|
||||
}
|
||||
|
||||
bool FlatTextarea::animStep(float64 ms) {
|
||||
void FlatTextarea::step_appearance(float64 ms, bool timer) {
|
||||
float dt = ms / _st.phDuration;
|
||||
bool res = true;
|
||||
if (dt >= 1) {
|
||||
res = false;
|
||||
_a_appearance.stop();
|
||||
a_phLeft.finish();
|
||||
a_phAlpha.finish();
|
||||
a_phColor.finish();
|
||||
@@ -823,8 +837,7 @@ bool FlatTextarea::animStep(float64 ms) {
|
||||
a_phAlpha.update(dt, _st.phAlphaFunc);
|
||||
a_phColor.update(dt, _st.phColorFunc);
|
||||
}
|
||||
update();
|
||||
return res;
|
||||
if (timer) update();
|
||||
}
|
||||
|
||||
void FlatTextarea::setPlaceholder(const QString &ph) {
|
||||
@@ -839,7 +852,7 @@ void FlatTextarea::updatePlaceholder() {
|
||||
|
||||
a_phLeft.start(vis ? 0 : _st.phShift);
|
||||
a_phAlpha.start(vis ? 1 : 0);
|
||||
anim::start(this);
|
||||
_a_appearance.start();
|
||||
|
||||
_phVisible = vis;
|
||||
}
|
||||
|
@@ -24,7 +24,7 @@ Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
|
||||
#include "style.h"
|
||||
#include "animation.h"
|
||||
|
||||
class FlatTextarea : public QTextEdit, public Animated {
|
||||
class FlatTextarea : public QTextEdit {
|
||||
Q_OBJECT
|
||||
T_WIDGET
|
||||
|
||||
@@ -56,7 +56,7 @@ public:
|
||||
QRect getTextRect() const;
|
||||
int32 fakeMargin() const;
|
||||
|
||||
bool animStep(float64 ms);
|
||||
void step_appearance(float64 ms, bool timer);
|
||||
|
||||
QSize sizeHint() const;
|
||||
QSize minimumSizeHint() const;
|
||||
@@ -127,6 +127,8 @@ private:
|
||||
anim::ivalue a_phLeft;
|
||||
anim::fvalue a_phAlpha;
|
||||
anim::cvalue a_phColor;
|
||||
Animation _a_appearance;
|
||||
|
||||
style::flatTextarea _st;
|
||||
|
||||
bool _undoAvailable, _redoAvailable, _inDrop, _inHeightCheck;
|
||||
|
@@ -36,7 +36,7 @@ PopupMenu::PopupMenu(const style::PopupMenu &st) : TWidget(0)
|
||||
, _selected(-1)
|
||||
, _childMenuIndex(-1)
|
||||
, a_opacity(1)
|
||||
, _a_hide(animFunc(this, &PopupMenu::animStep_hide))
|
||||
, _a_hide(animation(this, &PopupMenu::step_hide))
|
||||
, _deleteOnHide(true)
|
||||
, _triggering(false)
|
||||
, _deleteLater(false) {
|
||||
@@ -54,7 +54,7 @@ PopupMenu::PopupMenu(QMenu *menu, const style::PopupMenu &st) : TWidget(0)
|
||||
, _selected(-1)
|
||||
, _childMenuIndex(-1)
|
||||
, a_opacity(1)
|
||||
, _a_hide(animFunc(this, &PopupMenu::animStep_hide))
|
||||
, _a_hide(animation(this, &PopupMenu::step_hide))
|
||||
, _deleteOnHide(true)
|
||||
, _triggering(false)
|
||||
, _deleteLater(false) {
|
||||
@@ -440,18 +440,16 @@ void PopupMenu::hideFinish() {
|
||||
hide();
|
||||
}
|
||||
|
||||
bool PopupMenu::animStep_hide(float64 ms) {
|
||||
void PopupMenu::step_hide(float64 ms, bool timer) {
|
||||
float64 dt = ms / _st.duration;
|
||||
bool res = true;
|
||||
if (dt >= 1) {
|
||||
_a_hide.stop();
|
||||
a_opacity.finish();
|
||||
hideFinish();
|
||||
res = false;
|
||||
} else {
|
||||
a_opacity.update(dt, anim::linear);
|
||||
}
|
||||
update();
|
||||
return res;
|
||||
if (timer) update();
|
||||
}
|
||||
|
||||
void PopupMenu::deleteOnHide(bool del) {
|
||||
|
@@ -59,7 +59,7 @@ private:
|
||||
|
||||
void childHiding(PopupMenu *child);
|
||||
|
||||
bool animStep_hide(float64 ms);
|
||||
void step_hide(float64 ms, bool timer);
|
||||
|
||||
void init();
|
||||
void hideFinish();
|
||||
|
@@ -38,12 +38,20 @@ void ScrollShadow::changeVisibility(bool shown) {
|
||||
setVisible(shown);
|
||||
}
|
||||
|
||||
ScrollBar::ScrollBar(ScrollArea *parent, bool vert, const style::flatScroll *st) : QWidget(parent), _st(st), _vertical(vert),
|
||||
_over(false), _overbar(false), _moving(false), _topSh(false), _bottomSh(false),
|
||||
_connected(vert ? parent->verticalScrollBar() : parent->horizontalScrollBar()),
|
||||
_scrollMax(_connected->maximum()), _hideIn(-1),
|
||||
a_bg((_st->hiding ? st::transparent : _st->bgColor)->c),
|
||||
a_bar((_st->hiding ? st::transparent : _st->barColor)->c) {
|
||||
ScrollBar::ScrollBar(ScrollArea *parent, bool vert, const style::flatScroll *st) : QWidget(parent)
|
||||
, _st(st)
|
||||
, _vertical(vert)
|
||||
, _over(false)
|
||||
, _overbar(false)
|
||||
, _moving(false)
|
||||
, _topSh(false)
|
||||
, _bottomSh(false)
|
||||
, _connected(vert ? parent->verticalScrollBar() : parent->horizontalScrollBar())
|
||||
, _scrollMax(_connected->maximum())
|
||||
, _hideIn(-1)
|
||||
, a_bg((_st->hiding ? st::transparent : _st->bgColor)->c)
|
||||
, a_bar((_st->hiding ? st::transparent : _st->barColor)->c)
|
||||
, _a_appearance(animation(this, &ScrollBar::step_appearance)) {
|
||||
recountSize();
|
||||
|
||||
_hideTimer.setSingleShot(true);
|
||||
@@ -115,7 +123,7 @@ void ScrollBar::onHideTimer() {
|
||||
_hideIn = -1;
|
||||
a_bg.start(QColor(a_bg.current().red(), a_bg.current().green(), a_bg.current().blue(), 0));
|
||||
a_bar.start(QColor(a_bar.current().red(), a_bar.current().green(), a_bar.current().blue(), 0));
|
||||
anim::start(this);
|
||||
_a_appearance.start();
|
||||
}
|
||||
|
||||
ScrollArea *ScrollBar::area() {
|
||||
@@ -144,26 +152,24 @@ void ScrollBar::paintEvent(QPaintEvent *e) {
|
||||
}
|
||||
}
|
||||
|
||||
bool ScrollBar::animStep(float64 ms) {
|
||||
void ScrollBar::step_appearance(float64 ms, bool timer) {
|
||||
float64 dt = ms / _st->duration;
|
||||
bool res = true;
|
||||
if (dt >= 1) {
|
||||
_a_appearance.stop();
|
||||
a_bg.finish();
|
||||
a_bar.finish();
|
||||
res = false;
|
||||
} else {
|
||||
a_bg.update(dt, anim::linear);
|
||||
a_bar.update(dt, anim::linear);
|
||||
}
|
||||
update();
|
||||
return res;
|
||||
if (timer) update();
|
||||
}
|
||||
|
||||
void ScrollBar::hideTimeout(int64 dt) {
|
||||
if (_hideIn < 0) {
|
||||
a_bg.start((_over ? _st->bgOverColor : _st->bgColor)->c);
|
||||
a_bar.start((_overbar ? _st->barOverColor : _st->barColor)->c);
|
||||
anim::start(this);
|
||||
_a_appearance.start();
|
||||
}
|
||||
_hideIn = dt;
|
||||
if (!_moving && _hideIn >= 0) {
|
||||
@@ -177,7 +183,7 @@ void ScrollBar::enterEvent(QEvent *e) {
|
||||
_over = true;
|
||||
a_bg.start(_st->bgOverColor->c);
|
||||
a_bar.start(_st->barColor->c);
|
||||
anim::start(this);
|
||||
_a_appearance.start();
|
||||
}
|
||||
|
||||
void ScrollBar::leaveEvent(QEvent *e) {
|
||||
@@ -185,7 +191,7 @@ void ScrollBar::leaveEvent(QEvent *e) {
|
||||
setMouseTracking(false);
|
||||
a_bg.start(_st->bgColor->c);
|
||||
a_bar.start(_st->barColor->c);
|
||||
anim::start(this);
|
||||
_a_appearance.start();
|
||||
if (_hideIn >= 0) {
|
||||
_hideTimer.start(_hideIn);
|
||||
} else if (_st->hiding) {
|
||||
@@ -202,7 +208,7 @@ void ScrollBar::mouseMoveEvent(QMouseEvent *e) {
|
||||
if (!_moving) {
|
||||
a_bar.start((newOverBar ? _st->barOverColor : _st->barColor)->c);
|
||||
a_bg.start(_st->bgOverColor->c);
|
||||
anim::start(this);
|
||||
_a_appearance.start();
|
||||
}
|
||||
}
|
||||
if (_moving) {
|
||||
@@ -232,7 +238,7 @@ void ScrollBar::mousePressEvent(QMouseEvent *e) {
|
||||
_overbar = true;
|
||||
a_bar.start(_st->barOverColor->c);
|
||||
a_bg.start(_st->bgOverColor->c);
|
||||
anim::start(this);
|
||||
_a_appearance.start();
|
||||
}
|
||||
}
|
||||
emit area()->scrollStarted();
|
||||
@@ -257,7 +263,7 @@ void ScrollBar::mouseReleaseEvent(QMouseEvent *e) {
|
||||
_hideTimer.start(_hideIn);
|
||||
}
|
||||
}
|
||||
if (a) anim::start(this);
|
||||
if (a) _a_appearance.start();
|
||||
emit area()->scrollFinished();
|
||||
}
|
||||
if (!_over) {
|
||||
|
@@ -50,7 +50,7 @@ private:
|
||||
|
||||
};
|
||||
|
||||
class ScrollBar : public QWidget, public Animated {
|
||||
class ScrollBar : public QWidget {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
@@ -67,7 +67,7 @@ public:
|
||||
void mouseReleaseEvent(QMouseEvent *e);
|
||||
void resizeEvent(QResizeEvent *e);
|
||||
|
||||
bool animStep(float64 ms);
|
||||
void step_appearance(float64 ms, bool timer);
|
||||
|
||||
void hideTimeout(int64 dt);
|
||||
|
||||
@@ -100,6 +100,8 @@ private:
|
||||
QTimer _hideTimer;
|
||||
|
||||
anim::cvalue a_bg, a_bar;
|
||||
Animation _a_appearance;
|
||||
|
||||
QRect _bar;
|
||||
};
|
||||
|
||||
|
@@ -1,160 +0,0 @@
|
||||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
the official desktop version of Telegram messaging app, see https://telegram.org
|
||||
|
||||
Telegram Desktop is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
It is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
In addition, as a special exception, the copyright holders give permission
|
||||
to link the code of portions of this program with the OpenSSL library.
|
||||
|
||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||
Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
|
||||
*/
|
||||
#include "stdafx.h"
|
||||
#include "switcher.h"
|
||||
|
||||
Switcher::Switcher(QWidget *parent, const style::switcher &st) : TWidget(parent)
|
||||
, _selected(0)
|
||||
, _over(-1)
|
||||
, _wasOver(-1)
|
||||
, _pressed(-1)
|
||||
, _st(st)
|
||||
, a_bgOver(_st.bgColor->c)
|
||||
, a_bgWasOver(_st.bgHovered->c) {
|
||||
resize(width(), _st.height);
|
||||
}
|
||||
|
||||
void Switcher::leaveEvent(QEvent *e) {
|
||||
setOver(-1);
|
||||
if (_pressed >= 0) return;
|
||||
|
||||
setMouseTracking(false);
|
||||
return TWidget::leaveEvent(e);
|
||||
}
|
||||
|
||||
void Switcher::enterEvent(QEvent *e) {
|
||||
setMouseTracking(true);
|
||||
return TWidget::enterEvent(e);
|
||||
}
|
||||
|
||||
void Switcher::mousePressEvent(QMouseEvent *e) {
|
||||
if (e->buttons() & Qt::LeftButton) {
|
||||
mouseMoveEvent(e);
|
||||
if (_over != _pressed) {
|
||||
_pressed = _over;
|
||||
e->accept();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Switcher::mouseMoveEvent(QMouseEvent *e) {
|
||||
if (rect().contains(e->pos())) {
|
||||
if (width()) {
|
||||
setOver((e->pos().x() * _buttons.size()) / width());
|
||||
}
|
||||
} else {
|
||||
setOver(-1);
|
||||
}
|
||||
}
|
||||
|
||||
void Switcher::mouseReleaseEvent(QMouseEvent *e) {
|
||||
if (_pressed >= 0) {
|
||||
if (_pressed == _over && _pressed != _selected) {
|
||||
setSelected(_pressed);
|
||||
} else {
|
||||
setSelected(_selected);
|
||||
}
|
||||
} else {
|
||||
leaveEvent(e);
|
||||
}
|
||||
}
|
||||
|
||||
void Switcher::addButton(const QString &btn) {
|
||||
_buttons.push_back(btn);
|
||||
update();
|
||||
}
|
||||
|
||||
bool Switcher::animStep(float64 ms) {
|
||||
float64 dt = ms / _st.duration;
|
||||
bool res = true;
|
||||
if (dt >= 1) {
|
||||
res = false;
|
||||
a_bgOver.finish();
|
||||
a_bgWasOver.finish();
|
||||
} else {
|
||||
a_bgOver.update(dt, anim::linear);
|
||||
a_bgWasOver.update(dt, anim::linear);
|
||||
}
|
||||
update();
|
||||
return res;
|
||||
}
|
||||
|
||||
void Switcher::paintEvent(QPaintEvent *e) {
|
||||
QPainter p(this);
|
||||
|
||||
p.fillRect(rect(), _st.bgColor->b);
|
||||
if (!_buttons.isEmpty()) {
|
||||
p.setFont(_st.font->f);
|
||||
float64 btnWidth = float64(width()) / _buttons.size();
|
||||
for (int i = 0; i < _buttons.size(); ++i) {
|
||||
QRect btnRect(qRound(i * btnWidth), 0, qRound((i + 1) * btnWidth) - qRound(i * btnWidth), height());
|
||||
if (i == _selected) {
|
||||
p.fillRect(btnRect, _st.bgActive->b);
|
||||
} else if (i == _over) {
|
||||
p.fillRect(btnRect, a_bgOver.current());
|
||||
} else if (i == _wasOver) {
|
||||
p.fillRect(btnRect, a_bgWasOver.current());
|
||||
}
|
||||
p.setPen((i == _selected ? _st.activeColor : _st.textColor)->p);
|
||||
p.drawText(btnRect, _buttons[i], style::al_center);
|
||||
}
|
||||
}
|
||||
if (_st.border) {
|
||||
p.fillRect(0, 0, width() - _st.border, _st.border, _st.borderColor->b);
|
||||
p.fillRect(width() - _st.border, 0, _st.border, height() - _st.border, _st.borderColor->b);
|
||||
p.fillRect(_st.border, height() - _st.border, width() - _st.border, _st.border, _st.borderColor->b);
|
||||
p.fillRect(0, _st.border, _st.border, height() - _st.border, _st.borderColor->b);
|
||||
}
|
||||
}
|
||||
|
||||
int Switcher::selected() const {
|
||||
return _selected;
|
||||
}
|
||||
|
||||
void Switcher::setSelected(int selected) {
|
||||
if (selected != _selected) {
|
||||
_selected = selected;
|
||||
emit changed();
|
||||
}
|
||||
_pressed = _over = _wasOver = -1;
|
||||
anim::stop(this);
|
||||
setCursor(style::cur_default);
|
||||
update();
|
||||
}
|
||||
|
||||
void Switcher::setOver(int over) {
|
||||
if (over != _over) {
|
||||
QColor c(a_bgOver.current());
|
||||
if (_wasOver == over) {
|
||||
a_bgOver = anim::cvalue(a_bgWasOver.current(), _st.bgHovered->c);
|
||||
} else {
|
||||
a_bgOver = anim::cvalue(_st.bgColor->c, _st.bgHovered->c);
|
||||
}
|
||||
a_bgWasOver = anim::cvalue(c, _st.bgColor->c);
|
||||
|
||||
_wasOver = _over;
|
||||
_over = over;
|
||||
|
||||
anim::start(this);
|
||||
|
||||
setCursor((_over >= 0 && _over != _selected) ? style::cur_pointer : style::cur_default);
|
||||
}
|
||||
}
|
@@ -1,65 +0,0 @@
|
||||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
the official desktop version of Telegram messaging app, see https://telegram.org
|
||||
|
||||
Telegram Desktop is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
It is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
In addition, as a special exception, the copyright holders give permission
|
||||
to link the code of portions of this program with the OpenSSL library.
|
||||
|
||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||
Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <QtWidgets/QWidget>
|
||||
#include "gui/twidget.h"
|
||||
|
||||
class Switcher : public TWidget, public Animated {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
Switcher(QWidget *parent, const style::switcher &st);
|
||||
|
||||
void mousePressEvent(QMouseEvent *e);
|
||||
void mouseMoveEvent(QMouseEvent *e);
|
||||
void mouseReleaseEvent(QMouseEvent *e);
|
||||
|
||||
void paintEvent(QPaintEvent *e);
|
||||
|
||||
void enterEvent(QEvent *e);
|
||||
void leaveEvent(QEvent *e);
|
||||
|
||||
void addButton(const QString &btn);
|
||||
|
||||
bool animStep(float64 ms);
|
||||
|
||||
int selected() const;
|
||||
void setSelected(int selected);
|
||||
|
||||
signals:
|
||||
|
||||
void changed();
|
||||
|
||||
private:
|
||||
|
||||
void setOver(int over);
|
||||
|
||||
int _selected;
|
||||
int _over, _wasOver, _pressed;
|
||||
|
||||
typedef QVector<QString> Buttons;
|
||||
Buttons _buttons;
|
||||
|
||||
style::switcher _st;
|
||||
anim::cvalue a_bgOver, a_bgWasOver;
|
||||
|
||||
};
|
Reference in New Issue
Block a user