mirror of https://github.com/procxx/kepka.git
Notifications settings done: screen corner selection + max count.
This commit is contained in:
parent
e7b6d7b498
commit
16ce28f4d2
|
@ -98,3 +98,15 @@ notificationsBoxScreenSize: size(280px, 160px);
|
||||||
notificationsBoxScreenBg: titleBg;
|
notificationsBoxScreenBg: titleBg;
|
||||||
notificationsBoxCountLabelTop: 80px;
|
notificationsBoxCountLabelTop: 80px;
|
||||||
notificationsBoxCountTop: 30px;
|
notificationsBoxCountTop: 30px;
|
||||||
|
|
||||||
|
notificationsSampleSkip: 5px;
|
||||||
|
notificationsSampleTopSkip: 5px;
|
||||||
|
notificationsSampleBottomSkip: 5px;
|
||||||
|
notificationsSampleMargin: 2px;
|
||||||
|
|
||||||
|
notificationSampleOpacity: 0.5;
|
||||||
|
notificationSampleSize: size(64px, 16px);
|
||||||
|
notificationSampleUserpicFg: #40ace3;
|
||||||
|
notificationSampleCloseFg: #d7d7d7;
|
||||||
|
notificationSampleTextFg: #d7d7d7;
|
||||||
|
notificationSampleNameFg: #939393;
|
||||||
|
|
|
@ -25,6 +25,10 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
#include "ui/buttons/round_button.h"
|
#include "ui/buttons/round_button.h"
|
||||||
#include "ui/widgets/discrete_slider.h"
|
#include "ui/widgets/discrete_slider.h"
|
||||||
#include "styles/style_boxes.h"
|
#include "styles/style_boxes.h"
|
||||||
|
#include "styles/style_dialogs.h"
|
||||||
|
#include "styles/style_window.h"
|
||||||
|
#include "application.h"
|
||||||
|
#include "localstorage.h"
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
|
@ -32,21 +36,83 @@ constexpr int kMaxNotificationsCount = 5;
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
|
class NotificationsBox::SampleWidget : public QWidget {
|
||||||
|
public:
|
||||||
|
SampleWidget(NotificationsBox *owner, const QPixmap &cache) : QWidget(nullptr)
|
||||||
|
, _owner(owner)
|
||||||
|
, _cache(cache) {
|
||||||
|
resize(cache.width() / cache.devicePixelRatio(), cache.height() / cache.devicePixelRatio());
|
||||||
|
|
||||||
|
setAttribute(Qt::WA_MacAlwaysShowToolWindow);
|
||||||
|
setAttribute(Qt::WA_TransparentForMouseEvents);
|
||||||
|
setAttribute(Qt::WA_OpaquePaintEvent);
|
||||||
|
setWindowFlags(Qt::Tool | Qt::WindowStaysOnTopHint | Qt::FramelessWindowHint | Qt::BypassWindowManagerHint | Qt::NoDropShadowWindowHint);
|
||||||
|
|
||||||
|
setWindowOpacity(0.);
|
||||||
|
show();
|
||||||
|
}
|
||||||
|
|
||||||
|
void detach() {
|
||||||
|
_owner = nullptr;
|
||||||
|
hideFast();
|
||||||
|
}
|
||||||
|
|
||||||
|
void showFast() {
|
||||||
|
_hiding = false;
|
||||||
|
startAnimation();
|
||||||
|
}
|
||||||
|
|
||||||
|
void hideFast() {
|
||||||
|
_hiding = true;
|
||||||
|
startAnimation();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual void paintEvent(QPaintEvent *e) {
|
||||||
|
Painter p(this);
|
||||||
|
p.drawPixmap(0, 0, _cache);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
void startAnimation() {
|
||||||
|
_opacity.start([this] { animationCallback(); }, _hiding ? 1. : 0., _hiding ? 0. : 1., st::notifyFastAnim);
|
||||||
|
}
|
||||||
|
void animationCallback() {
|
||||||
|
setWindowOpacity(_opacity.current(_hiding ? 0. : 1.));
|
||||||
|
if (!_opacity.animating() && _hiding) {
|
||||||
|
if (_owner) {
|
||||||
|
_owner->removeSample(this);
|
||||||
|
}
|
||||||
|
hide();
|
||||||
|
deleteLater();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
NotificationsBox *_owner;
|
||||||
|
QPixmap _cache;
|
||||||
|
FloatAnimation _opacity;
|
||||||
|
bool _hiding = false;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
NotificationsBox::NotificationsBox() : AbstractBox()
|
NotificationsBox::NotificationsBox() : AbstractBox()
|
||||||
|
, _chosenCorner(Global::NotificationsCorner())
|
||||||
|
, _oldCount(snap(Global::NotificationsCount(), 1, kMaxNotificationsCount))
|
||||||
, _countSlider(this)
|
, _countSlider(this)
|
||||||
, _save(this, lang(lng_settings_save), st::defaultBoxButton)
|
, _done(this, lang(lng_about_done), st::defaultBoxButton) {
|
||||||
, _cancel(this, lang(lng_cancel), st::cancelBoxButton) {
|
_sampleOpacities.reserve(kMaxNotificationsCount);
|
||||||
for (int i = 0; i != kMaxNotificationsCount; ++i) {
|
for (int i = 0; i != kMaxNotificationsCount; ++i) {
|
||||||
_countSlider->addSection(QString::number(i + 1));
|
_countSlider->addSection(QString::number(i + 1));
|
||||||
|
_sampleOpacities.push_back(FloatAnimation());
|
||||||
}
|
}
|
||||||
_countSlider->setActiveSectionFast(2);
|
_countSlider->setActiveSectionFast(_oldCount - 1);
|
||||||
|
_countSlider->setSectionActivatedCallback([this] { countChanged(); });
|
||||||
|
|
||||||
setMouseTracking(true);
|
setMouseTracking(true);
|
||||||
_save->setClickedCallback([this] {
|
_done->setClickedCallback([this] { onClose(); });
|
||||||
|
|
||||||
});
|
|
||||||
connect(_cancel, SIGNAL(clicked()), this, SLOT(onClose()));
|
|
||||||
|
|
||||||
|
prepareNotificationSampleSmall();
|
||||||
|
prepareNotificationSampleLarge();
|
||||||
setMaxHeight(st::notificationsBoxHeight);
|
setMaxHeight(st::notificationsBoxHeight);
|
||||||
|
|
||||||
prepare();
|
prepare();
|
||||||
|
@ -62,17 +128,55 @@ void NotificationsBox::paintEvent(QPaintEvent *e) {
|
||||||
p.setPen(st::boxTitleFg);
|
p.setPen(st::boxTitleFg);
|
||||||
p.drawTextLeft(contentLeft, st::boxTitlePosition.y(), width(), lang(lng_settings_notifications_position));
|
p.drawTextLeft(contentLeft, st::boxTitlePosition.y(), width(), lang(lng_settings_notifications_position));
|
||||||
|
|
||||||
auto screenLeft = (width() - st::notificationsBoxScreenSize.width()) / 2;
|
|
||||||
auto screenRect = getScreenRect();
|
auto screenRect = getScreenRect();
|
||||||
p.fillRect(screenRect.x(), screenRect.y(), st::notificationsBoxScreenSize.width(), st::notificationsBoxScreenSize.height(), st::notificationsBoxScreenBg);
|
p.fillRect(screenRect.x(), screenRect.y(), st::notificationsBoxScreenSize.width(), st::notificationsBoxScreenSize.height(), st::notificationsBoxScreenBg);
|
||||||
|
|
||||||
auto monitorTop = st::notificationsBoxMonitorTop;
|
auto monitorTop = st::notificationsBoxMonitorTop;
|
||||||
st::notificationsBoxMonitor.paint(p, contentLeft, monitorTop, width());
|
st::notificationsBoxMonitor.paint(p, contentLeft, monitorTop, width());
|
||||||
|
|
||||||
|
for (int corner = 0; corner != 4; ++corner) {
|
||||||
|
auto screenCorner = static_cast<Notify::ScreenCorner>(corner);
|
||||||
|
auto isLeft = Notify::IsLeftCorner(screenCorner);
|
||||||
|
auto isTop = Notify::IsTopCorner(screenCorner);
|
||||||
|
auto sampleLeft = isLeft ? (screenRect.x() + st::notificationsSampleSkip) : (screenRect.x() + screenRect.width() - st::notificationsSampleSkip - st::notificationSampleSize.width());
|
||||||
|
auto sampleTop = isTop ? (screenRect.y() + st::notificationsSampleTopSkip) : (screenRect.y() + screenRect.height() - st::notificationsSampleBottomSkip - st::notificationSampleSize.height());
|
||||||
|
if (corner == static_cast<int>(_chosenCorner)) {
|
||||||
|
auto count = currentCount();
|
||||||
|
for (int i = 0; i != kMaxNotificationsCount; ++i) {
|
||||||
|
auto opacity = _sampleOpacities[i].current(getms(), (i < count) ? 1. : 0.);
|
||||||
|
p.setOpacity(opacity);
|
||||||
|
p.drawPixmapLeft(sampleLeft, sampleTop, width(), _notificationSampleSmall);
|
||||||
|
sampleTop += (isTop ? 1 : -1) * (st::notificationSampleSize.height() + st::notificationsSampleMargin);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
p.setOpacity(st::notificationSampleOpacity);
|
||||||
|
p.drawPixmapLeft(sampleLeft, sampleTop, width(), _notificationSampleSmall);
|
||||||
|
p.setOpacity(1.);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
auto labelTop = screenRect.y() + screenRect.height() + st::notificationsBoxCountLabelTop;
|
auto labelTop = screenRect.y() + screenRect.height() + st::notificationsBoxCountLabelTop;
|
||||||
p.drawTextLeft(contentLeft, labelTop, width(), lang(lng_settings_notifications_count));
|
p.drawTextLeft(contentLeft, labelTop, width(), lang(lng_settings_notifications_count));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void NotificationsBox::countChanged() {
|
||||||
|
auto count = currentCount();
|
||||||
|
auto moreSamples = (count > _oldCount);
|
||||||
|
auto from = moreSamples ? 0. : 1.;
|
||||||
|
auto to = moreSamples ? 1. : 0.;
|
||||||
|
auto indexDelta = moreSamples ? 1 : -1;
|
||||||
|
auto animatedDelta = moreSamples ? 0 : -1;
|
||||||
|
for (; _oldCount != count; _oldCount += indexDelta) {
|
||||||
|
_sampleOpacities[_oldCount + animatedDelta].start([this] { update(); }, from, to, st::notifyFastAnim);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentCount() != Global::NotificationsCount()) {
|
||||||
|
Global::SetNotificationsCount(currentCount());
|
||||||
|
Global::RefNotifySettingsChanged().notify(Notify::ChangeType::MaxCount);
|
||||||
|
Local::writeUserSettings();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int NotificationsBox::getContentLeft() const {
|
int NotificationsBox::getContentLeft() const {
|
||||||
return (width() - st::notificationsBoxMonitor.width()) / 2;
|
return (width() - st::notificationsBoxMonitor.width()) / 2;
|
||||||
}
|
}
|
||||||
|
@ -84,8 +188,7 @@ QRect NotificationsBox::getScreenRect() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
void NotificationsBox::resizeEvent(QResizeEvent *e) {
|
void NotificationsBox::resizeEvent(QResizeEvent *e) {
|
||||||
_save->moveToRight(st::boxButtonPadding.right(), height() - st::boxButtonPadding.bottom() - _save->height());
|
_done->moveToRight(st::boxButtonPadding.right(), height() - st::boxButtonPadding.bottom() - _done->height());
|
||||||
_cancel->moveToRight(st::boxButtonPadding.right() + _save->width() + st::boxButtonPadding.left(), _save->y());
|
|
||||||
|
|
||||||
auto screenRect = getScreenRect();
|
auto screenRect = getScreenRect();
|
||||||
auto sliderTop = screenRect.y() + screenRect.height() + st::notificationsBoxCountLabelTop + st::notificationsBoxCountTop;
|
auto sliderTop = screenRect.y() + screenRect.height() + st::notificationsBoxCountLabelTop + st::notificationsBoxCountTop;
|
||||||
|
@ -95,14 +198,201 @@ void NotificationsBox::resizeEvent(QResizeEvent *e) {
|
||||||
AbstractBox::resizeEvent(e);
|
AbstractBox::resizeEvent(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
void NotificationsBox::mousePressEvent(QMouseEvent *e) {
|
void NotificationsBox::prepareNotificationSampleSmall() {
|
||||||
|
auto width = st::notificationSampleSize.width();
|
||||||
|
auto height = st::notificationSampleSize.height();
|
||||||
|
auto sampleImage = QImage(width * cIntRetinaFactor(), height * cIntRetinaFactor(), QImage::Format_ARGB32_Premultiplied);
|
||||||
|
sampleImage.setDevicePixelRatio(cRetinaFactor());
|
||||||
|
sampleImage.fill(st::notifyBg->c);
|
||||||
|
{
|
||||||
|
Painter p(&sampleImage);
|
||||||
|
p.setPen(Qt::NoPen);
|
||||||
|
p.setRenderHint(QPainter::HighQualityAntialiasing);
|
||||||
|
|
||||||
|
auto padding = height / 8;
|
||||||
|
auto userpicSize = height - 2 * padding;
|
||||||
|
p.setBrush(st::notificationSampleUserpicFg);
|
||||||
|
p.drawEllipse(rtlrect(padding, padding, userpicSize, userpicSize, width));
|
||||||
|
|
||||||
|
auto rowLeft = height;
|
||||||
|
auto rowHeight = padding;
|
||||||
|
auto nameTop = (height - 5 * padding) / 2;
|
||||||
|
auto nameWidth = height;
|
||||||
|
p.setBrush(st::notificationSampleNameFg);
|
||||||
|
p.drawRoundedRect(rtlrect(rowLeft, nameTop, nameWidth, rowHeight, width), rowHeight / 2, rowHeight / 2);
|
||||||
|
|
||||||
|
auto rowWidth = (width - rowLeft - 3 * padding);
|
||||||
|
auto rowTop = nameTop + rowHeight + padding;
|
||||||
|
p.setBrush(st::notificationSampleTextFg);
|
||||||
|
p.drawRoundedRect(rtlrect(rowLeft, rowTop, rowWidth, rowHeight, width), rowHeight / 2, rowHeight / 2);
|
||||||
|
rowTop += rowHeight + padding;
|
||||||
|
p.drawRoundedRect(rtlrect(rowLeft, rowTop, rowWidth, rowHeight, width), rowHeight / 2, rowHeight / 2);
|
||||||
|
|
||||||
|
auto closeLeft = width - 2 * padding;
|
||||||
|
p.fillRect(rtlrect(closeLeft, padding, padding, padding, width), st::notificationSampleCloseFg);
|
||||||
|
}
|
||||||
|
_notificationSampleSmall = App::pixmapFromImageInPlace(std_::move(sampleImage));
|
||||||
|
_notificationSampleSmall.setDevicePixelRatio(cRetinaFactor());
|
||||||
|
}
|
||||||
|
|
||||||
|
void NotificationsBox::prepareNotificationSampleLarge() {
|
||||||
|
int w = st::notifyWidth, h = st::notifyMinHeight;
|
||||||
|
auto sampleImage = QImage(w * cIntRetinaFactor(), h * cIntRetinaFactor(), QImage::Format_ARGB32_Premultiplied);
|
||||||
|
sampleImage.setDevicePixelRatio(cRetinaFactor());
|
||||||
|
sampleImage.fill(st::notifyBg->c);
|
||||||
|
{
|
||||||
|
Painter p(&sampleImage);
|
||||||
|
p.fillRect(0, 0, w - st::notifyBorderWidth, st::notifyBorderWidth, st::notifyBorder->b);
|
||||||
|
p.fillRect(w - st::notifyBorderWidth, 0, st::notifyBorderWidth, h - st::notifyBorderWidth, st::notifyBorder->b);
|
||||||
|
p.fillRect(st::notifyBorderWidth, h - st::notifyBorderWidth, w - st::notifyBorderWidth, st::notifyBorderWidth, st::notifyBorder->b);
|
||||||
|
p.fillRect(0, st::notifyBorderWidth, st::notifyBorderWidth, h - st::notifyBorderWidth, st::notifyBorder->b);
|
||||||
|
|
||||||
|
static QPixmap icon = App::pixmapFromImageInPlace(App::wnd()->iconLarge().scaled(st::notifyPhotoSize, st::notifyPhotoSize, Qt::IgnoreAspectRatio, Qt::SmoothTransformation));
|
||||||
|
p.drawPixmap(st::notifyPhotoPos.x(), st::notifyPhotoPos.y(), icon);
|
||||||
|
|
||||||
|
int itemWidth = w - st::notifyPhotoPos.x() - st::notifyPhotoSize - st::notifyTextLeft - st::notifyClosePos.x() - st::notifyClose.width;
|
||||||
|
|
||||||
|
auto rectForName = rtlrect(st::notifyPhotoPos.x() + st::notifyPhotoSize + st::notifyTextLeft, st::notifyTextTop, itemWidth, st::msgNameFont->height, w);
|
||||||
|
|
||||||
|
static QString notifyText = st::dialogsTextFont->elided(lang(lng_notification_preview), itemWidth);
|
||||||
|
p.setFont(st::dialogsTextFont);
|
||||||
|
p.setPen(st::dialogsTextFgService);
|
||||||
|
p.drawText(st::notifyPhotoPos.x() + st::notifyPhotoSize + st::notifyTextLeft, st::notifyItemTop + st::msgNameFont->height + st::dialogsTextFont->ascent, notifyText);
|
||||||
|
|
||||||
|
p.setPen(st::dialogsNameFg);
|
||||||
|
p.setFont(st::msgNameFont);
|
||||||
|
|
||||||
|
static QString notifyTitle = st::msgNameFont->elided(qsl("Telegram Desktop"), rectForName.width());
|
||||||
|
p.drawText(rectForName.left(), rectForName.top() + st::msgNameFont->ascent, notifyTitle);
|
||||||
|
}
|
||||||
|
|
||||||
|
_notificationSampleLarge = App::pixmapFromImageInPlace(std_::move(sampleImage));
|
||||||
|
}
|
||||||
|
|
||||||
|
void NotificationsBox::removeSample(SampleWidget *widget) {
|
||||||
|
for (auto &samples : _cornerSamples) {
|
||||||
|
for (int i = 0, size = samples.size(); i != size; ++i) {
|
||||||
|
if (samples[i] == widget) {
|
||||||
|
for (int j = i + 1; j != size; ++j) {
|
||||||
|
samples[j]->detach();
|
||||||
|
}
|
||||||
|
samples.resize(i);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void NotificationsBox::mouseMoveEvent(QMouseEvent *e) {
|
void NotificationsBox::mouseMoveEvent(QMouseEvent *e) {
|
||||||
|
auto screenRect = getScreenRect();
|
||||||
|
auto cornerWidth = screenRect.width() / 3;
|
||||||
|
auto cornerHeight = screenRect.height() / 3;
|
||||||
|
auto topLeft = rtlrect(screenRect.x(), screenRect.y(), cornerWidth, cornerHeight, width());
|
||||||
|
auto topRight = rtlrect(screenRect.x() + screenRect.width() - cornerWidth, screenRect.y(), cornerWidth, cornerHeight, width());
|
||||||
|
auto bottomRight = rtlrect(screenRect.x() + screenRect.width() - cornerWidth, screenRect.y() + screenRect.height() - cornerHeight, cornerWidth, cornerHeight, width());
|
||||||
|
auto bottomLeft = rtlrect(screenRect.x(), screenRect.y() + screenRect.height() - cornerHeight, cornerWidth, cornerHeight, width());
|
||||||
|
if (topLeft.contains(e->pos())) {
|
||||||
|
setOverCorner(Notify::ScreenCorner::TopLeft);
|
||||||
|
} else if (topRight.contains(e->pos())) {
|
||||||
|
setOverCorner(Notify::ScreenCorner::TopRight);
|
||||||
|
} else if (bottomRight.contains(e->pos())) {
|
||||||
|
setOverCorner(Notify::ScreenCorner::BottomRight);
|
||||||
|
} else if (bottomLeft.contains(e->pos())) {
|
||||||
|
setOverCorner(Notify::ScreenCorner::BottomLeft);
|
||||||
|
} else {
|
||||||
|
clearOverCorner();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void NotificationsBox::leaveEvent(QEvent *e) {
|
||||||
|
clearOverCorner();
|
||||||
|
}
|
||||||
|
|
||||||
|
void NotificationsBox::setOverCorner(Notify::ScreenCorner corner) {
|
||||||
|
if (_isOverCorner) {
|
||||||
|
if (corner == _overCorner) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
for_const (auto widget, _cornerSamples[static_cast<int>(_overCorner)]) {
|
||||||
|
widget->hideFast();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
_isOverCorner = true;
|
||||||
|
setCursor(style::cur_pointer);
|
||||||
|
Global::SetNotificationsDemoIsShown(true);
|
||||||
|
Global::RefNotifySettingsChanged().notify(Notify::ChangeType::DemoIsShown);
|
||||||
|
}
|
||||||
|
_overCorner = corner;
|
||||||
|
|
||||||
|
auto &samples = _cornerSamples[static_cast<int>(_overCorner)];
|
||||||
|
auto samplesAlready = samples.size();
|
||||||
|
auto samplesNeeded = currentCount();
|
||||||
|
auto samplesLeave = qMin(samplesAlready, samplesNeeded);
|
||||||
|
for (int i = 0; i != samplesLeave; ++i) {
|
||||||
|
samples[i]->showFast();
|
||||||
|
}
|
||||||
|
if (samplesNeeded > samplesLeave) {
|
||||||
|
auto r = psDesktopRect();
|
||||||
|
auto isLeft = Notify::IsLeftCorner(_overCorner);
|
||||||
|
auto isTop = Notify::IsTopCorner(_overCorner);
|
||||||
|
auto sampleLeft = (isLeft == rtl()) ? (r.x() + r.width() - st::notifyWidth - st::notifyDeltaX) : (r.x() + st::notifyDeltaX);
|
||||||
|
auto sampleTop = isTop ? (r.y() + st::notifyDeltaY) : (r.y() + r.height() - st::notifyDeltaY - st::notifyMinHeight);
|
||||||
|
for (int i = samplesLeave; i != samplesNeeded; ++i) {
|
||||||
|
auto widget = std_::make_unique<SampleWidget>(this, _notificationSampleLarge);
|
||||||
|
widget->move(sampleLeft, sampleTop + (isTop ? 1 : -1) * i * (st::notifyMinHeight + st::notifyDeltaY));
|
||||||
|
widget->showFast();
|
||||||
|
samples.push_back(widget.release());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for (int i = samplesLeave; i != samplesAlready; ++i) {
|
||||||
|
samples[i]->hideFast();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void NotificationsBox::clearOverCorner() {
|
||||||
|
if (_isOverCorner) {
|
||||||
|
_isOverCorner = false;
|
||||||
|
setCursor(style::cur_default);
|
||||||
|
Global::SetNotificationsDemoIsShown(false);
|
||||||
|
Global::RefNotifySettingsChanged().notify(Notify::ChangeType::DemoIsShown);
|
||||||
|
|
||||||
|
for_const (auto &samples, _cornerSamples) {
|
||||||
|
for_const (auto widget, samples) {
|
||||||
|
widget->hideFast();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int NotificationsBox::currentCount() const {
|
||||||
|
return _countSlider->activeSection() + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void NotificationsBox::mousePressEvent(QMouseEvent *e) {
|
||||||
|
_isDownCorner = _isOverCorner;
|
||||||
|
_downCorner = _overCorner;
|
||||||
}
|
}
|
||||||
|
|
||||||
void NotificationsBox::mouseReleaseEvent(QMouseEvent *e) {
|
void NotificationsBox::mouseReleaseEvent(QMouseEvent *e) {
|
||||||
|
auto isDownCorner = createAndSwap(_isDownCorner);
|
||||||
|
if (isDownCorner && _isOverCorner && _downCorner == _overCorner && _downCorner != _chosenCorner) {
|
||||||
|
_chosenCorner = _downCorner;
|
||||||
|
update();
|
||||||
|
|
||||||
|
if (_chosenCorner != Global::NotificationsCorner()) {
|
||||||
|
Global::SetNotificationsCorner(_chosenCorner);
|
||||||
|
Global::RefNotifySettingsChanged().notify(Notify::ChangeType::Corner);
|
||||||
|
Local::writeUserSettings();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
NotificationsBox::~NotificationsBox() {
|
||||||
|
for_const (auto &samples, _cornerSamples) {
|
||||||
|
for_const (auto widget, samples) {
|
||||||
|
widget->detach();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
clearOverCorner();
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,23 +30,48 @@ class DiscreteSlider;
|
||||||
} // namespace Ui
|
} // namespace Ui
|
||||||
|
|
||||||
class NotificationsBox : public AbstractBox {
|
class NotificationsBox : public AbstractBox {
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
NotificationsBox();
|
NotificationsBox();
|
||||||
|
~NotificationsBox();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void paintEvent(QPaintEvent *e) override;
|
void paintEvent(QPaintEvent *e) override;
|
||||||
void resizeEvent(QResizeEvent *e) override;
|
void resizeEvent(QResizeEvent *e) override;
|
||||||
void mousePressEvent(QMouseEvent *e) override;
|
void mousePressEvent(QMouseEvent *e) override;
|
||||||
void mouseMoveEvent(QMouseEvent *e) override;
|
void mouseMoveEvent(QMouseEvent *e) override;
|
||||||
|
void leaveEvent(QEvent *e) override;
|
||||||
void mouseReleaseEvent(QMouseEvent *e) override;
|
void mouseReleaseEvent(QMouseEvent *e) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
using ScreenCorner = Notify::ScreenCorner;
|
||||||
|
void countChanged();
|
||||||
|
void setOverCorner(ScreenCorner corner);
|
||||||
|
void clearOverCorner();
|
||||||
|
|
||||||
|
class SampleWidget;
|
||||||
|
void removeSample(SampleWidget *widget);
|
||||||
|
|
||||||
|
int currentCount() const;
|
||||||
|
|
||||||
QRect getScreenRect() const;
|
QRect getScreenRect() const;
|
||||||
int getContentLeft() const;
|
int getContentLeft() const;
|
||||||
|
void prepareNotificationSampleSmall();
|
||||||
|
void prepareNotificationSampleLarge();
|
||||||
|
|
||||||
|
QPixmap _notificationSampleSmall;
|
||||||
|
QPixmap _notificationSampleLarge;
|
||||||
|
ScreenCorner _chosenCorner;
|
||||||
|
std_::vector_of_moveable<FloatAnimation> _sampleOpacities;
|
||||||
|
|
||||||
|
bool _isOverCorner = false;
|
||||||
|
ScreenCorner _overCorner = ScreenCorner::TopLeft;
|
||||||
|
bool _isDownCorner = false;
|
||||||
|
ScreenCorner _downCorner = ScreenCorner::TopLeft;
|
||||||
|
|
||||||
|
int _oldCount;
|
||||||
ChildWidget<Ui::DiscreteSlider> _countSlider;
|
ChildWidget<Ui::DiscreteSlider> _countSlider;
|
||||||
ChildWidget<BoxButton> _save, _cancel;
|
ChildWidget<BoxButton> _done;
|
||||||
|
|
||||||
|
QVector<SampleWidget*> _cornerSamples[4];
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -635,6 +635,9 @@ struct Data {
|
||||||
bool IncludeMuted = true;
|
bool IncludeMuted = true;
|
||||||
DBINotifyView NotifyView = dbinvShowPreview;
|
DBINotifyView NotifyView = dbinvShowPreview;
|
||||||
bool NativeNotifications = false;
|
bool NativeNotifications = false;
|
||||||
|
int NotificationsCount = 3;
|
||||||
|
Notify::ScreenCorner NotificationsCorner = Notify::ScreenCorner::BottomRight;
|
||||||
|
bool NotificationsDemoIsShown = false;
|
||||||
base::Observable<Notify::ChangeType> NotifySettingsChanged;
|
base::Observable<Notify::ChangeType> NotifySettingsChanged;
|
||||||
|
|
||||||
DBIConnectionType ConnectionType = dbictAuto;
|
DBIConnectionType ConnectionType = dbictAuto;
|
||||||
|
@ -742,6 +745,9 @@ DefineVar(Global, bool, RestoreSoundNotifyFromTray);
|
||||||
DefineVar(Global, bool, IncludeMuted);
|
DefineVar(Global, bool, IncludeMuted);
|
||||||
DefineVar(Global, DBINotifyView, NotifyView);
|
DefineVar(Global, DBINotifyView, NotifyView);
|
||||||
DefineVar(Global, bool, NativeNotifications);
|
DefineVar(Global, bool, NativeNotifications);
|
||||||
|
DefineVar(Global, int, NotificationsCount);
|
||||||
|
DefineVar(Global, Notify::ScreenCorner, NotificationsCorner);
|
||||||
|
DefineVar(Global, bool, NotificationsDemoIsShown);
|
||||||
DefineRefVar(Global, base::Observable<Notify::ChangeType>, NotifySettingsChanged);
|
DefineRefVar(Global, base::Observable<Notify::ChangeType>, NotifySettingsChanged);
|
||||||
|
|
||||||
DefineVar(Global, DBIConnectionType, ConnectionType);
|
DefineVar(Global, DBIConnectionType, ConnectionType);
|
||||||
|
|
|
@ -149,8 +149,26 @@ enum class ChangeType {
|
||||||
IncludeMuted,
|
IncludeMuted,
|
||||||
DesktopEnabled,
|
DesktopEnabled,
|
||||||
ViewParams,
|
ViewParams,
|
||||||
|
MaxCount,
|
||||||
|
Corner,
|
||||||
|
DemoIsShown,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum class ScreenCorner {
|
||||||
|
TopLeft = 0,
|
||||||
|
TopRight = 1,
|
||||||
|
BottomRight = 2,
|
||||||
|
BottomLeft = 3,
|
||||||
|
};
|
||||||
|
|
||||||
|
inline bool IsLeftCorner(ScreenCorner corner) {
|
||||||
|
return (corner == ScreenCorner::TopLeft) || (corner == ScreenCorner::BottomLeft);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool IsTopCorner(ScreenCorner corner) {
|
||||||
|
return (corner == ScreenCorner::TopLeft) || (corner == ScreenCorner::TopRight);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace Notify
|
} // namespace Notify
|
||||||
|
|
||||||
#define DeclareReadOnlyVar(Type, Name) const Type &Name();
|
#define DeclareReadOnlyVar(Type, Name) const Type &Name();
|
||||||
|
@ -308,6 +326,9 @@ DeclareVar(bool, RestoreSoundNotifyFromTray);
|
||||||
DeclareVar(bool, IncludeMuted);
|
DeclareVar(bool, IncludeMuted);
|
||||||
DeclareVar(DBINotifyView, NotifyView);
|
DeclareVar(DBINotifyView, NotifyView);
|
||||||
DeclareVar(bool, NativeNotifications);
|
DeclareVar(bool, NativeNotifications);
|
||||||
|
DeclareVar(int, NotificationsCount);
|
||||||
|
DeclareVar(Notify::ScreenCorner, NotificationsCorner);
|
||||||
|
DeclareVar(bool, NotificationsDemoIsShown);
|
||||||
DeclareRefVar(base::Observable<Notify::ChangeType>, NotifySettingsChanged);
|
DeclareRefVar(base::Observable<Notify::ChangeType>, NotifySettingsChanged);
|
||||||
|
|
||||||
DeclareVar(DBIConnectionType, ConnectionType);
|
DeclareVar(DBIConnectionType, ConnectionType);
|
||||||
|
|
|
@ -549,6 +549,8 @@ enum {
|
||||||
dbiVideoVolume = 0x42,
|
dbiVideoVolume = 0x42,
|
||||||
dbiStickersRecentLimit = 0x43,
|
dbiStickersRecentLimit = 0x43,
|
||||||
dbiNativeNotifications = 0x44,
|
dbiNativeNotifications = 0x44,
|
||||||
|
dbiNotificationsCount = 0x45,
|
||||||
|
dbiNotificationsCorner = 0x46,
|
||||||
|
|
||||||
dbiEncryptedWithSalt = 333,
|
dbiEncryptedWithSalt = 333,
|
||||||
dbiEncrypted = 444,
|
dbiEncrypted = 444,
|
||||||
|
@ -1004,6 +1006,22 @@ bool _readSetting(quint32 blockId, QDataStream &stream, int version) {
|
||||||
Global::SetNativeNotifications(v == 1);
|
Global::SetNativeNotifications(v == 1);
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
|
case dbiNotificationsCount: {
|
||||||
|
qint32 v;
|
||||||
|
stream >> v;
|
||||||
|
if (!_checkStreamStatus(stream)) return false;
|
||||||
|
|
||||||
|
Global::SetNotificationsCount((v > 0 ? v : 3));
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case dbiNotificationsCorner: {
|
||||||
|
qint32 v;
|
||||||
|
stream >> v;
|
||||||
|
if (!_checkStreamStatus(stream)) return false;
|
||||||
|
|
||||||
|
Global::SetNotificationsCorner(static_cast<Notify::ScreenCorner>((v >= 0 && v < 4) ? v : 2));
|
||||||
|
} break;
|
||||||
|
|
||||||
case dbiWorkMode: {
|
case dbiWorkMode: {
|
||||||
qint32 v;
|
qint32 v;
|
||||||
stream >> v;
|
stream >> v;
|
||||||
|
@ -1572,7 +1590,7 @@ void _writeUserSettings() {
|
||||||
_writeMap(WriteMapFast);
|
_writeMap(WriteMapFast);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32 size = 18 * (sizeof(quint32) + sizeof(qint32));
|
uint32 size = 20 * (sizeof(quint32) + sizeof(qint32));
|
||||||
size += sizeof(quint32) + Serialize::stringSize(Global::AskDownloadPath() ? QString() : Global::DownloadPath()) + Serialize::bytearraySize(Global::AskDownloadPath() ? QByteArray() : Global::DownloadPathBookmark());
|
size += sizeof(quint32) + Serialize::stringSize(Global::AskDownloadPath() ? QString() : Global::DownloadPath()) + Serialize::bytearraySize(Global::AskDownloadPath() ? QByteArray() : Global::DownloadPathBookmark());
|
||||||
size += sizeof(quint32) + sizeof(qint32) + (cRecentEmojisPreload().isEmpty() ? cGetRecentEmojis().size() : cRecentEmojisPreload().size()) * (sizeof(uint64) + sizeof(ushort));
|
size += sizeof(quint32) + sizeof(qint32) + (cRecentEmojisPreload().isEmpty() ? cGetRecentEmojis().size() : cRecentEmojisPreload().size()) * (sizeof(uint64) + sizeof(ushort));
|
||||||
size += sizeof(quint32) + sizeof(qint32) + cEmojiVariants().size() * (sizeof(uint32) + sizeof(uint64));
|
size += sizeof(quint32) + sizeof(qint32) + cEmojiVariants().size() * (sizeof(uint32) + sizeof(uint64));
|
||||||
|
@ -1597,6 +1615,8 @@ void _writeUserSettings() {
|
||||||
data.stream << quint32(dbiDesktopNotify) << qint32(Global::DesktopNotify());
|
data.stream << quint32(dbiDesktopNotify) << qint32(Global::DesktopNotify());
|
||||||
data.stream << quint32(dbiNotifyView) << qint32(Global::NotifyView());
|
data.stream << quint32(dbiNotifyView) << qint32(Global::NotifyView());
|
||||||
data.stream << quint32(dbiNativeNotifications) << qint32(Global::NativeNotifications());
|
data.stream << quint32(dbiNativeNotifications) << qint32(Global::NativeNotifications());
|
||||||
|
data.stream << quint32(dbiNotificationsCount) << qint32(Global::NotificationsCount());
|
||||||
|
data.stream << quint32(dbiNotificationsCorner) << qint32(Global::NotificationsCorner());
|
||||||
data.stream << quint32(dbiAskDownloadPath) << qint32(Global::AskDownloadPath());
|
data.stream << quint32(dbiAskDownloadPath) << qint32(Global::AskDownloadPath());
|
||||||
data.stream << quint32(dbiDownloadPath) << (Global::AskDownloadPath() ? QString() : Global::DownloadPath()) << (Global::AskDownloadPath() ? QByteArray() : Global::DownloadPathBookmark());
|
data.stream << quint32(dbiDownloadPath) << (Global::AskDownloadPath() ? QString() : Global::DownloadPath()) << (Global::AskDownloadPath() ? QByteArray() : Global::DownloadPathBookmark());
|
||||||
data.stream << quint32(dbiCompressPastedImage) << qint32(cCompressPastedImage());
|
data.stream << quint32(dbiCompressPastedImage) << qint32(cCompressPastedImage());
|
||||||
|
|
|
@ -59,8 +59,7 @@ void ScaleWidget::createControls() {
|
||||||
_scale->addSection(scaleLabel(dbisOneAndHalf));
|
_scale->addSection(scaleLabel(dbisOneAndHalf));
|
||||||
_scale->addSection(scaleLabel(dbisTwo));
|
_scale->addSection(scaleLabel(dbisTwo));
|
||||||
_scale->setActiveSectionFast(cEvalScale(cConfigScale()) - 1);
|
_scale->setActiveSectionFast(cEvalScale(cConfigScale()) - 1);
|
||||||
|
_scale->setSectionActivatedCallback([this] { scaleChanged(); });
|
||||||
connect(_scale, SIGNAL(sectionActivated()), this, SLOT(onSectionActivated()));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ScaleWidget::onAutoChosen() {
|
void ScaleWidget::onAutoChosen() {
|
||||||
|
@ -102,7 +101,7 @@ void ScaleWidget::setScale(DBIScale newScale) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ScaleWidget::onSectionActivated() {
|
void ScaleWidget::scaleChanged() {
|
||||||
auto newScale = dbisAuto;
|
auto newScale = dbisAuto;
|
||||||
switch (_scale->activeSection()) {
|
switch (_scale->activeSection()) {
|
||||||
case 0: newScale = dbisOne; break;
|
case 0: newScale = dbisOne; break;
|
||||||
|
|
|
@ -38,10 +38,10 @@ public:
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void onAutoChosen();
|
void onAutoChosen();
|
||||||
void onSectionActivated();
|
|
||||||
void onRestartNow();
|
void onRestartNow();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void scaleChanged();
|
||||||
void createControls();
|
void createControls();
|
||||||
void setScale(DBIScale newScale);
|
void setScale(DBIScale newScale);
|
||||||
|
|
||||||
|
|
|
@ -30,11 +30,17 @@ DiscreteSlider::DiscreteSlider(QWidget *parent) : TWidget(parent)
|
||||||
setCursor(style::cur_pointer);
|
setCursor(style::cur_pointer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DiscreteSlider::setSectionActivatedCallback(SectionActivatedCallback &&callback) {
|
||||||
|
_callback = std_::move(callback);
|
||||||
|
}
|
||||||
|
|
||||||
void DiscreteSlider::setActiveSection(int index) {
|
void DiscreteSlider::setActiveSection(int index) {
|
||||||
setSelectedSection(index);
|
setSelectedSection(index);
|
||||||
if (_activeIndex != index) {
|
if (_activeIndex != index) {
|
||||||
_activeIndex = index;
|
_activeIndex = index;
|
||||||
emit sectionActivated();
|
if (_callback) {
|
||||||
|
_callback();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -23,17 +23,19 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
namespace Ui {
|
namespace Ui {
|
||||||
|
|
||||||
class DiscreteSlider : public TWidget {
|
class DiscreteSlider : public TWidget {
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
DiscreteSlider(QWidget *parent);
|
DiscreteSlider(QWidget *parent);
|
||||||
|
|
||||||
|
void addSection(const QString &label);
|
||||||
|
|
||||||
int activeSection() const {
|
int activeSection() const {
|
||||||
return _activeIndex;
|
return _activeIndex;
|
||||||
}
|
}
|
||||||
void setActiveSection(int index);
|
void setActiveSection(int index);
|
||||||
void setActiveSectionFast(int index);
|
void setActiveSectionFast(int index);
|
||||||
void addSection(const QString &label);
|
|
||||||
|
using SectionActivatedCallback = base::lambda_unique<void()>;
|
||||||
|
void setSectionActivatedCallback(SectionActivatedCallback &&callback);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void paintEvent(QPaintEvent *e) override;
|
void paintEvent(QPaintEvent *e) override;
|
||||||
|
@ -43,9 +45,6 @@ protected:
|
||||||
|
|
||||||
int resizeGetHeight(int newWidth) override;
|
int resizeGetHeight(int newWidth) override;
|
||||||
|
|
||||||
signals:
|
|
||||||
void sectionActivated();
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void resizeSections(int newWidth);
|
void resizeSections(int newWidth);
|
||||||
int getIndexFromPosition(QPoint pos);
|
int getIndexFromPosition(QPoint pos);
|
||||||
|
@ -62,6 +61,8 @@ private:
|
||||||
QList<Section> _sections;
|
QList<Section> _sections;
|
||||||
int _activeIndex = 0;
|
int _activeIndex = 0;
|
||||||
|
|
||||||
|
SectionActivatedCallback _callback;
|
||||||
|
|
||||||
bool _pressed = false;
|
bool _pressed = false;
|
||||||
int _selected = 0;
|
int _selected = 0;
|
||||||
anim::ivalue a_left = { 0 };
|
anim::ivalue a_left = { 0 };
|
||||||
|
|
|
@ -34,25 +34,26 @@ namespace Notifications {
|
||||||
namespace Default {
|
namespace Default {
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
// 3 desktop notifies at the same time.
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
int notificationMaxHeight() {
|
int notificationMaxHeight() {
|
||||||
return st::notifyMinHeight + st::notifyReplyArea.heightMax + st::notifyBorderWidth;
|
return st::notifyMinHeight + st::notifyReplyArea.heightMax + st::notifyBorderWidth;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QPoint notificationStartPosition() {
|
||||||
|
auto r = psDesktopRect();
|
||||||
|
auto isLeft = Notify::IsLeftCorner(Global::NotificationsCorner());
|
||||||
|
auto isTop = Notify::IsTopCorner(Global::NotificationsCorner());
|
||||||
|
auto x = (isLeft == rtl()) ? (r.x() + r.width() - st::notifyWidth - st::notifyDeltaX) : (r.x() + st::notifyDeltaX);
|
||||||
|
auto y = isTop ? r.y() : (r.y() + r.height());
|
||||||
|
return QPoint(x, y);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal::Widget::Direction notificationShiftDirection() {
|
||||||
|
auto isTop = Notify::IsTopCorner(Global::NotificationsCorner());
|
||||||
|
return isTop ? internal::Widget::Direction::Down : internal::Widget::Direction::Up;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
void start() {
|
void start() {
|
||||||
|
@ -73,13 +74,69 @@ Manager::Manager() {
|
||||||
notification->updatePeerPhoto();
|
notification->updatePeerPhoto();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
subscribe(Global::RefNotifySettingsChanged(), [this](const Notify::ChangeType &change) {
|
||||||
|
settingsChanged(change);
|
||||||
|
});
|
||||||
_inputCheckTimer.setTimeoutHandler([this] { checkLastInput(); });
|
_inputCheckTimer.setTimeoutHandler([this] { checkLastInput(); });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Manager::hasReplyingNotification() const {
|
||||||
|
for_const (auto notification, _notifications) {
|
||||||
|
if (notification->isReplying()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Manager::settingsChanged(const Notify::ChangeType &change) {
|
||||||
|
if (change == Notify::ChangeType::Corner) {
|
||||||
|
auto startPosition = notificationStartPosition();
|
||||||
|
auto shiftDirection = notificationShiftDirection();
|
||||||
|
for_const (auto notification, _notifications) {
|
||||||
|
notification->updatePosition(startPosition, shiftDirection);
|
||||||
|
}
|
||||||
|
if (_hideAll) {
|
||||||
|
_hideAll->updatePosition(startPosition, shiftDirection);
|
||||||
|
}
|
||||||
|
} else if (change == Notify::ChangeType::MaxCount) {
|
||||||
|
int allow = Global::NotificationsCount();
|
||||||
|
for (int i = _notifications.size(); i != 0;) {
|
||||||
|
auto notification = _notifications[--i];
|
||||||
|
if (notification->isUnlinked()) continue;
|
||||||
|
if (--allow < 0) {
|
||||||
|
notification->unlinkHistory();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (allow > 0) {
|
||||||
|
for (int i = 0; i != allow; ++i) {
|
||||||
|
showNextFromQueue();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (change == Notify::ChangeType::DemoIsShown) {
|
||||||
|
auto demoIsShown = Global::NotificationsDemoIsShown();
|
||||||
|
_demoMasterOpacity.start([this] { demoMasterOpacityCallback(); }, demoIsShown ? 1. : 0., demoIsShown ? 0. : 1., st::notifyFastAnim);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Manager::demoMasterOpacityCallback() {
|
||||||
|
for_const (auto notification, _notifications) {
|
||||||
|
notification->updateOpacity();
|
||||||
|
}
|
||||||
|
if (_hideAll) {
|
||||||
|
_hideAll->updateOpacity();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
float64 Manager::demoMasterOpacity() const {
|
||||||
|
return _demoMasterOpacity.current(Global::NotificationsDemoIsShown() ? 0. : 1.);
|
||||||
|
}
|
||||||
|
|
||||||
void Manager::checkLastInput() {
|
void Manager::checkLastInput() {
|
||||||
|
auto replying = hasReplyingNotification();
|
||||||
auto waiting = false;
|
auto waiting = false;
|
||||||
for_const (auto notification, _notifications) {
|
for_const (auto notification, _notifications) {
|
||||||
if (!notification->checkLastInput()) {
|
if (!notification->checkLastInput(replying)) {
|
||||||
waiting = true;
|
waiting = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -89,14 +146,7 @@ void Manager::checkLastInput() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Manager::startAllHiding() {
|
void Manager::startAllHiding() {
|
||||||
auto hasReplyingNotification = false;
|
if (!hasReplyingNotification()) {
|
||||||
for_const (auto notification, _notifications) {
|
|
||||||
if (notification->isReplying()) {
|
|
||||||
hasReplyingNotification = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!hasReplyingNotification) {
|
|
||||||
int notHidingCount = 0;
|
int notHidingCount = 0;
|
||||||
for_const (auto notification, _notifications) {
|
for_const (auto notification, _notifications) {
|
||||||
if (notification->isShowing()) {
|
if (notification->isShowing()) {
|
||||||
|
@ -123,13 +173,15 @@ void Manager::stopAllHiding() {
|
||||||
|
|
||||||
void Manager::showNextFromQueue() {
|
void Manager::showNextFromQueue() {
|
||||||
if (!_queuedNotifications.isEmpty()) {
|
if (!_queuedNotifications.isEmpty()) {
|
||||||
int count = kNotifyWindowsCount;
|
int count = Global::NotificationsCount();
|
||||||
for_const (auto notification, _notifications) {
|
for_const (auto notification, _notifications) {
|
||||||
if (notification->isUnlinked()) continue;
|
if (notification->isUnlinked()) continue;
|
||||||
--count;
|
--count;
|
||||||
}
|
}
|
||||||
if (count > 0) {
|
if (count > 0) {
|
||||||
auto position = notificationStartPosition();
|
auto startPosition = notificationStartPosition();
|
||||||
|
auto startShift = 0;
|
||||||
|
auto shiftDirection = notificationShiftDirection();
|
||||||
do {
|
do {
|
||||||
auto queued = _queuedNotifications.front();
|
auto queued = _queuedNotifications.front();
|
||||||
_queuedNotifications.pop_front();
|
_queuedNotifications.pop_front();
|
||||||
|
@ -140,7 +192,7 @@ void Manager::showNextFromQueue() {
|
||||||
queued.author,
|
queued.author,
|
||||||
queued.item,
|
queued.item,
|
||||||
queued.forwardedCount,
|
queued.forwardedCount,
|
||||||
position);
|
startPosition, startShift, shiftDirection);
|
||||||
Platform::Notifications::defaultNotificationShown(notification.get());
|
Platform::Notifications::defaultNotificationShown(notification.get());
|
||||||
_notifications.push_back(notification.release());
|
_notifications.push_back(notification.release());
|
||||||
--count;
|
--count;
|
||||||
|
@ -155,27 +207,18 @@ void Manager::showNextFromQueue() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QPoint Manager::notificationStartPosition() const {
|
|
||||||
auto r = psDesktopRect();
|
|
||||||
auto x = r.x() + r.width() - notificationWidth() - st::notifyDeltaX;
|
|
||||||
auto y = r.y() + r.height();
|
|
||||||
return QPoint(x, y);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Manager::moveWidgets() {
|
void Manager::moveWidgets() {
|
||||||
auto startPosition = notificationStartPosition();
|
auto shift = st::notifyDeltaY;
|
||||||
auto top = startPosition.y();
|
int lastShift = 0, lastShiftCurrent = 0, count = 0;
|
||||||
int firstLeft = 0, firstTopCurrent = 0, firstTop = 0, count = 0;
|
|
||||||
for (int i = _notifications.size(); i != 0;) {
|
for (int i = _notifications.size(); i != 0;) {
|
||||||
auto notification = _notifications[--i];
|
auto notification = _notifications[--i];
|
||||||
if (notification->isUnlinked()) continue;
|
if (notification->isUnlinked()) continue;
|
||||||
|
|
||||||
top -= notification->height() + st::notifyDeltaY;
|
notification->changeShift(shift);
|
||||||
notification->moveTop(top);
|
shift += notification->height() + st::notifyDeltaY;
|
||||||
|
|
||||||
firstLeft = notification->x();
|
lastShiftCurrent = notification->currentShift();
|
||||||
firstTopCurrent = notification->y();
|
lastShift = shift;
|
||||||
firstTop = top;
|
|
||||||
|
|
||||||
++count;
|
++count;
|
||||||
}
|
}
|
||||||
|
@ -183,9 +226,9 @@ void Manager::moveWidgets() {
|
||||||
if (count > 1 || !_queuedNotifications.isEmpty()) {
|
if (count > 1 || !_queuedNotifications.isEmpty()) {
|
||||||
auto deltaY = st::notifyHideAll.height + st::notifyDeltaY;
|
auto deltaY = st::notifyHideAll.height + st::notifyDeltaY;
|
||||||
if (!_hideAll) {
|
if (!_hideAll) {
|
||||||
_hideAll = new HideAllButton(QPoint(firstLeft, firstTopCurrent - deltaY));
|
_hideAll = new HideAllButton(notificationStartPosition(), lastShiftCurrent, notificationShiftDirection());
|
||||||
}
|
}
|
||||||
_hideAll->moveTop(firstTop - deltaY);
|
_hideAll->changeShift(lastShift);
|
||||||
_hideAll->stopHiding();
|
_hideAll->stopHiding();
|
||||||
} else if (_hideAll) {
|
} else if (_hideAll) {
|
||||||
_hideAll->startHidingFast();
|
_hideAll->startHidingFast();
|
||||||
|
@ -196,18 +239,18 @@ void Manager::changeNotificationHeight(Notification *notification, int newHeight
|
||||||
auto deltaHeight = newHeight - notification->height();
|
auto deltaHeight = newHeight - notification->height();
|
||||||
if (!deltaHeight) return;
|
if (!deltaHeight) return;
|
||||||
|
|
||||||
notification->addToHeight(deltaHeight, Notification::AddToHeight::Above);
|
notification->addToHeight(deltaHeight);
|
||||||
auto index = _notifications.indexOf(notification);
|
auto index = _notifications.indexOf(notification);
|
||||||
if (index > 0) {
|
if (index > 0) {
|
||||||
for (int i = 0; i != index; ++i) {
|
for (int i = 0; i != index; ++i) {
|
||||||
auto notification = _notifications[i];
|
auto notification = _notifications[i];
|
||||||
if (notification->isUnlinked()) continue;
|
if (notification->isUnlinked()) continue;
|
||||||
|
|
||||||
notification->addToTop(-deltaHeight);
|
notification->addToShift(deltaHeight);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (_hideAll) {
|
if (_hideAll) {
|
||||||
_hideAll->addToTop(-deltaHeight);
|
_hideAll->addToShift(deltaHeight);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -293,57 +336,56 @@ Manager::~Manager() {
|
||||||
|
|
||||||
namespace internal {
|
namespace internal {
|
||||||
|
|
||||||
Widget::Widget(QPoint position) : TWidget(nullptr)
|
Widget::Widget(QPoint startPosition, int shift, Direction shiftDirection) : TWidget(nullptr)
|
||||||
, _opacityDuration(st::notifyFastAnim)
|
, _opacityDuration(st::notifyFastAnim)
|
||||||
, a_opacity(0, 1)
|
, a_opacity(0, 1)
|
||||||
, a_func(anim::linear)
|
, a_func(anim::linear)
|
||||||
, _a_appearance(animation(this, &Widget::step_appearance))
|
, _a_opacity(animation(this, &Widget::step_opacity))
|
||||||
, a_top(position.y())
|
, _startPosition(startPosition)
|
||||||
, _a_movement(animation(this, &Notification::step_movement)) {
|
, _direction(shiftDirection)
|
||||||
|
, a_shift(shift)
|
||||||
|
, _a_shift(animation(this, &Widget::step_shift)) {
|
||||||
setWindowOpacity(0.);
|
setWindowOpacity(0.);
|
||||||
|
|
||||||
setAttribute(Qt::WA_OpaquePaintEvent);
|
setAttribute(Qt::WA_OpaquePaintEvent);
|
||||||
|
|
||||||
setWindowFlags(Qt::Tool | Qt::WindowStaysOnTopHint | Qt::FramelessWindowHint | Qt::BypassWindowManagerHint | Qt::NoDropShadowWindowHint);
|
setWindowFlags(Qt::Tool | Qt::WindowStaysOnTopHint | Qt::FramelessWindowHint | Qt::BypassWindowManagerHint | Qt::NoDropShadowWindowHint);
|
||||||
setAttribute(Qt::WA_MacAlwaysShowToolWindow);
|
setAttribute(Qt::WA_MacAlwaysShowToolWindow);
|
||||||
setAttribute(Qt::WA_NoSystemBackground, true);
|
|
||||||
setAttribute(Qt::WA_TranslucentBackground, true);
|
|
||||||
|
|
||||||
_a_appearance.start();
|
_a_opacity.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Widget::step_appearance(float64 ms, bool timer) {
|
void Widget::step_opacity(float64 ms, bool timer) {
|
||||||
float64 dt = ms / float64(_opacityDuration);
|
float64 dt = ms / float64(_opacityDuration);
|
||||||
if (dt >= 1) {
|
if (dt >= 1) {
|
||||||
a_opacity.finish();
|
a_opacity.finish();
|
||||||
_a_appearance.stop();
|
_a_opacity.stop();
|
||||||
if (_hiding) {
|
if (_hiding) {
|
||||||
deleteLater();
|
deleteLater();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
a_opacity.update(dt, a_func);
|
a_opacity.update(dt, a_func);
|
||||||
}
|
}
|
||||||
setWindowOpacity(a_opacity.current());
|
updateOpacity();
|
||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Widget::step_movement(float64 ms, bool timer) {
|
void Widget::step_shift(float64 ms, bool timer) {
|
||||||
float64 dt = ms / float64(st::notifyFastAnim);
|
float64 dt = ms / float64(st::notifyFastAnim);
|
||||||
if (dt >= 1) {
|
if (dt >= 1) {
|
||||||
a_top.finish();
|
a_shift.finish();
|
||||||
} else {
|
} else {
|
||||||
a_top.update(dt, anim::linear);
|
a_shift.update(dt, anim::linear);
|
||||||
}
|
}
|
||||||
move(x(), a_top.current());
|
moveByShift();
|
||||||
update();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Widget::hideSlow() {
|
void Widget::hideSlow() {
|
||||||
animHide(st::notifySlowHide, st::notifySlowHideFunc);
|
hideAnimated(st::notifySlowHide, st::notifySlowHideFunc);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Widget::hideFast() {
|
void Widget::hideFast() {
|
||||||
animHide(st::notifyFastAnim, anim::linear);
|
hideAnimated(st::notifyFastAnim, anim::linear);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Widget::hideStop() {
|
void Widget::hideStop() {
|
||||||
|
@ -352,29 +394,39 @@ void Widget::hideStop() {
|
||||||
a_func = anim::linear;
|
a_func = anim::linear;
|
||||||
a_opacity.start(1);
|
a_opacity.start(1);
|
||||||
_hiding = false;
|
_hiding = false;
|
||||||
_a_appearance.start();
|
_a_opacity.start();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Widget::animHide(float64 duration, anim::transition func) {
|
void Widget::hideAnimated(float64 duration, anim::transition func) {
|
||||||
_opacityDuration = duration;
|
_opacityDuration = duration;
|
||||||
a_func = func;
|
a_func = func;
|
||||||
a_opacity.start(0);
|
a_opacity.start(0);
|
||||||
_hiding = true;
|
_hiding = true;
|
||||||
_a_appearance.start();
|
_a_opacity.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Widget::moveTop(int top) {
|
void Widget::updateOpacity() {
|
||||||
a_top.start(top);
|
if (auto manager = ManagerInstance.data()) {
|
||||||
_a_movement.start();
|
setWindowOpacity(a_opacity.current() * manager->demoMasterOpacity());
|
||||||
}
|
|
||||||
|
|
||||||
void Widget::addToHeight(int add, AddToHeight aboveOrBelow) {
|
|
||||||
int newHeight = height() + add;
|
|
||||||
if (aboveOrBelow == AddToHeight::Above) {
|
|
||||||
a_top.add(-add);
|
|
||||||
}
|
}
|
||||||
updateGeometry(x(), a_top.current(), width(), newHeight);
|
}
|
||||||
|
|
||||||
|
void Widget::changeShift(int top) {
|
||||||
|
a_shift.start(top);
|
||||||
|
_a_shift.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Widget::updatePosition(QPoint startPosition, Direction shiftDirection) {
|
||||||
|
_startPosition = startPosition;
|
||||||
|
_direction = shiftDirection;
|
||||||
|
moveByShift();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Widget::addToHeight(int add) {
|
||||||
|
auto newHeight = height() + add;
|
||||||
|
auto newPosition = computePosition(newHeight);
|
||||||
|
updateGeometry(newPosition.x(), newPosition.y(), width(), newHeight);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Widget::updateGeometry(int x, int y, int width, int height) {
|
void Widget::updateGeometry(int x, int y, int width, int height) {
|
||||||
|
@ -382,9 +434,21 @@ void Widget::updateGeometry(int x, int y, int width, int height) {
|
||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Widget::addToTop(int add) {
|
void Widget::addToShift(int add) {
|
||||||
a_top.add(add);
|
a_shift.add(add);
|
||||||
move(x(), a_top.current());
|
moveByShift();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Widget::moveByShift() {
|
||||||
|
move(computePosition(height()));
|
||||||
|
}
|
||||||
|
|
||||||
|
QPoint Widget::computePosition(int height) const {
|
||||||
|
auto realShift = a_shift.current();
|
||||||
|
if (_direction == Direction::Up) {
|
||||||
|
realShift = -realShift - height;
|
||||||
|
}
|
||||||
|
return QPoint(_startPosition.x(), _startPosition.y() + realShift);
|
||||||
}
|
}
|
||||||
|
|
||||||
Background::Background(QWidget *parent) : TWidget(parent) {
|
Background::Background(QWidget *parent) : TWidget(parent) {
|
||||||
|
@ -400,7 +464,7 @@ void Background::paintEvent(QPaintEvent *e) {
|
||||||
p.fillRect(st::notifyBorderWidth, height() - st::notifyBorderWidth, width() - 2 * st::notifyBorderWidth, st::notifyBorderWidth, st::notifyBorder);
|
p.fillRect(st::notifyBorderWidth, height() - st::notifyBorderWidth, width() - 2 * st::notifyBorderWidth, st::notifyBorderWidth, st::notifyBorder);
|
||||||
}
|
}
|
||||||
|
|
||||||
Notification::Notification(History *history, PeerData *peer, PeerData *author, HistoryItem *msg, int forwardedCount, QPoint position) : Widget(position)
|
Notification::Notification(History *history, PeerData *peer, PeerData *author, HistoryItem *msg, int forwardedCount, QPoint startPosition, int shift, Direction shiftDirection) : Widget(startPosition, shift, shiftDirection)
|
||||||
, _history(history)
|
, _history(history)
|
||||||
, _peer(peer)
|
, _peer(peer)
|
||||||
, _author(author)
|
, _author(author)
|
||||||
|
@ -411,7 +475,8 @@ Notification::Notification(History *history, PeerData *peer, PeerData *author, H
|
||||||
#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) {
|
, _reply(this, lang(lng_notification_reply), st::defaultBoxButton) {
|
||||||
updateGeometry(position.x(), position.y(), notificationWidth(), st::notifyMinHeight);
|
auto position = computePosition(st::notifyMinHeight);
|
||||||
|
updateGeometry(position.x(), position.y(), st::notifyWidth, st::notifyMinHeight);
|
||||||
|
|
||||||
_userpicLoaded = _peer ? _peer->userpicLoaded() : true;
|
_userpicLoaded = _peer ? _peer->userpicLoaded() : true;
|
||||||
updateNotifyDisplay();
|
updateNotifyDisplay();
|
||||||
|
@ -460,7 +525,7 @@ void Notification::prepareActionsCache() {
|
||||||
_buttonsCache = App::pixmapFromImageInPlace(std_::move(actionsCacheImg));
|
_buttonsCache = App::pixmapFromImageInPlace(std_::move(actionsCacheImg));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Notification::checkLastInput() {
|
bool Notification::checkLastInput(bool hasReplyingNotifications) {
|
||||||
if (!_waitingForInput) return true;
|
if (!_waitingForInput) return true;
|
||||||
|
|
||||||
auto wasUserInput = true; // TODO
|
auto wasUserInput = true; // TODO
|
||||||
|
@ -472,7 +537,7 @@ bool Notification::checkLastInput() {
|
||||||
#endif // Q_OS_WIN && !Q_OS_WINRT
|
#endif // Q_OS_WIN && !Q_OS_WINRT
|
||||||
if (wasUserInput) {
|
if (wasUserInput) {
|
||||||
_waitingForInput = false;
|
_waitingForInput = false;
|
||||||
if (!isReplying()) {
|
if (!hasReplyingNotifications) {
|
||||||
_hideTimer.start(st::notifyWaitLongHide);
|
_hideTimer.start(st::notifyWaitLongHide);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
@ -684,9 +749,6 @@ void Notification::changeHeight(int newHeight) {
|
||||||
bool Notification::unlinkHistory(History *history) {
|
bool Notification::unlinkHistory(History *history) {
|
||||||
auto unlink = _history && (history == _history || !history);
|
auto unlink = _history && (history == _history || !history);
|
||||||
if (unlink) {
|
if (unlink) {
|
||||||
if (_history->peer->id != 4456802837) {
|
|
||||||
int a = 0;
|
|
||||||
}
|
|
||||||
hideFast();
|
hideFast();
|
||||||
_history = nullptr;
|
_history = nullptr;
|
||||||
_item = nullptr;
|
_item = nullptr;
|
||||||
|
@ -748,10 +810,11 @@ Notification::~Notification() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
HideAllButton::HideAllButton(QPoint position) : Widget(position) {
|
HideAllButton::HideAllButton(QPoint startPosition, int shift, Direction shiftDirection) : Widget(startPosition, shift, shiftDirection) {
|
||||||
setCursor(style::cur_pointer);
|
setCursor(style::cur_pointer);
|
||||||
|
|
||||||
updateGeometry(position.x(), position.y(), notificationWidth(), st::notifyHideAll.height);
|
auto position = computePosition(st::notifyHideAll.height);
|
||||||
|
updateGeometry(position.x(), position.y(), st::notifyWidth, st::notifyHideAll.height);
|
||||||
hide();
|
hide();
|
||||||
createWinId();
|
createWinId();
|
||||||
|
|
||||||
|
|
|
@ -31,6 +31,7 @@ namespace Window {
|
||||||
namespace Notifications {
|
namespace Notifications {
|
||||||
namespace Default {
|
namespace Default {
|
||||||
namespace internal {
|
namespace internal {
|
||||||
|
class Widget;
|
||||||
class Notification;
|
class Notification;
|
||||||
class HideAllButton;
|
class HideAllButton;
|
||||||
} // namespace internal
|
} // namespace internal
|
||||||
|
@ -59,6 +60,7 @@ private:
|
||||||
friend class Notification;
|
friend class Notification;
|
||||||
using HideAllButton = internal::HideAllButton;
|
using HideAllButton = internal::HideAllButton;
|
||||||
friend class HideAllButton;
|
friend class HideAllButton;
|
||||||
|
friend class internal::Widget;
|
||||||
|
|
||||||
void doUpdateAll() override;
|
void doUpdateAll() override;
|
||||||
void doShowNotification(HistoryItem *item, int forwardedCount) override;
|
void doShowNotification(HistoryItem *item, int forwardedCount) override;
|
||||||
|
@ -75,9 +77,14 @@ private:
|
||||||
void stopAllHiding();
|
void stopAllHiding();
|
||||||
void checkLastInput();
|
void checkLastInput();
|
||||||
|
|
||||||
QPoint notificationStartPosition() const;
|
float64 demoMasterOpacity() const;
|
||||||
|
void demoMasterOpacityCallback();
|
||||||
|
|
||||||
void moveWidgets();
|
void moveWidgets();
|
||||||
void changeNotificationHeight(Notification *widget, int newHeight);
|
void changeNotificationHeight(Notification *widget, int newHeight);
|
||||||
|
void settingsChanged(const Notify::ChangeType &change);
|
||||||
|
|
||||||
|
bool hasReplyingNotification() const;
|
||||||
|
|
||||||
using Notifications = QList<Notification*>;
|
using Notifications = QList<Notification*>;
|
||||||
Notifications _notifications;
|
Notifications _notifications;
|
||||||
|
@ -105,46 +112,57 @@ private:
|
||||||
using QueuedNotifications = QList<QueuedNotification>;
|
using QueuedNotifications = QList<QueuedNotification>;
|
||||||
QueuedNotifications _queuedNotifications;
|
QueuedNotifications _queuedNotifications;
|
||||||
|
|
||||||
|
FloatAnimation _demoMasterOpacity;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
namespace internal {
|
namespace internal {
|
||||||
|
|
||||||
class Widget : public TWidget {
|
class Widget : public TWidget {
|
||||||
public:
|
public:
|
||||||
Widget(QPoint position);
|
enum class Direction {
|
||||||
|
Up,
|
||||||
|
Down,
|
||||||
|
};
|
||||||
|
Widget(QPoint startPosition, int shift, Direction shiftDirection);
|
||||||
|
|
||||||
bool isShowing() const {
|
bool isShowing() const {
|
||||||
return _a_appearance.animating() && !_hiding;
|
return _a_opacity.animating() && !_hiding;
|
||||||
}
|
}
|
||||||
void moveTop(int top);
|
|
||||||
|
|
||||||
enum class AddToHeight {
|
void updateOpacity();
|
||||||
Above,
|
void changeShift(int top);
|
||||||
Below,
|
int currentShift() const {
|
||||||
};
|
return a_shift.current();
|
||||||
void addToHeight(int add, AddToHeight aboveOrBelow);
|
}
|
||||||
void addToTop(int add);
|
void updatePosition(QPoint startPosition, Direction shiftDirection);
|
||||||
|
void addToHeight(int add);
|
||||||
|
void addToShift(int add);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void hideSlow();
|
void hideSlow();
|
||||||
void hideFast();
|
void hideFast();
|
||||||
void hideStop();
|
void hideStop();
|
||||||
|
QPoint computePosition(int height) const;
|
||||||
|
|
||||||
virtual void updateGeometry(int x, int y, int width, int height);
|
virtual void updateGeometry(int x, int y, int width, int height);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void animHide(float64 duration, anim::transition func);
|
void moveByShift();
|
||||||
void step_appearance(float64 ms, bool timer);
|
void hideAnimated(float64 duration, anim::transition func);
|
||||||
void step_movement(float64 ms, bool timer);
|
void step_opacity(float64 ms, bool timer);
|
||||||
|
void step_shift(float64 ms, bool timer);
|
||||||
|
|
||||||
bool _hiding = false;
|
bool _hiding = false;
|
||||||
float64 _opacityDuration;
|
float64 _opacityDuration;
|
||||||
anim::fvalue a_opacity;
|
anim::fvalue a_opacity;
|
||||||
anim::transition a_func;
|
anim::transition a_func;
|
||||||
Animation _a_appearance;
|
Animation _a_opacity;
|
||||||
|
|
||||||
anim::ivalue a_top;
|
QPoint _startPosition;
|
||||||
Animation _a_movement;
|
Direction _direction;
|
||||||
|
anim::ivalue a_shift;
|
||||||
|
Animation _a_shift;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -161,7 +179,7 @@ class Notification : public Widget {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Notification(History *history, PeerData *peer, PeerData *author, HistoryItem *item, int forwardedCount, QPoint position);
|
Notification(History *history, PeerData *peer, PeerData *author, HistoryItem *item, int forwardedCount, QPoint startPosition, int shift, Direction shiftDirection);
|
||||||
|
|
||||||
void startHiding();
|
void startHiding();
|
||||||
void stopHiding();
|
void stopHiding();
|
||||||
|
@ -179,7 +197,7 @@ public:
|
||||||
// Called only by Manager.
|
// Called only by Manager.
|
||||||
void itemRemoved(HistoryItem *del);
|
void itemRemoved(HistoryItem *del);
|
||||||
bool unlinkHistory(History *history = nullptr);
|
bool unlinkHistory(History *history = nullptr);
|
||||||
bool checkLastInput();
|
bool checkLastInput(bool hasReplyingNotifications);
|
||||||
|
|
||||||
~Notification();
|
~Notification();
|
||||||
|
|
||||||
|
@ -237,7 +255,7 @@ private:
|
||||||
|
|
||||||
class HideAllButton : public Widget {
|
class HideAllButton : public Widget {
|
||||||
public:
|
public:
|
||||||
HideAllButton(QPoint position);
|
HideAllButton(QPoint startPosition, int shift, Direction shiftDirection);
|
||||||
|
|
||||||
void startHiding();
|
void startHiding();
|
||||||
void startHidingFast();
|
void startHidingFast();
|
||||||
|
|
|
@ -37,7 +37,7 @@ notifyTextTop: 7px;
|
||||||
notifySlowHideFunc: transition(easeInCirc);
|
notifySlowHideFunc: transition(easeInCirc);
|
||||||
notifyWaitLongHide: 3000;
|
notifyWaitLongHide: 3000;
|
||||||
notifyFastAnim: 150;
|
notifyFastAnim: 150;
|
||||||
notifyMinWidth: 316px;
|
notifyWidth: 320px;
|
||||||
notifyMinHeight: 80px;
|
notifyMinHeight: 80px;
|
||||||
notifyDeltaX: 6px;
|
notifyDeltaX: 6px;
|
||||||
notifyDeltaY: 7px;
|
notifyDeltaY: 7px;
|
||||||
|
|
Loading…
Reference in New Issue