mirror of
https://github.com/telegramdesktop/tdesktop
synced 2025-03-22 19:34:27 +00:00
added stickers preview
This commit is contained in:
parent
6b565acbd6
commit
e312adb786
@ -1940,6 +1940,9 @@ stickerIconSelColor: #58b2ed;
|
||||
stickerIconLeft: sprite(342px, 72px, 40px, 1px);
|
||||
stickerIconRight: sprite(342px, 73px, 40px, 1px);
|
||||
stickerIconMove: 400;
|
||||
stickerPreviewDuration: 150;
|
||||
stickerPreviewBg: #FFFFFFB0;
|
||||
stickerPreviewMin: 0.1;
|
||||
|
||||
verifiedCheckProfile: sprite(285px, 235px, 18px, 18px);
|
||||
verifiedCheckProfilePos: point(7px, 6px);
|
||||
|
@ -2805,79 +2805,4 @@ namespace App {
|
||||
|
||||
WallPapers gServerBackgrounds;
|
||||
|
||||
void sendBotCommand(const QString &cmd, MsgId replyTo) {
|
||||
if (MainWidget *m = main()) m->sendBotCommand(cmd, replyTo);
|
||||
}
|
||||
|
||||
void insertBotCommand(const QString &cmd) {
|
||||
if (MainWidget *m = main()) m->insertBotCommand(cmd);
|
||||
}
|
||||
|
||||
void searchByHashtag(const QString &tag, PeerData *inPeer) {
|
||||
if (MainWidget *m = main()) m->searchMessages(tag + ' ', (inPeer && inPeer->isChannel()) ? inPeer : 0);
|
||||
}
|
||||
|
||||
void openPeerByName(const QString &username, bool toProfile, const QString &startToken) {
|
||||
if (MainWidget *m = main()) m->openPeerByName(username, toProfile, startToken);
|
||||
}
|
||||
|
||||
void joinGroupByHash(const QString &hash) {
|
||||
if (MainWidget *m = main()) m->joinGroupByHash(hash);
|
||||
}
|
||||
|
||||
void stickersBox(const QString &name) {
|
||||
if (MainWidget *m = main()) m->stickersBox(MTP_inputStickerSetShortName(MTP_string(name)));
|
||||
}
|
||||
|
||||
void openLocalUrl(const QString &url) {
|
||||
if (MainWidget *m = main()) m->openLocalUrl(url);
|
||||
}
|
||||
|
||||
bool forward(const PeerId &peer, ForwardWhatMessages what) {
|
||||
if (MainWidget *m = main()) return m->onForward(peer, what);
|
||||
return false;
|
||||
}
|
||||
|
||||
void removeDialog(History *history) {
|
||||
if (MainWidget *m = main()) m->removeDialog(history);
|
||||
}
|
||||
|
||||
void showSettings() {
|
||||
if (Window *win = wnd()) win->showSettings();
|
||||
}
|
||||
|
||||
void showLayer(LayeredWidget *w, bool forceFast) {
|
||||
if (Window *win = wnd()) win->showLayer(w, forceFast);
|
||||
}
|
||||
|
||||
void replaceLayer(LayeredWidget *w) {
|
||||
if (Window *win = wnd()) win->replaceLayer(w);
|
||||
}
|
||||
|
||||
void showLayerLast(LayeredWidget *w) {
|
||||
if (Window *win = wnd()) win->showLayerLast(w);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
namespace Notify {
|
||||
|
||||
void userIsBotChanged(UserData *user) {
|
||||
if (MainWidget *m = App::main()) {
|
||||
m->notifyUserIsBotChanged(user);
|
||||
}
|
||||
}
|
||||
|
||||
void botCommandsChanged(UserData *user) {
|
||||
if (MainWidget *m = App::main()) {
|
||||
m->notifyBotCommandsChanged(user);
|
||||
}
|
||||
}
|
||||
|
||||
void migrateUpdated(PeerData *peer) {
|
||||
if (MainWidget *m = App::main()) {
|
||||
m->notifyMigrateUpdated(peer);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -80,13 +80,6 @@ enum RoundCorners {
|
||||
RoundCornersCount
|
||||
};
|
||||
|
||||
enum ForwardWhatMessages {
|
||||
ForwardSelectedMessages,
|
||||
ForwardContextMessage,
|
||||
ForwardPressedMessage,
|
||||
ForwardPressedLinkMessage
|
||||
};
|
||||
|
||||
class LayeredWidget;
|
||||
|
||||
namespace App {
|
||||
@ -233,7 +226,7 @@ namespace App {
|
||||
bool quiting();
|
||||
void setQuiting();
|
||||
|
||||
QImage readImage(QByteArray data, QByteArray *format = 0, bool opaque = true, bool *animated = 0);
|
||||
QImage readImage(QByteArray data, QByteArray *format = 0, bool opaque = true, bool *animated = 0);
|
||||
QImage readImage(const QString &file, QByteArray *format = 0, bool opaque = true, bool *animated = 0, QByteArray *content = 0);
|
||||
|
||||
void regVideoItem(VideoData *data, HistoryItem *item);
|
||||
@ -300,28 +293,6 @@ namespace App {
|
||||
typedef QList<WallPaper> WallPapers;
|
||||
DeclareSetting(WallPapers, ServerBackgrounds);
|
||||
|
||||
void sendBotCommand(const QString &cmd, MsgId replyTo = 0);
|
||||
void insertBotCommand(const QString &cmd);
|
||||
void searchByHashtag(const QString &tag, PeerData *inPeer);
|
||||
void openPeerByName(const QString &username, bool toProfile = false, const QString &startToken = QString());
|
||||
void joinGroupByHash(const QString &hash);
|
||||
void stickersBox(const QString &name);
|
||||
void openLocalUrl(const QString &url);
|
||||
bool forward(const PeerId &peer, ForwardWhatMessages what);
|
||||
void removeDialog(History *history);
|
||||
void showSettings();
|
||||
void showLayer(LayeredWidget *w, bool forceFast = false);
|
||||
void replaceLayer(LayeredWidget *w);
|
||||
void showLayerLast(LayeredWidget *w);
|
||||
|
||||
};
|
||||
|
||||
namespace Notify {
|
||||
|
||||
void userIsBotChanged(UserData *user);
|
||||
void botCommandsChanged(UserData *user);
|
||||
void migrateUpdated(PeerData *peer);
|
||||
|
||||
};
|
||||
|
||||
inline int32 stickersCountHash(bool checkOfficial = false) {
|
||||
@ -344,3 +315,5 @@ inline int32 stickersCountHash(bool checkOfficial = false) {
|
||||
}
|
||||
return (!checkOfficial || (!foundBad && foundOfficial)) ? int32(acc & 0x7FFFFFFF) : 0;
|
||||
}
|
||||
|
||||
#include "facades.h"
|
||||
|
@ -1200,7 +1200,8 @@ StickerPanInner::StickerPanInner() : TWidget()
|
||||
, _top(0)
|
||||
, _selected(-1)
|
||||
, _pressedSel(-1)
|
||||
, _settings(this, lang(lng_stickers_you_have)) {
|
||||
, _settings(this, lang(lng_stickers_you_have))
|
||||
, _previewShown(false) {
|
||||
setMaxHeight(st::emojiPanMaxHeight);
|
||||
|
||||
setMouseTracking(true);
|
||||
@ -1210,6 +1211,9 @@ StickerPanInner::StickerPanInner() : TWidget()
|
||||
connect(App::wnd(), SIGNAL(imageLoaded()), this, SLOT(update()));
|
||||
connect(&_settings, SIGNAL(clicked()), this, SLOT(onSettings()));
|
||||
|
||||
_previewTimer.setSingleShot(true);
|
||||
connect(&_previewTimer, SIGNAL(timeout()), this, SLOT(onPreview()));
|
||||
|
||||
refreshStickers();
|
||||
}
|
||||
|
||||
@ -1349,15 +1353,23 @@ void StickerPanInner::mousePressEvent(QMouseEvent *e) {
|
||||
updateSelected();
|
||||
|
||||
_pressedSel = _selected;
|
||||
_previewTimer.start(QApplication::startDragTime());
|
||||
}
|
||||
|
||||
void StickerPanInner::mouseReleaseEvent(QMouseEvent *e) {
|
||||
_previewTimer.stop();
|
||||
|
||||
int32 pressed = _pressedSel;
|
||||
_pressedSel = -1;
|
||||
|
||||
_lastMousePos = e->globalPos();
|
||||
updateSelected();
|
||||
|
||||
if (_previewShown) {
|
||||
_previewShown = false;
|
||||
return;
|
||||
}
|
||||
|
||||
if (_selected < 0 || _selected != pressed) return;
|
||||
if (_selected >= MatrixRowShift * _sets.size()) {
|
||||
return;
|
||||
@ -1638,7 +1650,7 @@ void StickerPanInner::refreshPanels(QVector<EmojiPanel*> &panels) {
|
||||
}
|
||||
|
||||
void StickerPanInner::updateSelected() {
|
||||
if (_pressedSel >= 0) return;
|
||||
if (_pressedSel >= 0 && !_previewShown) return;
|
||||
|
||||
int32 selIndex = -1;
|
||||
QPoint p(mapFromGlobal(_lastMousePos));
|
||||
@ -1715,6 +1727,12 @@ void StickerPanInner::updateSelected() {
|
||||
}
|
||||
}
|
||||
_selected = selIndex;
|
||||
if (_pressedSel >= 0 && _selected >= 0 && _pressedSel != _selected) {
|
||||
_pressedSel = _selected;
|
||||
if (newSel >= 0 && xNewSel < 0) {
|
||||
Ui::showStickerPreview(_sets.at(newSelTab).pack.at(newSel % MatrixRowShift));
|
||||
}
|
||||
}
|
||||
if (startanim) anim::start(this);
|
||||
}
|
||||
|
||||
@ -1722,6 +1740,16 @@ void StickerPanInner::onSettings() {
|
||||
App::showLayer(new StickersBox());
|
||||
}
|
||||
|
||||
void StickerPanInner::onPreview() {
|
||||
if (_pressedSel >= 0 && _pressedSel < MatrixRowShift * _sets.size()) {
|
||||
int tab = (_pressedSel / MatrixRowShift), sel = _pressedSel % MatrixRowShift;
|
||||
if (sel < _sets.at(tab).pack.size()) {
|
||||
Ui::showStickerPreview(_sets.at(tab).pack.at(sel));
|
||||
_previewShown = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool StickerPanInner::animStep(float64 ms) {
|
||||
uint64 now = getms();
|
||||
QRegion toUpdate;
|
||||
|
@ -349,6 +349,7 @@ public slots:
|
||||
|
||||
void updateSelected();
|
||||
void onSettings();
|
||||
void onPreview();
|
||||
|
||||
signals:
|
||||
|
||||
@ -394,6 +395,9 @@ private:
|
||||
QPoint _lastMousePos;
|
||||
|
||||
LinkButton _settings;
|
||||
|
||||
QTimer _previewTimer;
|
||||
bool _previewShown;
|
||||
};
|
||||
|
||||
class EmojiPanel : public TWidget {
|
||||
|
109
Telegram/SourceFiles/facades.cpp
Normal file
109
Telegram/SourceFiles/facades.cpp
Normal file
@ -0,0 +1,109 @@
|
||||
/*
|
||||
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 "window.h"
|
||||
#include "mainwidget.h"
|
||||
|
||||
namespace App {
|
||||
|
||||
void sendBotCommand(const QString &cmd, MsgId replyTo) {
|
||||
if (MainWidget *m = main()) m->sendBotCommand(cmd, replyTo);
|
||||
}
|
||||
|
||||
void insertBotCommand(const QString &cmd) {
|
||||
if (MainWidget *m = main()) m->insertBotCommand(cmd);
|
||||
}
|
||||
|
||||
void searchByHashtag(const QString &tag, PeerData *inPeer) {
|
||||
if (MainWidget *m = main()) m->searchMessages(tag + ' ', (inPeer && inPeer->isChannel()) ? inPeer : 0);
|
||||
}
|
||||
|
||||
void openPeerByName(const QString &username, bool toProfile, const QString &startToken) {
|
||||
if (MainWidget *m = main()) m->openPeerByName(username, toProfile, startToken);
|
||||
}
|
||||
|
||||
void joinGroupByHash(const QString &hash) {
|
||||
if (MainWidget *m = main()) m->joinGroupByHash(hash);
|
||||
}
|
||||
|
||||
void stickersBox(const QString &name) {
|
||||
if (MainWidget *m = main()) m->stickersBox(MTP_inputStickerSetShortName(MTP_string(name)));
|
||||
}
|
||||
|
||||
void openLocalUrl(const QString &url) {
|
||||
if (MainWidget *m = main()) m->openLocalUrl(url);
|
||||
}
|
||||
|
||||
bool forward(const PeerId &peer, ForwardWhatMessages what) {
|
||||
if (MainWidget *m = main()) return m->onForward(peer, what);
|
||||
return false;
|
||||
}
|
||||
|
||||
void removeDialog(History *history) {
|
||||
if (MainWidget *m = main()) m->removeDialog(history);
|
||||
}
|
||||
|
||||
void showSettings() {
|
||||
if (Window *win = wnd()) win->showSettings();
|
||||
}
|
||||
|
||||
void showLayer(LayeredWidget *widget, bool forceFast) {
|
||||
if (Window *w = wnd()) w->showLayer(widget, forceFast);
|
||||
}
|
||||
|
||||
void replaceLayer(LayeredWidget *widget) {
|
||||
if (Window *w = wnd()) w->replaceLayer(widget);
|
||||
}
|
||||
|
||||
void showLayerLast(LayeredWidget *widget) {
|
||||
if (Window *w = wnd()) w->showLayerLast(widget);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
namespace Ui {
|
||||
|
||||
void showStickerPreview(DocumentData *sticker) {
|
||||
if (MainWidget *m = App::main()) m->ui_showStickerPreview(sticker);
|
||||
}
|
||||
|
||||
void hideStickerPreview() {
|
||||
if (MainWidget *m = App::main()) m->ui_hideStickerPreview();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
namespace Notify {
|
||||
|
||||
void userIsBotChanged(UserData *user) {
|
||||
if (MainWidget *m = App::main()) m->notifyUserIsBotChanged(user);
|
||||
}
|
||||
|
||||
void botCommandsChanged(UserData *user) {
|
||||
if (MainWidget *m = App::main()) m->notifyBotCommandsChanged(user);
|
||||
}
|
||||
|
||||
void migrateUpdated(PeerData *peer) {
|
||||
if (MainWidget *m = App::main()) m->notifyMigrateUpdated(peer);
|
||||
}
|
||||
|
||||
}
|
56
Telegram/SourceFiles/facades.h
Normal file
56
Telegram/SourceFiles/facades.h
Normal file
@ -0,0 +1,56 @@
|
||||
/*
|
||||
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
|
||||
|
||||
class LayeredWidget;
|
||||
|
||||
namespace App {
|
||||
|
||||
void sendBotCommand(const QString &cmd, MsgId replyTo = 0);
|
||||
void insertBotCommand(const QString &cmd);
|
||||
void searchByHashtag(const QString &tag, PeerData *inPeer);
|
||||
void openPeerByName(const QString &username, bool toProfile = false, const QString &startToken = QString());
|
||||
void joinGroupByHash(const QString &hash);
|
||||
void stickersBox(const QString &name);
|
||||
void openLocalUrl(const QString &url);
|
||||
bool forward(const PeerId &peer, ForwardWhatMessages what);
|
||||
void removeDialog(History *history);
|
||||
void showSettings();
|
||||
void showLayer(LayeredWidget *w, bool forceFast = false);
|
||||
void replaceLayer(LayeredWidget *w);
|
||||
void showLayerLast(LayeredWidget *w);
|
||||
|
||||
};
|
||||
|
||||
namespace Ui { // it doesn't allow me to use UI :(
|
||||
|
||||
void showStickerPreview(DocumentData *sticker);
|
||||
void hideStickerPreview();
|
||||
|
||||
};
|
||||
|
||||
namespace Notify {
|
||||
|
||||
void userIsBotChanged(UserData *user);
|
||||
void botCommandsChanged(UserData *user);
|
||||
void migrateUpdated(PeerData *peer);
|
||||
|
||||
};
|
@ -27,8 +27,12 @@ Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
|
||||
#include "mainwidget.h"
|
||||
#include "gui/filedialog.h"
|
||||
|
||||
BackgroundWidget::BackgroundWidget(QWidget *parent, LayeredWidget *w) : QWidget(parent), w(w),
|
||||
aBackground(0), aBackgroundFunc(anim::easeOutCirc), hiding(false), shadow(st::boxShadow) {
|
||||
BackgroundWidget::BackgroundWidget(QWidget *parent, LayeredWidget *w) : TWidget(parent)
|
||||
, w(w)
|
||||
, aBackground(0)
|
||||
, aBackgroundFunc(anim::easeOutCirc)
|
||||
, hiding(false)
|
||||
, shadow(st::boxShadow) {
|
||||
w->setParent(this);
|
||||
if (App::app()) App::app()->mtpPause();
|
||||
setGeometry(0, 0, App::wnd()->width(), App::wnd()->height());
|
||||
@ -189,3 +193,115 @@ BackgroundWidget::~BackgroundWidget() {
|
||||
(*i)->deleteLater();
|
||||
}
|
||||
}
|
||||
|
||||
StickerPreviewWidget::StickerPreviewWidget(QWidget *parent) : TWidget(parent)
|
||||
, a_shown(0, 0)
|
||||
, _a_shown(animFunc(this, &StickerPreviewWidget::animStep_shown))
|
||||
, _doc(0)
|
||||
, _cacheStatus(CacheNotLoaded) {
|
||||
setAttribute(Qt::WA_TransparentForMouseEvents);
|
||||
}
|
||||
|
||||
void StickerPreviewWidget::paintEvent(QPaintEvent *e) {
|
||||
Painter p(this);
|
||||
QRect r(e->rect());
|
||||
|
||||
const QPixmap &draw(currentImage());
|
||||
uint32 w = draw.width() / cIntRetinaFactor(), h = draw.height() / cIntRetinaFactor();
|
||||
if (_a_shown.animating()) {
|
||||
float64 shown = a_shown.current();
|
||||
p.setOpacity(shown);
|
||||
// w = qMax(qRound(w * (st::stickerPreviewMin + ((1. - st::stickerPreviewMin) * shown)) / 2.) * 2 + int(w % 2), 1);
|
||||
// h = qMax(qRound(h * (st::stickerPreviewMin + ((1. - st::stickerPreviewMin) * shown)) / 2.) * 2 + int(h % 2), 1);
|
||||
}
|
||||
p.fillRect(r, st::stickerPreviewBg);
|
||||
p.drawPixmap((width() - w) / 2, (height() - h) / 2, draw);
|
||||
}
|
||||
|
||||
void StickerPreviewWidget::resizeEvent(QResizeEvent *e) {
|
||||
update();
|
||||
}
|
||||
|
||||
bool StickerPreviewWidget::animStep_shown(float64 ms) {
|
||||
float64 dt = ms / st::stickerPreviewDuration;
|
||||
if (dt >= 1) {
|
||||
a_shown.finish();
|
||||
_a_shown.stop();
|
||||
if (a_shown.current() < 0.5) hide();
|
||||
} else {
|
||||
a_shown.update(dt, anim::linear);
|
||||
}
|
||||
update();
|
||||
return true;
|
||||
}
|
||||
|
||||
void StickerPreviewWidget::showPreview(DocumentData *sticker) {
|
||||
if (sticker && !sticker->sticker()) sticker = 0;
|
||||
if (sticker) {
|
||||
_cache = QPixmap();
|
||||
if (isHidden() || _a_shown.animating()) {
|
||||
if (isHidden()) show();
|
||||
a_shown.start(1);
|
||||
_a_shown.start();
|
||||
} else {
|
||||
update();
|
||||
}
|
||||
} else if (isHidden()) {
|
||||
return;
|
||||
} else {
|
||||
a_shown.start(0);
|
||||
_a_shown.start();
|
||||
}
|
||||
_doc = sticker;
|
||||
_cacheStatus = CacheNotLoaded;
|
||||
}
|
||||
|
||||
void StickerPreviewWidget::hidePreview() {
|
||||
showPreview(0);
|
||||
}
|
||||
|
||||
QSize StickerPreviewWidget::currentDimensions() const {
|
||||
if (!_doc) return QSize(_cache.width() / cIntRetinaFactor(), _cache.height() / cIntRetinaFactor());
|
||||
|
||||
QSize result(qMax(_doc->dimensions.width(), 1), qMax(_doc->dimensions.height(), 1));
|
||||
if (result.width() > st::maxStickerSize) {
|
||||
result.setHeight(qMax(qRound((st::maxStickerSize * result.height()) / result.width()), 1));
|
||||
result.setWidth(st::maxStickerSize);
|
||||
}
|
||||
if (result.height() > st::maxStickerSize) {
|
||||
result.setWidth(qMax(qRound((st::maxStickerSize * result.width()) / result.height()), 1));
|
||||
result.setHeight(st::maxStickerSize);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
QPixmap StickerPreviewWidget::currentImage() const {
|
||||
if (_doc && _cacheStatus != CacheLoaded) {
|
||||
bool already = !_doc->already().isEmpty(), hasdata = !_doc->data.isEmpty();
|
||||
if (!_doc->loader && _doc->status != FileFailed && !already && !hasdata) {
|
||||
_doc->save(QString());
|
||||
}
|
||||
if (_doc->sticker()->img->isNull() && (already || hasdata)) {
|
||||
if (already) {
|
||||
_doc->sticker()->img = ImagePtr(_doc->already());
|
||||
} else {
|
||||
_doc->sticker()->img = ImagePtr(_doc->data);
|
||||
}
|
||||
}
|
||||
if (_doc->sticker()->img->isNull()) {
|
||||
if (_cacheStatus != CacheThumbLoaded) {
|
||||
QSize s = currentDimensions();
|
||||
_cache = _doc->thumb->pixBlurred(s.width(), s.height());
|
||||
_cacheStatus = CacheThumbLoaded;
|
||||
}
|
||||
} else {
|
||||
QSize s = currentDimensions();
|
||||
_cache = _doc->sticker()->img->pix(s.width(), s.height());
|
||||
_cacheStatus = CacheLoaded;
|
||||
}
|
||||
}
|
||||
return _cache;
|
||||
}
|
||||
|
||||
StickerPreviewWidget::~StickerPreviewWidget() {
|
||||
}
|
||||
|
@ -57,7 +57,7 @@ signals:
|
||||
|
||||
};
|
||||
|
||||
class BackgroundWidget : public QWidget, public Animated {
|
||||
class BackgroundWidget : public TWidget, public Animated {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
@ -104,3 +104,39 @@ private:
|
||||
|
||||
BoxShadow shadow;
|
||||
};
|
||||
|
||||
class StickerPreviewWidget : public TWidget {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
|
||||
StickerPreviewWidget(QWidget *parent);
|
||||
|
||||
void paintEvent(QPaintEvent *e);
|
||||
void resizeEvent(QResizeEvent *e);
|
||||
|
||||
bool animStep_shown(float64 ms);
|
||||
|
||||
void showPreview(DocumentData *sticker);
|
||||
void hidePreview();
|
||||
|
||||
~StickerPreviewWidget();
|
||||
|
||||
private:
|
||||
|
||||
QSize currentDimensions() const;
|
||||
QPixmap currentImage() const;
|
||||
|
||||
anim::fvalue a_shown;
|
||||
Animation _a_shown;
|
||||
DocumentData *_doc;
|
||||
|
||||
enum CacheStatus {
|
||||
CacheNotLoaded,
|
||||
CacheThumbLoaded,
|
||||
CacheLoaded,
|
||||
};
|
||||
mutable CacheStatus _cacheStatus;
|
||||
mutable QPixmap _cache;
|
||||
|
||||
};
|
||||
|
@ -395,6 +395,7 @@ MainWidget::MainWidget(Window *window) : TWidget(window)
|
||||
, _hider(0)
|
||||
, _peerInStack(0)
|
||||
, _msgIdInStack(0)
|
||||
, _stickerPreview(0)
|
||||
, _playerHeight(0)
|
||||
, _contentScrollAddToY(0)
|
||||
, _mediaType(this)
|
||||
@ -744,6 +745,20 @@ QPixmap MainWidget::grabTopBar() {
|
||||
}
|
||||
}
|
||||
|
||||
void MainWidget::ui_showStickerPreview(DocumentData *sticker) {
|
||||
if (!sticker || !sticker->sticker()) return;
|
||||
if (!_stickerPreview) {
|
||||
_stickerPreview = new StickerPreviewWidget(this);
|
||||
resizeEvent(0);
|
||||
}
|
||||
_stickerPreview->showPreview(sticker);
|
||||
}
|
||||
|
||||
void MainWidget::ui_hideStickerPreview() {
|
||||
if (!_stickerPreview) return;
|
||||
_stickerPreview->hidePreview();
|
||||
}
|
||||
|
||||
void MainWidget::noHider(HistoryHider *destroyed) {
|
||||
if (_hider == destroyed) {
|
||||
_hider = 0;
|
||||
@ -2566,6 +2581,7 @@ void MainWidget::orderWidgets() {
|
||||
dialogs.raise();
|
||||
_mediaType.raise();
|
||||
if (_hider) _hider->raise();
|
||||
if (_stickerPreview) _stickerPreview->raise();
|
||||
}
|
||||
|
||||
QRect MainWidget::historyRect() const {
|
||||
@ -2826,6 +2842,7 @@ void MainWidget::resizeEvent(QResizeEvent *e) {
|
||||
_mediaType.moveToLeft(width() - _mediaType.width(), _playerHeight + st::topBarHeight);
|
||||
if (profile) profile->setGeometry(history.geometry());
|
||||
if (overview) overview->setGeometry(history.geometry());
|
||||
if (_stickerPreview) _stickerPreview->setGeometry(rect());
|
||||
_contentScrollAddToY = 0;
|
||||
}
|
||||
|
||||
|
@ -178,6 +178,8 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
class StickerPreviewWidget;
|
||||
|
||||
class MainWidget : public TWidget, public RPCSender {
|
||||
Q_OBJECT
|
||||
|
||||
@ -412,6 +414,9 @@ public:
|
||||
QPixmap grabTopBar();
|
||||
QPixmap grabInner();
|
||||
|
||||
void ui_showStickerPreview(DocumentData *sticker);
|
||||
void ui_hideStickerPreview();
|
||||
|
||||
~MainWidget();
|
||||
|
||||
signals:
|
||||
@ -565,6 +570,8 @@ private:
|
||||
PeerData *_peerInStack;
|
||||
MsgId _msgIdInStack;
|
||||
|
||||
StickerPreviewWidget *_stickerPreview;
|
||||
|
||||
int32 _playerHeight;
|
||||
int32 _contentScrollAddToY;
|
||||
|
||||
|
41
Telegram/SourceFiles/mtproto/mtpAuthKey.cpp
Normal file
41
Telegram/SourceFiles/mtproto/mtpAuthKey.cpp
Normal file
@ -0,0 +1,41 @@
|
||||
/*
|
||||
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"
|
||||
|
||||
void aesEncrypt(const void *src, void *dst, uint32 len, void *key, void *iv) {
|
||||
uchar aes_key[32], aes_iv[32];
|
||||
memcpy(aes_key, key, 32);
|
||||
memcpy(aes_iv, iv, 32);
|
||||
|
||||
AES_KEY aes;
|
||||
AES_set_encrypt_key(aes_key, 256, &aes);
|
||||
AES_ige_encrypt((const uchar*)src, (uchar*)dst, len, &aes, aes_iv, AES_ENCRYPT);
|
||||
}
|
||||
|
||||
void aesDecrypt(const void *src, void *dst, uint32 len, void *key, void *iv) {
|
||||
uchar aes_key[32], aes_iv[32];
|
||||
memcpy(aes_key, key, 32);
|
||||
memcpy(aes_iv, iv, 32);
|
||||
|
||||
AES_KEY aes;
|
||||
AES_set_decrypt_key(aes_key, 256, &aes);
|
||||
AES_ige_encrypt((const uchar*)src, (uchar*)dst, len, &aes, aes_iv, AES_DECRYPT);
|
||||
}
|
@ -112,15 +112,8 @@ inline bool operator==(const mtpAuthKey &a, const mtpAuthKey &b) {
|
||||
typedef QSharedPointer<mtpAuthKey> mtpAuthKeyPtr;
|
||||
typedef QVector<mtpAuthKeyPtr> mtpKeysMap;
|
||||
|
||||
inline void aesEncrypt(const void *src, void *dst, uint32 len, void *key, void *iv) {
|
||||
uchar aes_key[32], aes_iv[32];
|
||||
memcpy(aes_key, key, 32);
|
||||
memcpy(aes_iv, iv, 32);
|
||||
|
||||
AES_KEY aes;
|
||||
AES_set_encrypt_key(aes_key, 256, &aes);
|
||||
AES_ige_encrypt((const uchar*)src, (uchar*)dst, len, &aes, aes_iv, AES_ENCRYPT);
|
||||
}
|
||||
void aesEncrypt(const void *src, void *dst, uint32 len, void *key, void *iv);
|
||||
void aesDecrypt(const void *src, void *dst, uint32 len, void *key, void *iv);
|
||||
|
||||
inline void aesEncrypt(const void *src, void *dst, uint32 len, const mtpAuthKeyPtr &authKey, const MTPint128 &msgKey) {
|
||||
MTPint256 aesKey, aesIV;
|
||||
@ -136,16 +129,6 @@ inline void aesEncryptLocal(const void *src, void *dst, uint32 len, const mtpAut
|
||||
return aesEncrypt(src, dst, len, &aesKey, &aesIV);
|
||||
}
|
||||
|
||||
inline void aesDecrypt(const void *src, void *dst, uint32 len, void *key, void *iv) {
|
||||
uchar aes_key[32], aes_iv[32];
|
||||
memcpy(aes_key, key, 32);
|
||||
memcpy(aes_iv, iv, 32);
|
||||
|
||||
AES_KEY aes;
|
||||
AES_set_decrypt_key(aes_key, 256, &aes);
|
||||
AES_ige_encrypt((const uchar*)src, (uchar*)dst, len, &aes, aes_iv, AES_DECRYPT);
|
||||
}
|
||||
|
||||
inline void aesDecrypt(const void *src, void *dst, uint32 len, const mtpAuthKeyPtr &authKey, const MTPint128 &msgKey) {
|
||||
MTPint256 aesKey, aesIV;
|
||||
authKey->prepareAES(msgKey, aesKey, aesIV, false);
|
||||
|
@ -436,3 +436,10 @@ inline int32 ceilclamp(int32 value, int32 step, int32 lowest, int32 highest) {
|
||||
inline int32 ceilclamp(float64 value, int32 step, int32 lowest, int32 highest) {
|
||||
return qMax(qMin(qCeil(value / step), highest), lowest);
|
||||
}
|
||||
|
||||
enum ForwardWhatMessages {
|
||||
ForwardSelectedMessages,
|
||||
ForwardContextMessage,
|
||||
ForwardPressedMessage,
|
||||
ForwardPressedLinkMessage
|
||||
};
|
||||
|
@ -987,6 +987,8 @@ bool Window::eventFilter(QObject *obj, QEvent *evt) {
|
||||
psUserActionDone();
|
||||
main->checkIdleFinish();
|
||||
}
|
||||
} else if (t == QEvent::MouseButtonRelease) {
|
||||
Ui::hideStickerPreview();
|
||||
}
|
||||
if (obj == App::app()) {
|
||||
if (t == QEvent::ApplicationActivate) {
|
||||
|
@ -992,6 +992,7 @@
|
||||
<ClCompile Include="SourceFiles\boxes\usernamebox.cpp" />
|
||||
<ClCompile Include="SourceFiles\dialogswidget.cpp" />
|
||||
<ClCompile Include="SourceFiles\dropdown.cpp" />
|
||||
<ClCompile Include="SourceFiles\facades.cpp" />
|
||||
<ClCompile Include="SourceFiles\fileuploader.cpp" />
|
||||
<ClCompile Include="SourceFiles\gui\animation.cpp" />
|
||||
<ClCompile Include="SourceFiles\gui\boxshadow.cpp" />
|
||||
@ -1029,6 +1030,7 @@
|
||||
<ClCompile Include="SourceFiles\mainwidget.cpp" />
|
||||
<ClCompile Include="SourceFiles\mediaview.cpp" />
|
||||
<ClCompile Include="SourceFiles\mtproto\mtp.cpp" />
|
||||
<ClCompile Include="SourceFiles\mtproto\mtpAuthKey.cpp" />
|
||||
<ClCompile Include="SourceFiles\mtproto\mtpConnection.cpp" />
|
||||
<ClCompile Include="SourceFiles\mtproto\mtpCoreTypes.cpp" />
|
||||
<ClCompile Include="SourceFiles\mtproto\mtpDC.cpp" />
|
||||
@ -1552,6 +1554,7 @@
|
||||
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(QTDIR)\bin\moc.exe;%(FullPath)</AdditionalInputs>
|
||||
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(QTDIR)\bin\moc.exe;%(FullPath)</AdditionalInputs>
|
||||
</CustomBuild>
|
||||
<ClInclude Include="SourceFiles\facades.h" />
|
||||
<ClInclude Include="SourceFiles\gui\boxshadow.h" />
|
||||
<CustomBuild Include="SourceFiles\gui\popupmenu.h">
|
||||
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Deploy|Win32'">$(QTDIR)\bin\moc.exe;%(FullPath);$(QTDIR)\bin\moc.exe;%(FullPath)</AdditionalInputs>
|
||||
|
@ -900,6 +900,12 @@
|
||||
<ClCompile Include="SourceFiles\gui\popupmenu.cpp">
|
||||
<Filter>gui</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="SourceFiles\facades.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="SourceFiles\mtproto\mtpAuthKey.cpp">
|
||||
<Filter>mtproto</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="SourceFiles\stdafx.h">
|
||||
@ -989,6 +995,9 @@
|
||||
<ClInclude Include="SourceFiles\config.h">
|
||||
<Filter>Version</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="SourceFiles\facades.h">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<CustomBuild Include="SourceFiles\mtproto\mtpConnection.h">
|
||||
|
Loading…
Reference in New Issue
Block a user