mirror of https://github.com/procxx/kepka.git
Custom notifications inline reply added, positioning broken.
This commit is contained in:
parent
c8aa7672e9
commit
043cba0a64
|
@ -1400,15 +1400,7 @@ btnCancelSearch: iconedButton(btnAddContact) {
|
||||||
downIcon: sprite(188px, 43px, 18px, 18px);
|
downIcon: sprite(188px, 43px, 18px, 18px);
|
||||||
}
|
}
|
||||||
|
|
||||||
notifyBG: white;
|
simpleClose: iconedButton(btnDefIconed) {
|
||||||
notifyBorder: #f1f1f1;
|
|
||||||
notifyBorderWidth: 1px;
|
|
||||||
notifySlowHide: 4000;
|
|
||||||
notifyPhotoSize: 62px;
|
|
||||||
notifyMacPhotoSize: 64px;
|
|
||||||
notifyPhotoPos: point(9px, 9px);
|
|
||||||
notifyClosePos: point(1px, 2px);
|
|
||||||
notifyClose: iconedButton(btnDefIconed) {
|
|
||||||
icon: sprite(167px, 130px, 10px, 10px);
|
icon: sprite(167px, 130px, 10px, 10px);
|
||||||
iconPos: point(10px, 10px);
|
iconPos: point(10px, 10px);
|
||||||
downIcon: sprite(167px, 130px, 10px, 10px);
|
downIcon: sprite(167px, 130px, 10px, 10px);
|
||||||
|
@ -1417,17 +1409,6 @@ notifyClose: iconedButton(btnDefIconed) {
|
||||||
width: 30px;
|
width: 30px;
|
||||||
height: 30px;
|
height: 30px;
|
||||||
}
|
}
|
||||||
notifyItemTop: 12px;
|
|
||||||
notifyTextLeft: 12px;
|
|
||||||
notifyTextTop: 7px;
|
|
||||||
notifySlowHideFunc: transition(easeInCirc);
|
|
||||||
notifyWaitShortHide: 0;
|
|
||||||
notifyWaitLongHide: 20000;
|
|
||||||
notifyFastAnim: 150;
|
|
||||||
notifyWidth: 316px;
|
|
||||||
notifyHeight: 80px;
|
|
||||||
notifyDeltaX: 6px;
|
|
||||||
notifyDeltaY: 7px;
|
|
||||||
|
|
||||||
boxPhotoPadding: margins(28px, 28px, 28px, 18px);
|
boxPhotoPadding: margins(28px, 28px, 28px, 18px);
|
||||||
boxPhotoCompressedPadding: margins(0px, 2px, 0px, 22px);
|
boxPhotoCompressedPadding: margins(0px, 2px, 0px, 22px);
|
||||||
|
@ -2031,7 +2012,7 @@ sessionInfoFont: msgFont;
|
||||||
sessionInfoColor: #888888;
|
sessionInfoColor: #888888;
|
||||||
sessionTerminateTop: 30px;
|
sessionTerminateTop: 30px;
|
||||||
sessionTerminateSkip: 18px;
|
sessionTerminateSkip: 18px;
|
||||||
sessionTerminate: iconedButton(notifyClose) {
|
sessionTerminate: iconedButton(simpleClose) {
|
||||||
iconPos: point(3px, 3px);
|
iconPos: point(3px, 3px);
|
||||||
downIconPos: point(3px, 4px);
|
downIconPos: point(3px, 4px);
|
||||||
width: 16px;
|
width: 16px;
|
||||||
|
@ -2045,6 +2026,8 @@ webPageDescriptionFont: normalFont;
|
||||||
webPagePhotoSize: 100px;
|
webPagePhotoSize: 100px;
|
||||||
webPagePhotoDelta: 8px;
|
webPagePhotoDelta: 8px;
|
||||||
|
|
||||||
|
mediaPlayerSuppressDuration: 150;
|
||||||
|
|
||||||
botDescSkip: 8px;
|
botDescSkip: 8px;
|
||||||
|
|
||||||
suppressAll: 0.2;
|
suppressAll: 0.2;
|
||||||
|
|
Binary file not shown.
After Width: | Height: | Size: 139 B |
Binary file not shown.
After Width: | Height: | Size: 192 B |
Binary file not shown.
After Width: | Height: | Size: 142 B |
Binary file not shown.
After Width: | Height: | Size: 190 B |
Binary file not shown.
After Width: | Height: | Size: 292 B |
Binary file not shown.
After Width: | Height: | Size: 506 B |
|
@ -872,6 +872,8 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
"lng_send_image_too_large" = "Could not send a file, because it is larger than 1.5 GB :(";
|
"lng_send_image_too_large" = "Could not send a file, because it is larger than 1.5 GB :(";
|
||||||
"lng_send_folder" = "Could not send «{name}» because it is a directory :(";
|
"lng_send_folder" = "Could not send «{name}» because it is a directory :(";
|
||||||
|
|
||||||
|
"lng_notification_reply" = "Reply";
|
||||||
|
|
||||||
"lng_forward_choose" = "Choose recipient...";
|
"lng_forward_choose" = "Choose recipient...";
|
||||||
"lng_forward_cant" = "Sorry, no way to forward here :(";
|
"lng_forward_cant" = "Sorry, no way to forward here :(";
|
||||||
"lng_forward_confirm" = "Forward to {recipient}?";
|
"lng_forward_confirm" = "Forward to {recipient}?";
|
||||||
|
|
|
@ -123,8 +123,8 @@ void DialogsInner::paintRegion(Painter &p, const QRegion ®ion, bool paintingO
|
||||||
p.fillRect(0, 0, w, st::mentionHeight, (selected ? st::mentionBgOver : st::white)->b);
|
p.fillRect(0, 0, w, st::mentionHeight, (selected ? st::mentionBgOver : st::white)->b);
|
||||||
if (!paintingOther) {
|
if (!paintingOther) {
|
||||||
if (selected) {
|
if (selected) {
|
||||||
int skip = (st::mentionHeight - st::notifyClose.icon.pxHeight()) / 2;
|
int skip = (st::mentionHeight - st::simpleClose.icon.pxHeight()) / 2;
|
||||||
p.drawSprite(QPoint(w - st::notifyClose.icon.pxWidth() - skip, skip), st::notifyClose.icon);
|
p.drawSprite(QPoint(w - st::simpleClose.icon.pxWidth() - skip, skip), st::simpleClose.icon);
|
||||||
}
|
}
|
||||||
QString first = (_hashtagFilter.size() < 2) ? QString() : ('#' + _hashtagResults.at(from).mid(0, _hashtagFilter.size() - 1)), second = (_hashtagFilter.size() < 2) ? ('#' + _hashtagResults.at(from)) : _hashtagResults.at(from).mid(_hashtagFilter.size() - 1);
|
QString first = (_hashtagFilter.size() < 2) ? QString() : ('#' + _hashtagResults.at(from).mid(0, _hashtagFilter.size() - 1)), second = (_hashtagFilter.size() < 2) ? ('#' + _hashtagResults.at(from)) : _hashtagResults.at(from).mid(_hashtagFilter.size() - 1);
|
||||||
int32 firstwidth = st::mentionFont->width(first), secondwidth = st::mentionFont->width(second);
|
int32 firstwidth = st::mentionFont->width(first), secondwidth = st::mentionFont->width(second);
|
||||||
|
|
|
@ -600,9 +600,9 @@ void FieldAutocompleteInner::paintEvent(QPaintEvent *e) {
|
||||||
bool selected = (i == _sel);
|
bool selected = (i == _sel);
|
||||||
if (selected) {
|
if (selected) {
|
||||||
p.fillRect(0, i * st::mentionHeight, width(), st::mentionHeight, st::mentionBgOver->b);
|
p.fillRect(0, i * st::mentionHeight, width(), st::mentionHeight, st::mentionBgOver->b);
|
||||||
int skip = (st::mentionHeight - st::notifyClose.icon.pxHeight()) / 2;
|
int skip = (st::mentionHeight - st::simpleClose.icon.pxHeight()) / 2;
|
||||||
if (!_hrows->isEmpty() || (!_mrows->isEmpty() && i < _recentInlineBotsInRows)) {
|
if (!_hrows->isEmpty() || (!_mrows->isEmpty() && i < _recentInlineBotsInRows)) {
|
||||||
p.drawSprite(QPoint(width() - st::notifyClose.icon.pxWidth() - skip, i * st::mentionHeight + skip), st::notifyClose.icon);
|
p.drawSprite(QPoint(width() - st::simpleClose.icon.pxWidth() - skip, i * st::mentionHeight + skip), st::simpleClose.icon);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
p.setPen(st::black->p);
|
p.setPen(st::black->p);
|
||||||
|
|
|
@ -984,13 +984,13 @@ void AudioPlayerFader::onTimer() {
|
||||||
} else if (ms > _suppressAllStart + notifyLengthMs - AudioFadeDuration) {
|
} else if (ms > _suppressAllStart + notifyLengthMs - AudioFadeDuration) {
|
||||||
if (_suppressAllGain.to() != 1.) _suppressAllGain.start(1.);
|
if (_suppressAllGain.to() != 1.) _suppressAllGain.start(1.);
|
||||||
_suppressAllGain.update(1. - ((_suppressAllStart + notifyLengthMs - ms) / float64(AudioFadeDuration)), anim::linear);
|
_suppressAllGain.update(1. - ((_suppressAllStart + notifyLengthMs - ms) / float64(AudioFadeDuration)), anim::linear);
|
||||||
} else if (ms >= _suppressAllStart + st::notifyFastAnim) {
|
} else if (ms >= _suppressAllStart + st::mediaPlayerSuppressDuration) {
|
||||||
if (_suppressAllAnim) {
|
if (_suppressAllAnim) {
|
||||||
_suppressAllGain.finish();
|
_suppressAllGain.finish();
|
||||||
_suppressAllAnim = false;
|
_suppressAllAnim = false;
|
||||||
}
|
}
|
||||||
} else if (ms > _suppressAllStart) {
|
} else if (ms > _suppressAllStart) {
|
||||||
_suppressAllGain.update((ms - _suppressAllStart) / st::notifyFastAnim, anim::linear);
|
_suppressAllGain.update((ms - _suppressAllStart) / st::mediaPlayerSuppressDuration, anim::linear);
|
||||||
}
|
}
|
||||||
suppressAllGain = _suppressAllGain.current();
|
suppressAllGain = _suppressAllGain.current();
|
||||||
suppressAudioChanged = (suppressAllGain != wasAudio);
|
suppressAudioChanged = (suppressAllGain != wasAudio);
|
||||||
|
|
|
@ -156,7 +156,7 @@ private:
|
||||||
|
|
||||||
if (auto manager = ManagerInstance.data()) {
|
if (auto manager = ManagerInstance.data()) {
|
||||||
if (manager->hasActionsSupport()) {
|
if (manager->hasActionsSupport()) {
|
||||||
auto label = lang(lng_context_reply_msg).toUtf8();
|
auto label = lang(lng_notification_reply).toUtf8();
|
||||||
auto actionReceiver = _data;
|
auto actionReceiver = _data;
|
||||||
auto actionHandler = &NotificationData::notificationClicked;
|
auto actionHandler = &NotificationData::notificationClicked;
|
||||||
auto actionLabel = label.constData();
|
auto actionLabel = label.constData();
|
||||||
|
|
|
@ -23,6 +23,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
|
|
||||||
#include "pspecific.h"
|
#include "pspecific.h"
|
||||||
#include "platform/mac/mac_utilities.h"
|
#include "platform/mac/mac_utilities.h"
|
||||||
|
#include "styles/style_window.h"
|
||||||
|
|
||||||
#include <Cocoa/Cocoa.h>
|
#include <Cocoa/Cocoa.h>
|
||||||
|
|
||||||
|
|
|
@ -2419,14 +2419,14 @@ EmojiPanel::EmojiPanel(QWidget *parent, const QString &text, uint64 setId, bool
|
||||||
, _setId(setId)
|
, _setId(setId)
|
||||||
, _special(special)
|
, _special(special)
|
||||||
, _deleteVisible(false)
|
, _deleteVisible(false)
|
||||||
, _delete(special ? 0 : new IconedButton(this, st::notifyClose)) { // Stickers::NoneSetId if in emoji
|
, _delete(special ? 0 : new IconedButton(this, st::simpleClose)) { // Stickers::NoneSetId if in emoji
|
||||||
resize(st::emojiPanWidth, st::emojiPanHeader);
|
resize(st::emojiPanWidth, st::emojiPanHeader);
|
||||||
setMouseTracking(true);
|
setMouseTracking(true);
|
||||||
setFocusPolicy(Qt::NoFocus);
|
setFocusPolicy(Qt::NoFocus);
|
||||||
setText(text);
|
setText(text);
|
||||||
if (_delete) {
|
if (_delete) {
|
||||||
_delete->hide();
|
_delete->hide();
|
||||||
_delete->moveToRight(st::emojiPanHeaderLeft - ((_delete->width() - st::notifyClose.icon.pxWidth()) / 2), (st::emojiPanHeader - _delete->height()) / 2, width());
|
_delete->moveToRight(st::emojiPanHeaderLeft - ((_delete->width() - st::simpleClose.icon.pxWidth()) / 2), (st::emojiPanHeader - _delete->height()) / 2, width());
|
||||||
connect(_delete, SIGNAL(clicked()), this, SLOT(onDelete()));
|
connect(_delete, SIGNAL(clicked()), this, SLOT(onDelete()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2444,7 +2444,7 @@ void EmojiPanel::updateText() {
|
||||||
int32 availw = st::emojiPanWidth - st::emojiPanHeaderLeft * 2;
|
int32 availw = st::emojiPanWidth - st::emojiPanHeaderLeft * 2;
|
||||||
if (_deleteVisible) {
|
if (_deleteVisible) {
|
||||||
if (!_special && _setId != Stickers::NoneSetId) {
|
if (!_special && _setId != Stickers::NoneSetId) {
|
||||||
availw -= st::notifyClose.icon.pxWidth() + st::emojiPanHeaderLeft;
|
availw -= st::simpleClose.icon.pxWidth() + st::emojiPanHeaderLeft;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
auto switchText = ([this]() {
|
auto switchText = ([this]() {
|
||||||
|
|
|
@ -24,8 +24,10 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
#include "platform/platform_notifications_manager.h"
|
#include "platform/platform_notifications_manager.h"
|
||||||
#include "mainwindow.h"
|
#include "mainwindow.h"
|
||||||
#include "lang.h"
|
#include "lang.h"
|
||||||
|
#include "ui/buttons/icon_button.h"
|
||||||
#include "dialogs/dialogs_layout.h"
|
#include "dialogs/dialogs_layout.h"
|
||||||
#include "styles/style_dialogs.h"
|
#include "styles/style_dialogs.h"
|
||||||
|
#include "styles/style_window.h"
|
||||||
|
|
||||||
namespace Window {
|
namespace Window {
|
||||||
namespace Notifications {
|
namespace Notifications {
|
||||||
|
@ -37,6 +39,16 @@ constexpr int kNotifyWindowsCount = 3;
|
||||||
|
|
||||||
NeverFreedPointer<Manager> ManagerInstance;
|
NeverFreedPointer<Manager> ManagerInstance;
|
||||||
|
|
||||||
|
int notificationWidth() {
|
||||||
|
static auto result = ([] {
|
||||||
|
auto replyWidth = st::defaultBoxButton.font->width(lang(lng_notification_reply).toUpper()) - st::defaultBoxButton.width;
|
||||||
|
auto textLeft = st::notifyPhotoPos.x() + st::notifyPhotoSize + st::notifyTextLeft;
|
||||||
|
auto minWidth = textLeft + replyWidth + st::boxButtonPadding.right();
|
||||||
|
return qMax(st::notifyMinWidth, minWidth);
|
||||||
|
})();
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
void start() {
|
void start() {
|
||||||
|
@ -78,7 +90,7 @@ void Manager::showNextFromQueue() {
|
||||||
|
|
||||||
int count = kNotifyWindowsCount;
|
int count = kNotifyWindowsCount;
|
||||||
for_const (auto widget, _widgets) {
|
for_const (auto widget, _widgets) {
|
||||||
if (widget->index() < 0) continue;
|
if (widget->isUnlinked()) continue;
|
||||||
--count;
|
--count;
|
||||||
}
|
}
|
||||||
if (count <= 0) {
|
if (count <= 0) {
|
||||||
|
@ -86,8 +98,8 @@ void Manager::showNextFromQueue() {
|
||||||
}
|
}
|
||||||
|
|
||||||
auto r = psDesktopRect();
|
auto r = psDesktopRect();
|
||||||
auto x = r.x() + r.width() - st::notifyWidth - st::notifyDeltaX;
|
auto x = r.x() + r.width() - notificationWidth() - st::notifyDeltaX;
|
||||||
auto y = r.y() + r.height() - st::notifyHeight - st::notifyDeltaY;
|
auto y = r.y() + r.height();
|
||||||
do {
|
do {
|
||||||
auto queued = _queuedNotifications.front();
|
auto queued = _queuedNotifications.front();
|
||||||
_queuedNotifications.pop_front();
|
_queuedNotifications.pop_front();
|
||||||
|
@ -98,11 +110,11 @@ void Manager::showNextFromQueue() {
|
||||||
--count;
|
--count;
|
||||||
} while (count > 0 && !_queuedNotifications.isEmpty());
|
} while (count > 0 && !_queuedNotifications.isEmpty());
|
||||||
|
|
||||||
auto shown = kNotifyWindowsCount - count;
|
auto bottom = y - st::notifyDeltaY;
|
||||||
for_const (auto widget, _widgets) {
|
for_const (auto widget, _widgets) {
|
||||||
if (widget->index() < 0) continue;
|
if (widget->isUnlinked() < 0) continue;
|
||||||
--shown;
|
widget->moveTop(y - widget->height(), y);
|
||||||
widget->moveTo(x, y - shown * (st::notifyHeight + st::notifyDeltaY));
|
y -= widget->height() + st::notifyDeltaY;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -177,12 +189,16 @@ Widget::Widget(History *history, PeerData *peer, PeerData *author, HistoryItem *
|
||||||
, _started(GetTickCount())
|
, _started(GetTickCount())
|
||||||
#endif // Q_OS_WIN && !Q_OS_WINRT
|
#endif // Q_OS_WIN && !Q_OS_WINRT
|
||||||
, _close(this, st::notifyClose)
|
, _close(this, st::notifyClose)
|
||||||
|
, _reply(this, lang(lng_notification_reply), st::defaultBoxButton)
|
||||||
, _alphaDuration(st::notifyFastAnim)
|
, _alphaDuration(st::notifyFastAnim)
|
||||||
, _posDuration(st::notifyFastAnim)
|
|
||||||
, a_opacity(0)
|
, a_opacity(0)
|
||||||
, a_func(anim::linear)
|
, a_func(anim::linear)
|
||||||
, a_y(y + st::notifyHeight + st::notifyDeltaY)
|
, a_top(y)
|
||||||
|
, a_bottom(y + st::notifyMinHeight)
|
||||||
|
, _a_movement(animation(this, &Widget::step_movement))
|
||||||
, _a_appearance(animation(this, &Widget::step_appearance)) {
|
, _a_appearance(animation(this, &Widget::step_appearance)) {
|
||||||
|
setGeometry(x, a_top.current(), notificationWidth(), a_bottom.current() - a_top.current());
|
||||||
|
|
||||||
updateNotifyDisplay();
|
updateNotifyDisplay();
|
||||||
|
|
||||||
_hideTimer.setSingleShot(true);
|
_hideTimer.setSingleShot(true);
|
||||||
|
@ -191,15 +207,21 @@ Widget::Widget(History *history, PeerData *peer, PeerData *author, HistoryItem *
|
||||||
_inputTimer.setSingleShot(true);
|
_inputTimer.setSingleShot(true);
|
||||||
connect(&_inputTimer, SIGNAL(timeout()), this, SLOT(checkLastInput()));
|
connect(&_inputTimer, SIGNAL(timeout()), this, SLOT(checkLastInput()));
|
||||||
|
|
||||||
_close.setClickedCallback([this] {
|
_close->setClickedCallback([this] {
|
||||||
unlinkHistoryAndNotify();
|
unlinkHistoryAndNotify();
|
||||||
});
|
});
|
||||||
_close.setAcceptBoth(true);
|
_close->setAcceptBoth(true);
|
||||||
_close.move(st::notifyWidth - st::notifyClose.width - st::notifyClosePos.x(), st::notifyClosePos.y());
|
_close->moveToRight(st::notifyClosePos.x(), st::notifyClosePos.y());
|
||||||
_close.show();
|
_close->show();
|
||||||
|
|
||||||
a_y.start(y);
|
_reply->setClickedCallback([this] {
|
||||||
setGeometry(x, a_y.current(), st::notifyWidth, st::notifyHeight);
|
showReplyField();
|
||||||
|
});
|
||||||
|
_replyPadding = st::notifyMinHeight - st::notifyPhotoPos.y() - st::notifyPhotoSize;
|
||||||
|
_reply->moveToRight(_replyPadding, height() - _reply->height() - _replyPadding);
|
||||||
|
_reply->hide();
|
||||||
|
|
||||||
|
prepareActionsCache();
|
||||||
|
|
||||||
a_opacity.start(1);
|
a_opacity.start(1);
|
||||||
setWindowFlags(Qt::Tool | Qt::WindowStaysOnTopHint | Qt::FramelessWindowHint | Qt::X11BypassWindowManagerHint);
|
setWindowFlags(Qt::Tool | Qt::WindowStaysOnTopHint | Qt::FramelessWindowHint | Qt::X11BypassWindowManagerHint);
|
||||||
|
@ -209,12 +231,29 @@ Widget::Widget(History *history, PeerData *peer, PeerData *author, HistoryItem *
|
||||||
|
|
||||||
setWindowOpacity(a_opacity.current());
|
setWindowOpacity(a_opacity.current());
|
||||||
|
|
||||||
_alphaDuration = _posDuration = st::notifyFastAnim;
|
_alphaDuration = st::notifyFastAnim;
|
||||||
_a_appearance.start();
|
_a_appearance.start();
|
||||||
|
|
||||||
checkLastInput();
|
checkLastInput();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Widget::prepareActionsCache() {
|
||||||
|
auto replyCache = myGrab(_reply);
|
||||||
|
auto fadeWidth = st::notifyFadeRight.width();
|
||||||
|
auto actionsTop = st::notifyTextTop + st::msgNameFont->height;
|
||||||
|
auto actionsCacheWidth = _reply->width() + _replyPadding + fadeWidth;
|
||||||
|
auto actionsCacheHeight = height() - actionsTop;
|
||||||
|
auto actionsCacheImg = QImage(actionsCacheWidth * cIntRetinaFactor(), actionsCacheHeight * cIntRetinaFactor(), QImage::Format_ARGB32_Premultiplied);
|
||||||
|
actionsCacheImg.fill(st::transparent->c);
|
||||||
|
{
|
||||||
|
Painter p(&actionsCacheImg);
|
||||||
|
st::notifyFadeRight.fill(p, rtlrect(0, 0, fadeWidth, actionsCacheHeight, actionsCacheWidth));
|
||||||
|
p.fillRect(rtlrect(fadeWidth, 0, actionsCacheWidth - fadeWidth, actionsCacheHeight, actionsCacheWidth), st::notifyBg);
|
||||||
|
p.drawPixmapRight(_replyPadding, _reply->y() - actionsTop, actionsCacheWidth, replyCache);
|
||||||
|
}
|
||||||
|
_buttonsCache = App::pixmapFromImageInPlace(std_::move(actionsCacheImg));
|
||||||
|
}
|
||||||
|
|
||||||
void Widget::checkLastInput() {
|
void Widget::checkLastInput() {
|
||||||
#if defined Q_OS_WIN && !defined Q_OS_WINRT
|
#if defined Q_OS_WIN && !defined Q_OS_WINRT
|
||||||
LASTINPUTINFO lii;
|
LASTINPUTINFO lii;
|
||||||
|
@ -235,24 +274,39 @@ void Widget::checkLastInput() {
|
||||||
#endif // else for Q_OS_WIN && !Q_OS_WINRT
|
#endif // else for Q_OS_WIN && !Q_OS_WINRT
|
||||||
}
|
}
|
||||||
|
|
||||||
void Widget::moveTo(int x, int y, int index) {
|
void Widget::onReplyResize() {
|
||||||
if (index >= 0) {
|
_a_movement.stop();
|
||||||
_index = index;
|
auto newHeight = st::notifyMinHeight + _replyArea->height() + st::notifyBorderWidth;
|
||||||
|
auto delta = height() - newHeight;
|
||||||
|
if (delta != 0) {
|
||||||
|
auto top = a_top.current() + delta;
|
||||||
|
a_top = anim::ivalue(top, top);
|
||||||
|
setGeometry(x(), top, width(), a_bottom.current() - top);
|
||||||
|
update();
|
||||||
}
|
}
|
||||||
move(x, a_y.current());
|
}
|
||||||
a_y.start(y);
|
|
||||||
a_opacity.restart();
|
void Widget::onReplySubmit(bool ctrlShiftEnter) {
|
||||||
_posDuration = st::notifyFastAnim;
|
sendReply();
|
||||||
_a_appearance.start();
|
}
|
||||||
|
|
||||||
|
void Widget::onReplyCancel() {
|
||||||
|
unlinkHistoryAndNotify();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Widget::moveTop(int top, int bottom) {
|
||||||
|
a_top.start(top);
|
||||||
|
a_bottom.start(bottom);
|
||||||
|
_a_movement.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Widget::updateNotifyDisplay() {
|
void Widget::updateNotifyDisplay() {
|
||||||
if (!_history || !_peer || (!_item && _forwardedCount < 2)) return;
|
if (!_history || !_peer || (!_item && _forwardedCount < 2)) return;
|
||||||
|
|
||||||
int32 w = st::notifyWidth, h = st::notifyHeight;
|
int32 w = width(), h = height();
|
||||||
QImage img(w * cIntRetinaFactor(), h * cIntRetinaFactor(), QImage::Format_ARGB32_Premultiplied);
|
QImage img(w * cIntRetinaFactor(), h * cIntRetinaFactor(), QImage::Format_ARGB32_Premultiplied);
|
||||||
if (cRetina()) img.setDevicePixelRatio(cRetinaFactor());
|
if (cRetina()) img.setDevicePixelRatio(cRetinaFactor());
|
||||||
img.fill(st::notifyBG->c);
|
img.fill(st::notifyBg->c);
|
||||||
|
|
||||||
{
|
{
|
||||||
Painter p(&img);
|
Painter p(&img);
|
||||||
|
@ -345,6 +399,64 @@ void Widget::unlinkHistoryAndNotify() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Widget::toggleActionButtons(bool visible) {
|
||||||
|
if (_actionsVisible != visible) {
|
||||||
|
_actionsVisible = visible;
|
||||||
|
_reply->hide();
|
||||||
|
a_actionsOpacity.start([this] { actionsOpacityCallback(); }, _actionsVisible ? 0. : 1., _actionsVisible ? 1. : 0., st::notifyActionsDuration);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Widget::actionsOpacityCallback() {
|
||||||
|
update();
|
||||||
|
if (!a_actionsOpacity.animating() && _actionsVisible) {
|
||||||
|
_reply->show();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Widget::showReplyField() {
|
||||||
|
if (_replyArea) return;
|
||||||
|
|
||||||
|
_replyArea = new InputArea(this, st::notifyReplyArea, lang(lng_message_ph), QString());
|
||||||
|
_replyArea->resize(width() - st::notifySendReply.width - 2 * st::notifyBorderWidth, st::notifySendReply.height);
|
||||||
|
_replyArea->moveToLeft(st::notifyBorderWidth, st::notifyMinHeight);
|
||||||
|
_replyArea->show();
|
||||||
|
_replyArea->setFocus();
|
||||||
|
_replyArea->setMaxLength(MaxMessageSize);
|
||||||
|
_replyArea->setCtrlEnterSubmit(CtrlEnterSubmitBoth);
|
||||||
|
connect(_replyArea, SIGNAL(resized()), this, SLOT(onReplyResize()));
|
||||||
|
connect(_replyArea, SIGNAL(submitted(bool)), this, SLOT(onReplySubmit(bool)));
|
||||||
|
connect(_replyArea, SIGNAL(cancelled()), this, SLOT(onReplyCancel()));
|
||||||
|
|
||||||
|
_replySend = new Ui::IconButton(this, st::notifySendReply);
|
||||||
|
_replySend->moveToRight(st::notifyBorderWidth, st::notifyMinHeight);
|
||||||
|
_replySend->show();
|
||||||
|
_replySend->setClickedCallback([this] { sendReply(); });
|
||||||
|
|
||||||
|
toggleActionButtons(false);
|
||||||
|
|
||||||
|
a_top.finish();
|
||||||
|
a_bottom.finish();
|
||||||
|
|
||||||
|
_a_movement.stop();
|
||||||
|
auto top = a_top.current() - _replyArea->height() - st::notifyBorderWidth;
|
||||||
|
auto bottom = a_top.current() + st::notifyMinHeight;
|
||||||
|
a_top = anim::ivalue(top, top);
|
||||||
|
a_bottom = anim::ivalue(bottom, bottom);
|
||||||
|
setGeometry(x(), top, width(), bottom - top);
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Widget::sendReply() {
|
||||||
|
if (!_history) return;
|
||||||
|
|
||||||
|
if (auto manager = ManagerInstance.data()) {
|
||||||
|
auto peerId = _history->peer->id;
|
||||||
|
auto msgId = _item ? _item->id : ShowAtUnreadMsgId;
|
||||||
|
manager->notificationReplied(peerId, msgId, _replyArea->getLastText());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Widget::unlinkHistory(History *history) {
|
void Widget::unlinkHistory(History *history) {
|
||||||
if (!history || history == _history) {
|
if (!history || history == _history) {
|
||||||
animHide(st::notifyFastAnim, anim::linear);
|
animHide(st::notifyFastAnim, anim::linear);
|
||||||
|
@ -358,6 +470,9 @@ void Widget::enterEvent(QEvent *e) {
|
||||||
if (auto manager = ManagerInstance.data()) {
|
if (auto manager = ManagerInstance.data()) {
|
||||||
manager->stopAllHiding();
|
manager->stopAllHiding();
|
||||||
}
|
}
|
||||||
|
if (!_replyArea) {
|
||||||
|
toggleActionButtons(true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Widget::leaveEvent(QEvent *e) {
|
void Widget::leaveEvent(QEvent *e) {
|
||||||
|
@ -365,6 +480,7 @@ void Widget::leaveEvent(QEvent *e) {
|
||||||
if (auto manager = ManagerInstance.data()) {
|
if (auto manager = ManagerInstance.data()) {
|
||||||
manager->startAllHiding();
|
manager->startAllHiding();
|
||||||
}
|
}
|
||||||
|
toggleActionButtons(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Widget::startHiding() {
|
void Widget::startHiding() {
|
||||||
|
@ -387,8 +503,27 @@ void Widget::mousePressEvent(QMouseEvent *e) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Widget::paintEvent(QPaintEvent *e) {
|
void Widget::paintEvent(QPaintEvent *e) {
|
||||||
QPainter p(this);
|
Painter p(this);
|
||||||
p.drawPixmap(0, 0, _cache);
|
p.drawPixmap(0, 0, _cache);
|
||||||
|
|
||||||
|
auto buttonsLeft = st::notifyPhotoPos.x() + st::notifyPhotoSize + st::notifyTextLeft;
|
||||||
|
auto buttonsTop = st::notifyTextTop + st::msgNameFont->height;
|
||||||
|
if (a_actionsOpacity.animating(getms())) {
|
||||||
|
p.setOpacity(a_actionsOpacity.current());
|
||||||
|
p.drawPixmapRight(0, buttonsTop, width(), _buttonsCache);
|
||||||
|
} else if (_actionsVisible) {
|
||||||
|
p.drawPixmapRight(0, buttonsTop, width(), _buttonsCache);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (height() > st::notifyMinHeight) {
|
||||||
|
auto replyAreaHeight = height() - st::notifyMinHeight - st::notifyBorderWidth;
|
||||||
|
if (replyAreaHeight > 0) {
|
||||||
|
p.fillRect(st::notifyBorderWidth, st::notifyMinHeight, width() - 2 * st::notifyBorderWidth, replyAreaHeight, st::notifyBg);
|
||||||
|
}
|
||||||
|
p.fillRect(0, st::notifyMinHeight, st::notifyBorderWidth, height() - st::notifyMinHeight, st::notifyBorder);
|
||||||
|
p.fillRect(width() - st::notifyBorderWidth, st::notifyMinHeight, st::notifyBorderWidth, height() - st::notifyMinHeight, st::notifyBorder);
|
||||||
|
p.fillRect(st::notifyBorderWidth, height() - st::notifyBorderWidth, width() - 2 * st::notifyBorderWidth, st::notifyBorderWidth, st::notifyBorder);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Widget::animHide(float64 duration, anim::transition func) {
|
void Widget::animHide(float64 duration, anim::transition func) {
|
||||||
|
@ -396,7 +531,6 @@ void Widget::animHide(float64 duration, anim::transition func) {
|
||||||
_alphaDuration = duration;
|
_alphaDuration = duration;
|
||||||
a_func = func;
|
a_func = func;
|
||||||
a_opacity.start(0);
|
a_opacity.start(0);
|
||||||
a_y.restart();
|
|
||||||
_hiding = true;
|
_hiding = true;
|
||||||
_a_appearance.start();
|
_a_appearance.start();
|
||||||
}
|
}
|
||||||
|
@ -406,7 +540,6 @@ void Widget::stopHiding() {
|
||||||
_alphaDuration = st::notifyFastAnim;
|
_alphaDuration = st::notifyFastAnim;
|
||||||
a_func = anim::linear;
|
a_func = anim::linear;
|
||||||
a_opacity.start(1);
|
a_opacity.start(1);
|
||||||
a_y.restart();
|
|
||||||
_hiding = false;
|
_hiding = false;
|
||||||
_hideTimer.stop();
|
_hideTimer.stop();
|
||||||
_a_appearance.start();
|
_a_appearance.start();
|
||||||
|
@ -418,25 +551,30 @@ void Widget::hideByTimer() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Widget::step_appearance(float64 ms, bool timer) {
|
void Widget::step_appearance(float64 ms, bool timer) {
|
||||||
float64 dtAlpha = ms / _alphaDuration, dtPos = ms / _posDuration;
|
float64 dt = ms / float64(_alphaDuration);
|
||||||
if (dtAlpha >= 1) {
|
if (dt >= 1) {
|
||||||
a_opacity.finish();
|
a_opacity.finish();
|
||||||
|
_a_appearance.stop();
|
||||||
if (_hiding) {
|
if (_hiding) {
|
||||||
_a_appearance.stop();
|
|
||||||
deleteLater();
|
deleteLater();
|
||||||
} else if (dtPos >= 1) {
|
|
||||||
_a_appearance.stop();
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
a_opacity.update(dtAlpha, a_func);
|
a_opacity.update(dt, a_func);
|
||||||
}
|
}
|
||||||
setWindowOpacity(a_opacity.current());
|
setWindowOpacity(a_opacity.current());
|
||||||
if (dtPos >= 1) {
|
update();
|
||||||
a_y.finish();
|
|
||||||
} else {
|
|
||||||
a_y.update(dtPos, anim::linear);
|
|
||||||
}
|
}
|
||||||
move(x(), a_y.current());
|
|
||||||
|
void Widget::step_movement(float64 ms, bool timer) {
|
||||||
|
float64 dt = ms / float64(st::notifyFastAnim);
|
||||||
|
if (dt >= 1) {
|
||||||
|
a_top.finish();
|
||||||
|
a_bottom.finish();
|
||||||
|
} else {
|
||||||
|
a_top.update(dt, anim::linear);
|
||||||
|
a_bottom.update(dt, anim::linear);
|
||||||
|
}
|
||||||
|
setGeometry(x(), a_top.current(), width(), a_bottom.current() - a_top.current());
|
||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -22,6 +22,10 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
|
|
||||||
#include "window/notifications_manager.h"
|
#include "window/notifications_manager.h"
|
||||||
|
|
||||||
|
namespace Ui {
|
||||||
|
class IconButton;
|
||||||
|
} // namespace Ui
|
||||||
|
|
||||||
namespace Window {
|
namespace Window {
|
||||||
namespace Notifications {
|
namespace Notifications {
|
||||||
namespace Default {
|
namespace Default {
|
||||||
|
@ -88,22 +92,20 @@ class Widget : public TWidget {
|
||||||
public:
|
public:
|
||||||
Widget(History *history, PeerData *peer, PeerData *author, HistoryItem *item, int forwardedCount, int x, int y);
|
Widget(History *history, PeerData *peer, PeerData *author, HistoryItem *item, int forwardedCount, int x, int y);
|
||||||
|
|
||||||
void step_appearance(float64 ms, bool timer);
|
|
||||||
void animHide(float64 duration, anim::transition func);
|
|
||||||
void startHiding();
|
void startHiding();
|
||||||
void stopHiding();
|
void stopHiding();
|
||||||
void moveTo(int x, int y, int index = -1);
|
void moveTop(int top, int bottom);
|
||||||
|
|
||||||
void updateNotifyDisplay();
|
void updateNotifyDisplay();
|
||||||
void updatePeerPhoto();
|
void updatePeerPhoto();
|
||||||
|
|
||||||
void itemRemoved(HistoryItem *del);
|
void itemRemoved(HistoryItem *del);
|
||||||
|
|
||||||
int index() const {
|
int isUnlinked() const {
|
||||||
return _history ? _index : -1;
|
return !_history;
|
||||||
}
|
}
|
||||||
|
|
||||||
void unlinkHistory(History *hist = 0);
|
void unlinkHistory(History *history = nullptr);
|
||||||
|
|
||||||
~Widget();
|
~Widget();
|
||||||
|
|
||||||
|
@ -116,9 +118,20 @@ protected:
|
||||||
private slots:
|
private slots:
|
||||||
void hideByTimer();
|
void hideByTimer();
|
||||||
void checkLastInput();
|
void checkLastInput();
|
||||||
|
void onReplyResize();
|
||||||
|
void onReplySubmit(bool ctrlShiftEnter);
|
||||||
|
void onReplyCancel();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void animHide(float64 duration, anim::transition func);
|
||||||
|
void step_appearance(float64 ms, bool timer);
|
||||||
|
void step_movement(float64 ms, bool timer);
|
||||||
void unlinkHistoryAndNotify();
|
void unlinkHistoryAndNotify();
|
||||||
|
void toggleActionButtons(bool visible);
|
||||||
|
void prepareActionsCache();
|
||||||
|
void actionsOpacityCallback();
|
||||||
|
void showReplyField();
|
||||||
|
void sendReply();
|
||||||
|
|
||||||
#if defined Q_OS_WIN && !defined Q_OS_WINRT
|
#if defined Q_OS_WIN && !defined Q_OS_WINRT
|
||||||
uint64 _started;
|
uint64 _started;
|
||||||
|
@ -129,17 +142,27 @@ private:
|
||||||
PeerData *_author;
|
PeerData *_author;
|
||||||
HistoryItem *_item;
|
HistoryItem *_item;
|
||||||
int _forwardedCount;
|
int _forwardedCount;
|
||||||
IconedButton _close;
|
ChildWidget<IconedButton> _close;
|
||||||
|
ChildWidget<BoxButton> _reply;
|
||||||
|
ChildWidget<InputArea> _replyArea = { nullptr };
|
||||||
|
ChildWidget<Ui::IconButton> _replySend = { nullptr };
|
||||||
QPixmap _cache;
|
QPixmap _cache;
|
||||||
float64 _alphaDuration, _posDuration;
|
float64 _alphaDuration;
|
||||||
QTimer _hideTimer, _inputTimer;
|
QTimer _hideTimer, _inputTimer;
|
||||||
bool _hiding = false;
|
bool _hiding = false;
|
||||||
int _index = 0;
|
|
||||||
|
anim::ivalue a_top, a_bottom;
|
||||||
|
Animation _a_movement;
|
||||||
|
|
||||||
anim::fvalue a_opacity;
|
anim::fvalue a_opacity;
|
||||||
anim::transition a_func;
|
anim::transition a_func;
|
||||||
anim::ivalue a_y;
|
|
||||||
Animation _a_appearance;
|
Animation _a_appearance;
|
||||||
|
|
||||||
|
int _replyPadding = 0;
|
||||||
|
bool _actionsVisible = false;
|
||||||
|
FloatAnimation a_actionsOpacity;
|
||||||
|
QPixmap _buttonsCache;
|
||||||
|
|
||||||
ImagePtr peerPhoto;
|
ImagePtr peerPhoto;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -23,6 +23,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
|
|
||||||
#include "pspecific.h"
|
#include "pspecific.h"
|
||||||
#include "mainwindow.h"
|
#include "mainwindow.h"
|
||||||
|
#include "styles/style_window.h"
|
||||||
|
|
||||||
namespace Window {
|
namespace Window {
|
||||||
namespace Notifications {
|
namespace Notifications {
|
||||||
|
|
|
@ -0,0 +1,69 @@
|
||||||
|
/*
|
||||||
|
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-2016 John Preston, https://desktop.telegram.org
|
||||||
|
*/
|
||||||
|
|
||||||
|
using "basic.style";
|
||||||
|
|
||||||
|
notifyBg: white;
|
||||||
|
notifyBorder: #f1f1f1;
|
||||||
|
notifyBorderWidth: 1px;
|
||||||
|
notifySlowHide: 4000;
|
||||||
|
notifyPhotoSize: 62px;
|
||||||
|
notifyMacPhotoSize: 64px;
|
||||||
|
notifyPhotoPos: point(9px, 9px);
|
||||||
|
notifyClosePos: point(1px, 2px);
|
||||||
|
notifyClose: iconedButton(simpleClose) {
|
||||||
|
}
|
||||||
|
notifyItemTop: 12px;
|
||||||
|
notifyTextLeft: 12px;
|
||||||
|
notifyTextTop: 7px;
|
||||||
|
notifySlowHideFunc: transition(easeInCirc);
|
||||||
|
notifyWaitShortHide: 0;
|
||||||
|
notifyWaitLongHide: 20000;
|
||||||
|
notifyFastAnim: 150;
|
||||||
|
notifyMinWidth: 316px;
|
||||||
|
notifyMinHeight: 80px;
|
||||||
|
notifyDeltaX: 6px;
|
||||||
|
notifyDeltaY: 7px;
|
||||||
|
notifyActionsDuration: 200;
|
||||||
|
|
||||||
|
notifyFadeRight: icon {{ "fade_horizontal_right", notifyBg }};
|
||||||
|
notifyReplyArea: InputArea(defaultInputArea) {
|
||||||
|
font: normalFont;
|
||||||
|
textMargins: margins(8px, 8px, 8px, 6px);
|
||||||
|
heightMin: 36px;
|
||||||
|
heightMax: 72px;
|
||||||
|
border: 0px;
|
||||||
|
borderActive: 0px;
|
||||||
|
borderError: 0px;
|
||||||
|
}
|
||||||
|
notifySendReply: IconButton {
|
||||||
|
width: 36px;
|
||||||
|
height: 36px;
|
||||||
|
|
||||||
|
opacity: 0.78;
|
||||||
|
overOpacity: 1.;
|
||||||
|
|
||||||
|
icon: icon {{ "notification_send", windowActiveBg, point(3px, 9px) }};
|
||||||
|
iconPosition: point(0px, 0px);
|
||||||
|
downIconPosition: point(0px, 1px);
|
||||||
|
|
||||||
|
duration: notifyFastAnim;
|
||||||
|
}
|
|
@ -40,6 +40,7 @@
|
||||||
'<(src_loc)/settings/settings.style',
|
'<(src_loc)/settings/settings.style',
|
||||||
'<(src_loc)/stickers/stickers.style',
|
'<(src_loc)/stickers/stickers.style',
|
||||||
'<(src_loc)/ui/widgets/widgets.style',
|
'<(src_loc)/ui/widgets/widgets.style',
|
||||||
|
'<(src_loc)/window/window.style',
|
||||||
],
|
],
|
||||||
'langpacks': [
|
'langpacks': [
|
||||||
'en',
|
'en',
|
||||||
|
@ -512,6 +513,8 @@
|
||||||
'<(src_loc)/pspecific_linux.h',
|
'<(src_loc)/pspecific_linux.h',
|
||||||
'<(src_loc)/platform/linux/linux_gdk_helper.cpp',
|
'<(src_loc)/platform/linux/linux_gdk_helper.cpp',
|
||||||
'<(src_loc)/platform/linux/linux_gdk_helper.h',
|
'<(src_loc)/platform/linux/linux_gdk_helper.h',
|
||||||
|
'<(src_loc)/platform/linux/linux_libnotify.cpp',
|
||||||
|
'<(src_loc)/platform/linux/linux_libnotify.h',
|
||||||
'<(src_loc)/platform/linux/linux_libs.cpp',
|
'<(src_loc)/platform/linux/linux_libs.cpp',
|
||||||
'<(src_loc)/platform/linux/linux_libs.h',
|
'<(src_loc)/platform/linux/linux_libs.h',
|
||||||
'<(src_loc)/platform/linux/file_dialog_linux.cpp',
|
'<(src_loc)/platform/linux/file_dialog_linux.cpp',
|
||||||
|
|
Loading…
Reference in New Issue