Fixed PanelAnimation for Retina, added 1px padding to emoji.

This commit is contained in:
John Preston 2016-11-11 11:59:55 +03:00
parent bd2be4e0c1
commit 55b1ba128d
9 changed files with 55 additions and 77 deletions

View File

@ -30,7 +30,7 @@ semiboldFont: font(fsize semibold);
emojiImgSize: 18px; // exceptional value for retina
emojiSize: 18px;
emojiPadding: 0px;
emojiPadding: 1px;
lineWidth: 1px;

View File

@ -4219,7 +4219,6 @@ void HistoryWidget::showHistory(const PeerId &peerId, MsgId showAtMsgId, bool re
if (_list) _list->deleteLater();
_list = nullptr;
_scroll.takeWidget();
updateTopBarSelection();
clearInlineBot();
@ -4229,6 +4228,9 @@ void HistoryWidget::showHistory(const PeerId &peerId, MsgId showAtMsgId, bool re
_peer = peerId ? App::peer(peerId) : nullptr;
_channel = _peer ? peerToChannel(_peer->id) : NoChannel;
_canSendMessages = canSendMessages(_peer);
updateTopBarSelection();
if (_peer && _peer->isChannel()) {
_peer->asChannel()->updateFull();
_joinChannel->setText(lang(_peer->isMegagroup() ? lng_group_invite_join : lng_channel_join).toUpper());

View File

@ -30,6 +30,13 @@ void PanelAnimation::setFinalImage(QImage &&finalImage, QRect inner) {
t_assert(!_finalImage.isNull());
_finalWidth = _finalImage.width();
_finalHeight = _finalImage.height();
_finalInnerLeft = inner.x();
_finalInnerTop = inner.y();
_finalInnerWidth = inner.width();
_finalInnerHeight = inner.height();
_finalInnerRight = _finalInnerLeft + _finalInnerWidth;
_finalInnerBottom = _finalInnerTop + _finalInnerHeight;
t_assert(QRect(0, 0, _finalWidth, _finalHeight).contains(inner));
setStartWidth();
setStartHeight();
@ -59,20 +66,12 @@ void PanelAnimation::setFinalImage(QImage &&finalImage, QRect inner) {
t_assert(_finalImage.depth() == static_cast<int>(sizeof(uint32) << 3));
t_assert(_finalImage.bytesPerLine() == (_finalIntsPerLine << 2));
t_assert(_finalIntsPerLineAdded >= 0);
_finalInnerLeft = inner.x();
_finalInnerTop = inner.y();
_finalInnerWidth = inner.width();
_finalInnerHeight = inner.height();
_finalInnerRight = _finalInnerLeft + _finalInnerWidth;
_finalInnerBottom = _finalInnerTop + _finalInnerHeight;
t_assert(QRect(0, 0, _finalWidth, _finalHeight).contains(inner));
}
void PanelAnimation::setShadow() {
if (_skipShadow) return;
_shadow.extend = _st.shadow.extend;
_shadow.extend = _st.shadow.extend * cIntRetinaFactor();
_shadow.left = cloneImage(_st.shadow.left);
if (_shadow.valid()) {
_shadow.topLeft = cloneImage(_st.shadow.topLeft);
@ -101,13 +100,13 @@ void PanelAnimation::setShadow() {
}
void PanelAnimation::setStartWidth() {
_startWidth = qRound(_st.startWidth * _finalImage.width());
if (_startWidth >= 0) t_assert(_startWidth <= _finalWidth);
_startWidth = qRound(_st.startWidth * _finalInnerWidth);
if (_startWidth >= 0) t_assert(_startWidth <= _finalInnerWidth);
}
void PanelAnimation::setStartHeight() {
_startHeight = qRound(_st.startHeight * _finalImage.height());
if (_startHeight >= 0) t_assert(_startHeight <= _finalHeight);
_startHeight = qRound(_st.startHeight * _finalInnerHeight);
if (_startHeight >= 0) t_assert(_startHeight <= _finalInnerHeight);
}
void PanelAnimation::setStartAlpha() {
@ -116,7 +115,7 @@ void PanelAnimation::setStartAlpha() {
}
void PanelAnimation::setStartFadeTop() {
_startFadeTop = qRound(_st.startFadeTop * _finalImage.height());
_startFadeTop = qRound(_st.startFadeTop * _finalInnerHeight);
}
void PanelAnimation::createFadeMask() {
@ -177,7 +176,8 @@ void PanelAnimation::setCornerMask(Corner &corner, QImage &&image) {
QImage PanelAnimation::cloneImage(const style::icon &source) {
if (source.empty()) return QImage();
auto result = QImage(source.width(), source.height(), QImage::Format_ARGB32_Premultiplied);
auto result = QImage(source.size() * cIntRetinaFactor(), QImage::Format_ARGB32_Premultiplied);
result.setDevicePixelRatio(cRetinaFactor());
result.fill(Qt::transparent);
{
Painter p(&result);

View File

@ -237,7 +237,8 @@ void InnerDropdown::startShowAnimation() {
_a_opacity = base::take(opacityAnimation);
_showAnimation = std_::make_unique<PanelAnimation>(_st.animation, _origin);
_showAnimation->setFinalImage(std_::move(cache), rect().marginsRemoved(_st.padding));
auto inner = rect().marginsRemoved(_st.padding);
_showAnimation->setFinalImage(std_::move(cache), QRect(inner.topLeft() * cIntRetinaFactor(), inner.size() * cIntRetinaFactor()));
auto corners = App::cornersMask(ImageRoundRadius::Small);
_showAnimation->setCornerMasks(QImage(*corners[0]), QImage(*corners[1]), QImage(*corners[2]), QImage(*corners[3]));
_showAnimation->start();

View File

@ -68,7 +68,7 @@ void PopupMenu::init() {
}
void PopupMenu::handleCompositingUpdate() {
_padding = _useTransaprency ? _st.shadow.extend : style::margins(st::lineWidth, st::lineWidth, st::lineWidth, st::lineWidth);
_padding = _useTransparency ? _st.shadow.extend : style::margins(st::lineWidth, st::lineWidth, st::lineWidth, st::lineWidth);
_menu->moveToLeft(_padding.left() + _st.scrollPadding.left(), _padding.top() + _st.scrollPadding.top());
handleMenuResize();
}
@ -126,7 +126,7 @@ void PopupMenu::paintEvent(QPaintEvent *e) {
}
void PopupMenu::paintBg(Painter &p) {
if (_useTransaprency) {
if (_useTransparency) {
Shadow::paint(p, _inner, width(), _st.shadow);
App::roundRect(p, _inner, _st.menu.itemBg, ImageRoundRadius::Small);
} else {
@ -307,7 +307,7 @@ void PopupMenu::prepareCache() {
void PopupMenu::startOpacityAnimation(bool hiding) {
_hiding = false;
if (!_useTransaprency) {
if (!_useTransparency) {
_a_opacity.finish();
if (hiding) {
hideFinished();
@ -334,7 +334,7 @@ void PopupMenu::showStarted() {
}
void PopupMenu::startShowAnimation() {
if (!_useTransaprency) {
if (!_useTransparency) {
_a_show.finish();
update();
return;
@ -346,8 +346,8 @@ void PopupMenu::startShowAnimation() {
_a_opacity = base::take(opacityAnimation);
_showAnimation = std_::make_unique<PanelAnimation>(_st.animation, _origin);
_showAnimation->setFinalImage(std_::move(cache), _inner);
if (_useTransaprency) {
_showAnimation->setFinalImage(std_::move(cache), QRect(_inner.topLeft() * cIntRetinaFactor(), _inner.size() * cIntRetinaFactor()));
if (_useTransparency) {
auto corners = App::cornersMask(ImageRoundRadius::Small);
_showAnimation->setCornerMasks(QImage(*corners[0]), QImage(*corners[1]), QImage(*corners[2]), QImage(*corners[3]));
} else {
@ -382,7 +382,7 @@ QImage PopupMenu::grabForPanelAnimation() {
result.fill(Qt::transparent);
{
Painter p(&result);
if (_useTransaprency) {
if (_useTransparency) {
App::roundRect(p, _inner, _st.menu.itemBg, ImageRoundRadius::Small);
} else {
p.fillRect(_inner, _st.menu.itemBg);
@ -410,7 +410,7 @@ void PopupMenu::showMenu(const QPoint &p, PopupMenu *parent, TriggeredSource sou
auto origin = PanelAnimation::Origin::TopLeft;
auto w = p - QPoint(0, _padding.top());
auto r = Sandbox::screenGeometry(p);
_useTransaprency = Platform::TransparentWindowsSupported(p);
_useTransparency = Platform::TransparentWindowsSupported(p);
handleCompositingUpdate();
if (rtl()) {
if (w.x() - width() < r.x() - _padding.left()) {

View File

@ -117,7 +117,7 @@ private:
std_::unique_ptr<PanelAnimation> _showAnimation;
FloatAnimation _a_show;
bool _useTransaprency = true;
bool _useTransparency = true;
bool _hiding = false;
QPixmap _cache;
FloatAnimation _a_opacity;

View File

@ -23,23 +23,21 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
namespace Window {
SlideAnimation::SlideAnimation()
: _animation(animation(this, &SlideAnimation::step)) {
}
void SlideAnimation::paintContents(Painter &p, const QRect &update) const {
int retina = cIntRetinaFactor();
_animation.step(getms());
if (a_coordOver.current() > 0) {
p.drawPixmap(QRect(0, 0, a_coordOver.current(), _cacheUnder.height() / retina), _cacheUnder, QRect(-a_coordUnder.current() * retina, 0, a_coordOver.current() * retina, _cacheUnder.height()));
p.setOpacity(a_progress.current());
p.fillRect(0, 0, a_coordOver.current(), _cacheUnder.height() / retina, st::slideFadeOutBg);
auto progress = _animation.current(getms());
auto coordUnder = anim::interpolate(0, -st::slideShift, progress);
auto coordOver = anim::interpolate(_cacheOver.width() / cIntRetinaFactor(), 0, progress);
if (coordOver) {
p.drawPixmap(QRect(0, 0, coordOver, _cacheUnder.height() / retina), _cacheUnder, QRect(-coordUnder * retina, 0, coordOver * retina, _cacheUnder.height()));
p.setOpacity(progress);
p.fillRect(0, 0, coordOver, _cacheUnder.height() / retina, st::slideFadeOutBg);
p.setOpacity(1);
}
p.drawPixmap(QRect(a_coordOver.current(), 0, _cacheOver.width() / retina, _cacheOver.height() / retina), _cacheOver, QRect(0, 0, _cacheOver.width(), _cacheOver.height()));
p.setOpacity(a_progress.current());
st::slideShadow.fill(p, QRect(a_coordOver.current() - st::slideShadow.width(), 0, st::slideShadow.width(), _cacheOver.height() / retina));
p.drawPixmap(QRect(coordOver, 0, _cacheOver.width() / retina, _cacheOver.height() / retina), _cacheOver, QRect(0, 0, _cacheOver.width(), _cacheOver.height()));
p.setOpacity(progress);
st::slideShadow.fill(p, QRect(coordOver - st::slideShadow.width(), 0, st::slideShadow.width(), _cacheOver.height() / retina));
if (_topBarShadowEnabled) {
p.setOpacity(1);
@ -69,42 +67,20 @@ void SlideAnimation::setFinishedCallback(FinishedCallback &&callback) {
}
void SlideAnimation::start() {
int delta = st::slideShift;
if (_direction == SlideDirection::FromLeft) {
a_progress = anim::fvalue(1, 0);
std::swap(_cacheUnder, _cacheOver);
a_coordUnder = anim::ivalue(-delta, 0);
a_coordOver = anim::ivalue(0, _cacheOver.width() / cIntRetinaFactor());
} else {
a_progress = anim::fvalue(0, 1);
a_coordUnder = anim::ivalue(0, -delta);
a_coordOver = anim::ivalue(_cacheOver.width() / cIntRetinaFactor(), 0);
}
_animation.start();
auto delta = st::slideShift;
auto fromLeft = (_direction == SlideDirection::FromLeft);
if (fromLeft) std::swap(_cacheUnder, _cacheOver);
_animation.start([this] { animationCallback(); }, fromLeft ? 1. : 0., fromLeft ? 0. : 1., st::slideDuration, transition());
_repaintCallback();
}
void SlideAnimation::step(float64 ms, bool timer) {
float64 dt = ms / st::slideDuration;
if (dt >= 1) {
dt = 1;
if (timer) {
_animation.stop();
a_coordUnder.finish();
a_coordOver.finish();
if (_finishedCallback) {
_finishedCallback();
}
return;
void SlideAnimation::animationCallback() {
_repaintCallback();
if (!_animation.animating()) {
if (_finishedCallback) {
_finishedCallback();
}
}
a_coordUnder.update(dt, transition());
a_coordOver.update(dt, transition());
a_progress.update(dt, transition());
if (timer && _repaintCallback) {
_repaintCallback();
}
}
} // namespace Window

View File

@ -29,8 +29,6 @@ enum class SlideDirection {
class SlideAnimation {
public:
SlideAnimation();
void paintContents(Painter &p, const QRect &update) const;
void setDirection(SlideDirection direction);
@ -50,15 +48,13 @@ public:
}
private:
void step(float64 ms, bool timer);
void animationCallback();
SlideDirection _direction = SlideDirection::FromRight;
bool _topBarShadowEnabled = false;
mutable Animation _animation;
mutable FloatAnimation _animation;
QPixmap _cacheUnder, _cacheOver;
anim::ivalue a_coordUnder, a_coordOver;
anim::fvalue a_progress;
RepaintCallback _repaintCallback;
FinishedCallback _finishedCallback;

View File

@ -239,6 +239,7 @@ void TopBarWidget::startAnim() {
_mediaType->hide();
_search->hide();
_menuToggle->hide();
_menu.destroy();
if (_membersShowArea) {
_membersShowArea->hide();
}
@ -282,6 +283,7 @@ void TopBarWidget::showAll() {
_info->setPeer(h);
_info->show();
_menuToggle->hide();
_menu.destroy();
} else {
_info->hide();
_menuToggle->show();
@ -291,6 +293,7 @@ void TopBarWidget::showAll() {
_search->hide();
_info->hide();
_menuToggle->hide();
_menu.destroy();
}
if (_membersShowArea) {
_membersShowArea->show();