Display emoji set loading radial animation.

This commit is contained in:
John Preston 2018-12-27 13:37:11 +04:00
parent aa2c52c1f8
commit df389a365c
5 changed files with 123 additions and 18 deletions

View File

@ -271,3 +271,5 @@ manageEmojiCheck: IconButton(defaultIconButton) {
height: 13px; height: 13px;
icon: stickersFeaturedInstalled; icon: stickersFeaturedInstalled;
} }
manageEmojiRadialSize: size(20px, 20px);
manageEmojiRadialThickness: 2px;

View File

@ -108,16 +108,29 @@ public:
protected: protected:
void paintEvent(QPaintEvent *e) override; void paintEvent(QPaintEvent *e) override;
void onStateChanged(State was, StateChangeSource source) override;
private: private:
[[nodiscard]] bool showOver() const;
[[nodiscard]] bool showOver(State state) const;
void setupContent(const Set &set); void setupContent(const Set &set);
void setupCheck(); void setupCheck();
void setupLabels(const Set &set); void setupLabels(const Set &set);
void setupAnimation();
void updateAnimation(TimeMs ms);
void setupHandler(); void setupHandler();
void load(); void load();
void step_radial(TimeMs ms, bool timer);
[[nodiscard]] QRect rightPartRect(QSize size) const;
[[nodiscard]] QRect radialRect() const;
[[nodiscard]] QRect checkRect() const;
int _id = 0; int _id = 0;
bool _switching = false; bool _switching = false;
rpl::variable<SetState> _state; rpl::variable<SetState> _state;
Ui::FlatLabel *_status = nullptr;
std::unique_ptr<Ui::RadialAnimation> _loading; std::unique_ptr<Ui::RadialAnimation> _loading;
}; };
@ -331,15 +344,64 @@ Row::Row(QWidget *widget, const Set &set)
void Row::paintEvent(QPaintEvent *e) { void Row::paintEvent(QPaintEvent *e) {
Painter p(this); Painter p(this);
if (isDisabled()) { const auto over = showOver();
return;
}
const auto over = isOver() || isDown();
const auto bg = over ? st::windowBgOver : st::windowBg; const auto bg = over ? st::windowBgOver : st::windowBg;
p.fillRect(rect(), bg); p.fillRect(rect(), bg);
const auto ms = getms(); const auto ms = getms();
paintRipple(p, 0, 0, ms); paintRipple(p, 0, 0, ms);
updateAnimation(ms);
if (_loading) {
_loading->draw(
p,
radialRect(),
st::manageEmojiRadialThickness,
over ? st::windowSubTextFgOver : st::windowSubTextFg);
}
}
QRect Row::rightPartRect(QSize size) const {
const auto x = width()
- (st::contactsPadding.right()
+ st::contactsCheckPosition.x()
+ st::manageEmojiCheck.width)
+ (st::manageEmojiCheck.width / 2);
const auto y = st::contactsPadding.top()
+ (st::contactsPhotoSize - st::manageEmojiCheck.height) / 2
+ (st::manageEmojiCheck.height / 2);
return QRect(
QPoint(x, y) - QPoint(size.width() / 2, size.height() / 2),
size);
}
QRect Row::radialRect() const {
return rightPartRect(st::manageEmojiRadialSize);
}
QRect Row::checkRect() const {
return rightPartRect(QSize(
st::manageEmojiCheck.width,
st::manageEmojiCheck.height));
}
bool Row::showOver(State state) const {
return (!(state & StateFlag::Disabled))
&& (state & (StateFlag::Over | StateFlag::Down));
}
bool Row::showOver() const {
return showOver(state());
}
void Row::onStateChanged(State was, StateChangeSource source) {
RippleButton::onStateChanged(was, source);
const auto over = showOver();
if (over != showOver(was)) {
_status->setTextColorOverride(over
? std::make_optional(st::windowSubTextFgOver->c)
: std::nullopt);
}
} }
void Row::setupContent(const Set &set) { void Row::setupContent(const Set &set) {
@ -362,6 +424,7 @@ void Row::setupContent(const Set &set) {
setupCheck(); setupCheck();
setupLabels(set); setupLabels(set);
setupAnimation();
resize(width(), st::defaultPeerList.item.height); resize(width(), st::defaultPeerList.item.height);
} }
@ -410,19 +473,14 @@ void Row::setupCheck() {
st::manageEmojiCheck)); st::manageEmojiCheck));
sizeValue( sizeValue(
) | rpl::start_with_next([=](QSize size) { ) | rpl::start_with_next([=](QSize size) {
const auto checkx = size.width() const auto rect = checkRect();
- (st::contactsPadding.right() check->moveToLeft(rect.x(), rect.y());
+ st::contactsCheckPosition.x()
+ check->width());
const auto checky = st::contactsPadding.top()
+ (st::contactsPhotoSize - check->height()) / 2;
check->moveToLeft(checkx, checky);
}, check->lifetime()); }, check->lifetime());
check->toggleOn(_state.value( check->toggleOn(_state.value(
) | rpl::map( ) | rpl::map(
_1 == Active() _1 == Active()
) | rpl::distinct_until_changed()); ));
check->setAttribute(Qt::WA_TransparentForMouseEvents); check->setAttribute(Qt::WA_TransparentForMouseEvents);
} }
@ -436,11 +494,11 @@ void Row::setupLabels(const Set &set) {
Ui::FlatLabel::InitType::Simple, Ui::FlatLabel::InitType::Simple,
st::localStorageRowTitle); st::localStorageRowTitle);
name->setAttribute(Qt::WA_TransparentForMouseEvents); name->setAttribute(Qt::WA_TransparentForMouseEvents);
const auto status = Ui::CreateChild<Ui::FlatLabel>( _status = Ui::CreateChild<Ui::FlatLabel>(
this, this,
_state.value() | rpl::map(StateDescription), _state.value() | rpl::map(StateDescription),
st::localStorageRowSize); st::localStorageRowSize);
status->setAttribute(Qt::WA_TransparentForMouseEvents); _status->setAttribute(Qt::WA_TransparentForMouseEvents);
sizeValue( sizeValue(
) | rpl::start_with_next([=](QSize size) { ) | rpl::start_with_next([=](QSize size) {
@ -450,10 +508,46 @@ void Row::setupLabels(const Set &set) {
const auto statusy = st::contactsPadding.top() const auto statusy = st::contactsPadding.top()
+ st::contactsStatusTop; + st::contactsStatusTop;
name->moveToLeft(left, namey); name->moveToLeft(left, namey);
status->moveToLeft(left, statusy); _status->moveToLeft(left, statusy);
}, name->lifetime()); }, name->lifetime());
} }
void Row::step_radial(TimeMs ms, bool timer) {
if (timer && !anim::Disabled()) {
update();
}
}
void Row::setupAnimation() {
_state.value(
) | rpl::start_with_next([=](const SetState &state) {
update();
}, lifetime());
}
void Row::updateAnimation(TimeMs ms) {
const auto state = _state.current();
if (const auto loading = base::get_if<Loading>(&state)) {
const auto progress = (loading->size > 0)
? (loading->already / float64(loading->size))
: 0.;
if (!_loading) {
_loading = std::make_unique<Ui::RadialAnimation>(
animation(this, &Row::step_radial));
_loading->start(progress);
} else {
_loading->update(progress, false, getms());
}
} else if (_loading) {
_loading->update(state.is<Failed>() ? 0. : 1., true, getms());
} else {
_loading = nullptr;
}
if (_loading && !_loading->animating()) {
_loading = nullptr;
}
}
} // namespace } // namespace
ManageSetsBox::ManageSetsBox(QWidget*) { ManageSetsBox::ManageSetsBox(QWidget*) {

View File

@ -19,8 +19,6 @@ public:
protected: protected:
void prepare() override; void prepare() override;
private:
}; };
} // namespace Emoji } // namespace Emoji

