mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-06-05 06:33:57 +02:00
Scroll expanded emoji category icons by wheel.
This commit is contained in:
parent
007cb9d156
commit
f1144965c0
2 changed files with 109 additions and 98 deletions
|
@ -115,17 +115,42 @@ void StickerIcon::ensureMediaCreated() const {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename UpdateCallback>
|
||||||
|
StickersListFooter::ScrollState::ScrollState(UpdateCallback &&callback)
|
||||||
|
: animation([=](crl::time now) {
|
||||||
|
callback();
|
||||||
|
return animationCallback(now);
|
||||||
|
}) {
|
||||||
|
}
|
||||||
|
|
||||||
|
bool StickersListFooter::ScrollState::animationCallback(crl::time now) {
|
||||||
|
if (anim::Disabled()) {
|
||||||
|
now += st::stickerIconMove;
|
||||||
|
}
|
||||||
|
if (!animationStart) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
const auto dt = (now - animationStart) / float64(st::stickerIconMove);
|
||||||
|
if (dt >= 1.) {
|
||||||
|
animationStart = 0;
|
||||||
|
x.finish();
|
||||||
|
selectionX.finish();
|
||||||
|
selectionWidth.finish();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
x.update(dt, anim::linear);
|
||||||
|
selectionX.update(dt, anim::linear);
|
||||||
|
selectionWidth.update(dt, anim::linear);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
StickersListFooter::StickersListFooter(Descriptor &&descriptor)
|
StickersListFooter::StickersListFooter(Descriptor &&descriptor)
|
||||||
: InnerFooter(descriptor.parent)
|
: InnerFooter(descriptor.parent)
|
||||||
, _controller(descriptor.controller)
|
, _controller(descriptor.controller)
|
||||||
, _searchButtonVisible(descriptor.searchButtonVisible)
|
, _searchButtonVisible(descriptor.searchButtonVisible)
|
||||||
, _settingsButtonVisible(descriptor.settingsButtonVisible)
|
, _settingsButtonVisible(descriptor.settingsButtonVisible)
|
||||||
, _iconsAnimation([=](crl::time now) {
|
, _iconState([=] { update(); })
|
||||||
return iconsAnimationCallback(_iconState, now);
|
, _subiconState([=] { update(); })
|
||||||
})
|
|
||||||
, _subiconsAnimation([=](crl::time now) {
|
|
||||||
return iconsAnimationCallback(_subiconState, now);
|
|
||||||
})
|
|
||||||
, _selectionBg(st::roundRadiusSmall, st::windowBgRipple)
|
, _selectionBg(st::roundRadiusSmall, st::windowBgRipple)
|
||||||
, _barSelection(descriptor.barSelection) {
|
, _barSelection(descriptor.barSelection) {
|
||||||
setMouseTracking(true);
|
setMouseTracking(true);
|
||||||
|
@ -409,13 +434,15 @@ void StickersListFooter::updateEmojiSectionWidth() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void StickersListFooter::updateEmojiWidthCallback() {
|
void StickersListFooter::updateEmojiWidthCallback() {
|
||||||
update();
|
refreshScrollableDimensions();
|
||||||
|
const auto shift = int(base::SafeRound(_iconState.x.current()));
|
||||||
const auto info = iconInfo(_iconState.selected);
|
const auto info = iconInfo(_iconState.selected);
|
||||||
UpdateAnimated(_iconState.selectionX, info.left);
|
UpdateAnimated(_iconState.selectionX, shift + info.left);
|
||||||
UpdateAnimated(_iconState.selectionWidth, info.width);
|
UpdateAnimated(_iconState.selectionWidth, info.width);
|
||||||
if (_iconsAnimation.animating()) {
|
if (_iconState.animation.animating()) {
|
||||||
iconsAnimationCallback(_iconState, crl::now());
|
_iconState.animationCallback(crl::now());
|
||||||
}
|
}
|
||||||
|
update();
|
||||||
}
|
}
|
||||||
|
|
||||||
void StickersListFooter::setSelectedIcon(
|
void StickersListFooter::setSelectedIcon(
|
||||||
|
@ -438,11 +465,11 @@ void StickersListFooter::setSelectedIcon(
|
||||||
_iconState.max);
|
_iconState.max);
|
||||||
if (animations == ValidateIconAnimations::None) {
|
if (animations == ValidateIconAnimations::None) {
|
||||||
_iconState.x = anim::value(iconsXFinal, iconsXFinal);
|
_iconState.x = anim::value(iconsXFinal, iconsXFinal);
|
||||||
_iconsAnimation.stop();
|
_iconState.animation.stop();
|
||||||
} else {
|
} else {
|
||||||
_iconState.x.start(iconsXFinal);
|
_iconState.x.start(iconsXFinal);
|
||||||
_iconState.animationStart = crl::now();
|
_iconState.animationStart = crl::now();
|
||||||
_iconsAnimation.start();
|
_iconState.animation.start();
|
||||||
}
|
}
|
||||||
updateSelected();
|
updateSelected();
|
||||||
update();
|
update();
|
||||||
|
@ -467,11 +494,11 @@ void StickersListFooter::setSelectedSubicon(
|
||||||
_subiconState.max);
|
_subiconState.max);
|
||||||
if (animations == ValidateIconAnimations::None) {
|
if (animations == ValidateIconAnimations::None) {
|
||||||
_subiconState.x = anim::value(subiconsXFinal, subiconsXFinal);
|
_subiconState.x = anim::value(subiconsXFinal, subiconsXFinal);
|
||||||
_subiconsAnimation.stop();
|
_subiconState.animation.stop();
|
||||||
} else {
|
} else {
|
||||||
_subiconState.x.start(subiconsXFinal);
|
_subiconState.x.start(subiconsXFinal);
|
||||||
_subiconState.animationStart = crl::now();
|
_subiconState.animationStart = crl::now();
|
||||||
_subiconsAnimation.start();
|
_subiconState.animation.start();
|
||||||
}
|
}
|
||||||
updateSelected();
|
updateSelected();
|
||||||
update();
|
update();
|
||||||
|
@ -479,12 +506,12 @@ void StickersListFooter::setSelectedSubicon(
|
||||||
|
|
||||||
void StickersListFooter::processHideFinished() {
|
void StickersListFooter::processHideFinished() {
|
||||||
_selected = _pressed = SpecialOver::None;
|
_selected = _pressed = SpecialOver::None;
|
||||||
_iconsAnimation.stop();
|
_iconState.animation.stop();
|
||||||
_iconState.animationStart = 0;
|
_iconState.animationStart = 0;
|
||||||
_iconState.x.finish();
|
_iconState.x.finish();
|
||||||
_iconState.selectionX.finish();
|
_iconState.selectionX.finish();
|
||||||
_iconState.selectionWidth.finish();
|
_iconState.selectionWidth.finish();
|
||||||
_subiconsAnimation.stop();
|
_subiconState.animation.stop();
|
||||||
_subiconState.animationStart = 0;
|
_subiconState.animationStart = 0;
|
||||||
_subiconState.x.finish();
|
_subiconState.x.finish();
|
||||||
_subiconState.selectionX.finish();
|
_subiconState.selectionX.finish();
|
||||||
|
@ -668,13 +695,11 @@ void StickersListFooter::mouseMoveEvent(QMouseEvent *e) {
|
||||||
: _iconState).dragging = true;
|
: _iconState).dragging = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
checkDragging(_iconState, _iconsAnimation);
|
checkDragging(_iconState);
|
||||||
checkDragging(_subiconState, _subiconsAnimation);
|
checkDragging(_subiconState);
|
||||||
}
|
}
|
||||||
|
|
||||||
void StickersListFooter::checkDragging(
|
void StickersListFooter::checkDragging(ScrollState &state) {
|
||||||
ScrollState &state,
|
|
||||||
Ui::Animations::Basic &animation) {
|
|
||||||
if (state.dragging) {
|
if (state.dragging) {
|
||||||
const auto newX = std::clamp(
|
const auto newX = std::clamp(
|
||||||
(rtl() ? -1 : 1) * (_iconsMouseDown.x() - _iconsMousePos.x())
|
(rtl() ? -1 : 1) * (_iconsMouseDown.x() - _iconsMousePos.x())
|
||||||
|
@ -684,7 +709,7 @@ void StickersListFooter::checkDragging(
|
||||||
if (newX != qRound(state.x.current())) {
|
if (newX != qRound(state.x.current())) {
|
||||||
state.x = anim::value(newX, newX);
|
state.x = anim::value(newX, newX);
|
||||||
state.animationStart = 0;
|
state.animationStart = 0;
|
||||||
animation.stop();
|
state.animation.stop();
|
||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -705,13 +730,18 @@ void StickersListFooter::mouseReleaseEvent(QMouseEvent *e) {
|
||||||
updateSelected();
|
updateSelected();
|
||||||
if (wasDown == _selected) {
|
if (wasDown == _selected) {
|
||||||
if (const auto icon = std::get_if<IconId>(&_selected)) {
|
if (const auto icon = std::get_if<IconId>(&_selected)) {
|
||||||
|
const auto shift = int(base::SafeRound(_iconState.x.current()));
|
||||||
const auto info = iconInfo(icon->index);
|
const auto info = iconInfo(icon->index);
|
||||||
_iconState.selectionX = anim::value(info.left, info.left);
|
_iconState.selectionX = anim::value(
|
||||||
|
shift + info.left,
|
||||||
|
shift + info.left);
|
||||||
_iconState.selectionWidth = anim::value(info.width, info.width);
|
_iconState.selectionWidth = anim::value(info.width, info.width);
|
||||||
|
const auto subshift = int(base::SafeRound(
|
||||||
|
_subiconState.x.current()));
|
||||||
const auto subinfo = subiconInfo(icon->subindex);
|
const auto subinfo = subiconInfo(icon->subindex);
|
||||||
_subiconState.selectionX = anim::value(
|
_subiconState.selectionX = anim::value(
|
||||||
subinfo.left,
|
subshift + subinfo.left,
|
||||||
subinfo.left);
|
subshift + subinfo.left);
|
||||||
_subiconState.selectionWidth = anim::value(
|
_subiconState.selectionWidth = anim::value(
|
||||||
subinfo.width,
|
subinfo.width,
|
||||||
subinfo.width);
|
subinfo.width);
|
||||||
|
@ -725,14 +755,12 @@ void StickersListFooter::mouseReleaseEvent(QMouseEvent *e) {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool StickersListFooter::finishDragging() {
|
bool StickersListFooter::finishDragging() {
|
||||||
const auto icon = finishDragging(_iconState, _iconsAnimation);
|
const auto icon = finishDragging(_iconState);
|
||||||
const auto subicon = finishDragging(_subiconState, _subiconsAnimation);
|
const auto subicon = finishDragging(_subiconState);
|
||||||
return icon || subicon;
|
return icon || subicon;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool StickersListFooter::finishDragging(
|
bool StickersListFooter::finishDragging(ScrollState &state) {
|
||||||
ScrollState &state,
|
|
||||||
Ui::Animations::Basic &animation) {
|
|
||||||
if (!state.dragging) {
|
if (!state.dragging) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -743,7 +771,7 @@ bool StickersListFooter::finishDragging(
|
||||||
if (newX != qRound(state.x.current())) {
|
if (newX != qRound(state.x.current())) {
|
||||||
state.x = anim::value(newX, newX);
|
state.x = anim::value(newX, newX);
|
||||||
state.animationStart = 0;
|
state.animationStart = 0;
|
||||||
animation.stop();
|
state.animation.stop();
|
||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
state.dragging = false;
|
state.dragging = false;
|
||||||
|
@ -767,32 +795,37 @@ void StickersListFooter::scrollByWheelEvent(
|
||||||
not_null<QWheelEvent*> e) {
|
not_null<QWheelEvent*> e) {
|
||||||
auto horizontal = (e->angleDelta().x() != 0);
|
auto horizontal = (e->angleDelta().x() != 0);
|
||||||
auto vertical = (e->angleDelta().y() != 0);
|
auto vertical = (e->angleDelta().y() != 0);
|
||||||
|
if (!horizontal && !vertical) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (horizontal) {
|
if (horizontal) {
|
||||||
_horizontal = true;
|
_horizontal = true;
|
||||||
}
|
}
|
||||||
auto newX = qRound(_iconState.x.current());
|
auto delta = horizontal
|
||||||
if (/*_horizontal && */horizontal) {
|
? ((rtl() ? -1 : 1) * (e->pixelDelta().x()
|
||||||
newX = std::clamp(
|
? e->pixelDelta().x()
|
||||||
newX - (rtl() ? -1 : 1) * (e->pixelDelta().x()
|
: e->angleDelta().x()))
|
||||||
? e->pixelDelta().x()
|
: (e->pixelDelta().y()
|
||||||
: e->angleDelta().x()),
|
? e->pixelDelta().y()
|
||||||
0,
|
: e->angleDelta().y());
|
||||||
_iconState.max);
|
const auto use = [&](ScrollState &state) {
|
||||||
} else if (/*!_horizontal && */vertical) {
|
const auto now = qRound(state.x.current());
|
||||||
newX = std::clamp(
|
const auto used = now - delta;
|
||||||
newX - (e->pixelDelta().y()
|
const auto next = std::clamp(used, 0, state.max);
|
||||||
? e->pixelDelta().y()
|
delta = next - used;
|
||||||
: e->angleDelta().y()),
|
if (next != now) {
|
||||||
0,
|
state.x = anim::value(next, next);
|
||||||
_iconState.max);
|
state.animationStart = 0;
|
||||||
}
|
state.animation.stop();
|
||||||
if (newX != qRound(_iconState.x.current())) {
|
updateSelected();
|
||||||
_iconState.x = anim::value(newX, newX);
|
update();
|
||||||
_iconState.animationStart = 0;
|
}
|
||||||
_iconsAnimation.stop();
|
};
|
||||||
updateSelected();
|
const auto index = v::get<IconId>(_selected).index;
|
||||||
update();
|
if (_icons[index].setId == AllEmojiSectionSetId()) {
|
||||||
|
use(_subiconState);
|
||||||
}
|
}
|
||||||
|
use(_iconState);
|
||||||
}
|
}
|
||||||
|
|
||||||
void StickersListFooter::clipCallback(
|
void StickersListFooter::clipCallback(
|
||||||
|
@ -856,7 +889,6 @@ void StickersListFooter::updateSelected() {
|
||||||
&& y < _iconsTop + st::emojiFooterHeight
|
&& y < _iconsTop + st::emojiFooterHeight
|
||||||
&& x >= _iconsLeft
|
&& x >= _iconsLeft
|
||||||
&& x < width() - _iconsRight) {
|
&& x < width() - _iconsRight) {
|
||||||
x += qRound(_iconState.x.current());
|
|
||||||
enumerateIcons([&](const IconInfo &info) {
|
enumerateIcons([&](const IconInfo &info) {
|
||||||
if (x >= info.left && x < info.left + info.width) {
|
if (x >= info.left && x < info.left + info.width) {
|
||||||
newOver = IconId{ .index = info.index };
|
newOver = IconId{ .index = info.index };
|
||||||
|
@ -927,14 +959,7 @@ void StickersListFooter::refreshIcons(
|
||||||
refreshIconsGeometry(animations);
|
refreshIconsGeometry(animations);
|
||||||
}
|
}
|
||||||
|
|
||||||
void StickersListFooter::refreshIconsGeometry(
|
void StickersListFooter::refreshScrollableDimensions() {
|
||||||
ValidateIconAnimations animations) {
|
|
||||||
_selected = _pressed = SpecialOver::None;
|
|
||||||
_iconState.x.finish();
|
|
||||||
_iconState.selectionX.finish();
|
|
||||||
_iconState.selectionWidth.finish();
|
|
||||||
_iconState.animationStart = 0;
|
|
||||||
_iconsAnimation.stop();
|
|
||||||
const auto &last = iconInfo(_icons.size() - 1);
|
const auto &last = iconInfo(_icons.size() - 1);
|
||||||
_iconState.max = std::max(
|
_iconState.max = std::max(
|
||||||
last.left + last.width + _iconsRight - width(),
|
last.left + last.width + _iconsRight - width(),
|
||||||
|
@ -942,9 +967,19 @@ void StickersListFooter::refreshIconsGeometry(
|
||||||
if (_iconState.x.current() > _iconState.max) {
|
if (_iconState.x.current() > _iconState.max) {
|
||||||
_iconState.x = anim::value(_iconState.max, _iconState.max);
|
_iconState.x = anim::value(_iconState.max, _iconState.max);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void StickersListFooter::refreshIconsGeometry(
|
||||||
|
ValidateIconAnimations animations) {
|
||||||
|
_selected = _pressed = SpecialOver::None;
|
||||||
|
_iconState.x.finish();
|
||||||
|
_iconState.selectionX.finish();
|
||||||
|
_iconState.selectionWidth.finish();
|
||||||
|
_iconState.animationStart = 0;
|
||||||
|
_iconState.animation.stop();
|
||||||
|
refreshScrollableDimensions();
|
||||||
updateSelected();
|
updateSelected();
|
||||||
validateSelectedIcon(_activeByScrollId, animations);
|
validateSelectedIcon(_activeByScrollId, animations);
|
||||||
refreshSubiconsGeometry();
|
|
||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -954,7 +989,7 @@ void StickersListFooter::refreshSubiconsGeometry() {
|
||||||
_subiconState.selectionX.finish();
|
_subiconState.selectionX.finish();
|
||||||
_subiconState.selectionWidth.finish();
|
_subiconState.selectionWidth.finish();
|
||||||
_subiconState.animationStart = 0;
|
_subiconState.animationStart = 0;
|
||||||
_subiconsAnimation.stop();
|
_subiconState.animation.stop();
|
||||||
const auto single = st::stickerIconWidth;
|
const auto single = st::stickerIconWidth;
|
||||||
const auto half = single / 2;
|
const auto half = single / 2;
|
||||||
const auto count = int(Section::Symbols) - int(Section::Recent);
|
const auto count = int(Section::Symbols) - int(Section::Recent);
|
||||||
|
@ -975,6 +1010,7 @@ void StickersListFooter::refreshSubiconsGeometry() {
|
||||||
if (_subiconState.x.current() > _subiconState.max) {
|
if (_subiconState.x.current() > _subiconState.max) {
|
||||||
_subiconState.x = anim::value(_subiconState.max, _subiconState.max);
|
_subiconState.x = anim::value(_subiconState.max, _subiconState.max);
|
||||||
}
|
}
|
||||||
|
updateEmojiWidthCallback();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool StickersListFooter::hasOnlyFeaturedSets() const {
|
bool StickersListFooter::hasOnlyFeaturedSets() const {
|
||||||
|
@ -1220,30 +1256,4 @@ void StickersListFooter::paintSetIcon(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool StickersListFooter::iconsAnimationCallback(
|
|
||||||
ScrollState &state,
|
|
||||||
crl::time now) {
|
|
||||||
if (anim::Disabled()) {
|
|
||||||
now += st::stickerIconMove;
|
|
||||||
}
|
|
||||||
if (state.animationStart) {
|
|
||||||
const auto dt = (now - state.animationStart)
|
|
||||||
/ float64(st::stickerIconMove);
|
|
||||||
if (dt >= 1.) {
|
|
||||||
state.animationStart = 0;
|
|
||||||
state.x.finish();
|
|
||||||
state.selectionX.finish();
|
|
||||||
state.selectionWidth.finish();
|
|
||||||
} else {
|
|
||||||
state.x.update(dt, anim::linear);
|
|
||||||
state.selectionX.update(dt, anim::linear);
|
|
||||||
state.selectionWidth.update(dt, anim::linear);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
update();
|
|
||||||
|
|
||||||
return (state.animationStart != 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace ChatHelpers
|
} // namespace ChatHelpers
|
||||||
|
|
|
@ -143,6 +143,11 @@ private:
|
||||||
bool visible = false;
|
bool visible = false;
|
||||||
};
|
};
|
||||||
struct ScrollState {
|
struct ScrollState {
|
||||||
|
template <typename UpdateCallback>
|
||||||
|
explicit ScrollState(UpdateCallback &&callback);
|
||||||
|
|
||||||
|
bool animationCallback(crl::time now);
|
||||||
|
|
||||||
int selected = 0;
|
int selected = 0;
|
||||||
int max = 0;
|
int max = 0;
|
||||||
int draggingStartX = 0;
|
int draggingStartX = 0;
|
||||||
|
@ -151,6 +156,7 @@ private:
|
||||||
anim::value selectionX;
|
anim::value selectionX;
|
||||||
anim::value selectionWidth;
|
anim::value selectionWidth;
|
||||||
crl::time animationStart = 0;
|
crl::time animationStart = 0;
|
||||||
|
Ui::Animations::Basic animation;
|
||||||
};
|
};
|
||||||
|
|
||||||
void enumerateVisibleIcons(Fn<void(const IconInfo &)> callback) const;
|
void enumerateVisibleIcons(Fn<void(const IconInfo &)> callback) const;
|
||||||
|
@ -160,7 +166,6 @@ private:
|
||||||
[[nodiscard]] IconInfo subiconInfo(int index) const;
|
[[nodiscard]] IconInfo subiconInfo(int index) const;
|
||||||
|
|
||||||
[[nodiscard]] std::shared_ptr<Lottie::FrameRenderer> getLottieRenderer();
|
[[nodiscard]] std::shared_ptr<Lottie::FrameRenderer> getLottieRenderer();
|
||||||
bool iconsAnimationCallback(ScrollState &state, crl::time now);
|
|
||||||
void setSelectedIcon(
|
void setSelectedIcon(
|
||||||
int newSelected,
|
int newSelected,
|
||||||
ValidateIconAnimations animations);
|
ValidateIconAnimations animations);
|
||||||
|
@ -173,13 +178,12 @@ private:
|
||||||
|
|
||||||
void refreshIconsGeometry(ValidateIconAnimations animations);
|
void refreshIconsGeometry(ValidateIconAnimations animations);
|
||||||
void refreshSubiconsGeometry();
|
void refreshSubiconsGeometry();
|
||||||
|
void refreshScrollableDimensions();
|
||||||
void updateSelected();
|
void updateSelected();
|
||||||
void updateSetIcon(uint64 setId);
|
void updateSetIcon(uint64 setId);
|
||||||
void updateSetIconAt(int left);
|
void updateSetIconAt(int left);
|
||||||
void checkDragging(ScrollState &state, Ui::Animations::Basic &animation);
|
void checkDragging(ScrollState &state);
|
||||||
bool finishDragging(
|
bool finishDragging(ScrollState &state);
|
||||||
ScrollState &state,
|
|
||||||
Ui::Animations::Basic &animation);
|
|
||||||
bool finishDragging();
|
bool finishDragging();
|
||||||
void paintStickerSettingsIcon(Painter &p) const;
|
void paintStickerSettingsIcon(Painter &p) const;
|
||||||
void paintSearchIcon(Painter &p) const;
|
void paintSearchIcon(Painter &p) const;
|
||||||
|
@ -223,10 +227,7 @@ private:
|
||||||
int _iconsTop = 0;
|
int _iconsTop = 0;
|
||||||
|
|
||||||
ScrollState _iconState;
|
ScrollState _iconState;
|
||||||
Ui::Animations::Basic _iconsAnimation;
|
|
||||||
|
|
||||||
ScrollState _subiconState;
|
ScrollState _subiconState;
|
||||||
Ui::Animations::Basic _subiconsAnimation;
|
|
||||||
|
|
||||||
Ui::RoundRect _selectionBg;
|
Ui::RoundRect _selectionBg;
|
||||||
Ui::Animations::Simple _subiconsWidthAnimation;
|
Ui::Animations::Simple _subiconsWidthAnimation;
|
||||||
|
|
Loading…
Add table
Reference in a new issue