View File

@ -805,10 +805,19 @@ void FlatLabel::setOpacity(float64 o) {
update(); update();
} }
void FlatLabel::setTextColorOverride(std::optional<QColor> color) {
_textColorOverride = color;
update();
}
void FlatLabel::paintEvent(QPaintEvent *e) { void FlatLabel::paintEvent(QPaintEvent *e) {
Painter p(this); Painter p(this);
p.setOpacity(_opacity); p.setOpacity(_opacity);
p.setPen(_st.textFg); if (_textColorOverride) {
p.setPen(*_textColorOverride);
} else {
p.setPen(_st.textFg);
}
p.setTextPalette(_st.palette); p.setTextPalette(_st.palette);
int textWidth = width() - _st.margin.left() - _st.margin.right(); int textWidth = width() - _st.margin.left() - _st.margin.right();
auto selection = _selection.empty() ? (_contextMenu ? _savedSelection : _selection) : _selection; auto selection = _selection.empty() ? (_contextMenu ? _savedSelection : _selection) : _selection;

View File

@ -97,6 +97,7 @@ public:
const style::FlatLabel &st = st::defaultFlatLabel); const style::FlatLabel &st = st::defaultFlatLabel);
void setOpacity(float64 o); void setOpacity(float64 o);
void setTextColorOverride(std::optional<QColor> color);
void setText(const QString &text); void setText(const QString &text);
void setRichText(const QString &text); void setRichText(const QString &text);
@ -175,6 +176,7 @@ private:
Text _text; Text _text;
const style::FlatLabel &_st; const style::FlatLabel &_st;
std::optional<QColor> _textColorOverride;
float64 _opacity = 1.; float64 _opacity = 1.;
int _allowedWidth = 0; int _allowedWidth = 0;