feat: top center notifications

This commit is contained in:
ZavaruKitsu 2023-08-30 20:12:41 +00:00
parent 8e8719870a
commit ca9feab071
4 changed files with 55 additions and 9 deletions

View file

@ -742,7 +742,8 @@ void Settings::addFromSerialized(const QByteArray &serialized) {
case ScreenCorner::TopLeft:
case ScreenCorner::TopRight:
case ScreenCorner::BottomRight:
case ScreenCorner::BottomLeft: _notificationsCorner = uncheckedNotificationsCorner; break;
case ScreenCorner::BottomLeft:
case ScreenCorner::TopCenter:_notificationsCorner = uncheckedNotificationsCorner; break;
}
_includeMutedCounter = (includeMutedCounter == 1);
_countUnreadMessages = (countUnreadMessages == 1);

View file

@ -103,6 +103,7 @@ public:
TopRight = 1,
BottomRight = 2,
BottomLeft = 3,
TopCenter = 4,
};
enum class NotifyView {
ShowPreview = 0,
@ -130,11 +131,16 @@ public:
[[nodiscard]] static bool IsLeftCorner(ScreenCorner corner) {
return (corner == ScreenCorner::TopLeft)
|| (corner == ScreenCorner::BottomLeft);
|| (corner == ScreenCorner::BottomLeft)
|| (corner == ScreenCorner::TopCenter);
}
[[nodiscard]] static bool IsTopCorner(ScreenCorner corner) {
return (corner == ScreenCorner::TopLeft)
|| (corner == ScreenCorner::TopRight);
|| (corner == ScreenCorner::TopRight)
|| (corner == ScreenCorner::TopCenter);
}
[[nodiscard]] static bool IsTopCenterCorner(ScreenCorner corner) {
return corner == ScreenCorner::TopCenter;
}
[[nodiscard]] QByteArray serialize() const;

View file

@ -111,7 +111,7 @@ private:
int _oldCount;
std::vector<SampleWidget*> _cornerSamples[4];
std::vector<SampleWidget*> _cornerSamples[5];
};
@ -191,6 +191,27 @@ void NotificationsCount::paintEvent(QPaintEvent *e) {
p.setOpacity(1.);
}
}
// support for top center notifications
auto screenCorner = static_cast<ScreenCorner>(4);
auto isLeft = Core::Settings::IsLeftCorner(screenCorner);
auto isTop = true;
auto sampleLeft = screenRect.x() + screenRect.width() / 2 - st::notificationSampleSize.width() / 2;
auto sampleTop = screenRect.y() + st::notificationsSampleTopSkip;
if (static_cast<int>(_chosenCorner) == 4) {
auto count = _oldCount;
for (int i = 0; i != kMaxNotificationsCount; ++i) {
auto opacity = _sampleOpacities[i].value((i < count) ? 1. : 0.);
p.setOpacity(opacity);
p.drawPixmapLeft(sampleLeft, sampleTop, width(), _notificationSampleSmall);
sampleTop += (isTop ? 1 : -1) * (st::notificationSampleSize.height() + st::notificationsSampleMargin);
}
p.setOpacity(1.);
} else {
p.setOpacity(st::notificationSampleOpacity);
p.drawPixmapLeft(sampleLeft, sampleTop, width(), _notificationSampleSmall);
p.setOpacity(1.);
}
}
void NotificationsCount::setCount(int count) {
@ -341,6 +362,7 @@ void NotificationsCount::mouseMoveEvent(QMouseEvent *e) {
auto topRight = style::rtlrect(screenRect.x() + screenRect.width() - cornerWidth, screenRect.y(), cornerWidth, cornerHeight, width());
auto bottomRight = style::rtlrect(screenRect.x() + screenRect.width() - cornerWidth, screenRect.y() + screenRect.height() - cornerHeight, cornerWidth, cornerHeight, width());
auto bottomLeft = style::rtlrect(screenRect.x(), screenRect.y() + screenRect.height() - cornerHeight, cornerWidth, cornerHeight, width());
auto topCenter = style::rtlrect(screenRect.x() + cornerWidth, screenRect.y(), cornerWidth, cornerHeight, width());
if (topLeft.contains(e->pos())) {
setOverCorner(ScreenCorner::TopLeft);
} else if (topRight.contains(e->pos())) {
@ -349,7 +371,9 @@ void NotificationsCount::mouseMoveEvent(QMouseEvent *e) {
setOverCorner(ScreenCorner::BottomRight);
} else if (bottomLeft.contains(e->pos())) {
setOverCorner(ScreenCorner::BottomLeft);
} else {
} else if (topCenter.contains(e->pos())) {
setOverCorner(ScreenCorner::TopCenter);
} else{
clearOverCorner();
}
}
@ -388,6 +412,11 @@ void NotificationsCount::setOverCorner(ScreenCorner corner) {
auto isTop = Core::Settings::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);
if (Core::Settings::IsTopCenterCorner(_overCorner)) {
sampleLeft = (r.x() + r.width() / 2 - st::notifyWidth / 2);
}
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));

View file

@ -52,6 +52,11 @@ namespace Notifications {
namespace Default {
namespace {
[[nodiscard]] int notifyWidth() {
const auto corner = Core::App().settings().notificationsCorner();
return Core::Settings::IsTopCenterCorner(corner) ? st::notifyWidth * 1.5 : st::notifyWidth;
}
[[nodiscard]] QPoint notificationStartPosition() {
const auto corner = Core::App().settings().notificationsCorner();
const auto window = Core::App().activePrimaryWindow();
@ -60,10 +65,15 @@ namespace {
: QGuiApplication::primaryScreen()->availableGeometry();
const auto isLeft = Core::Settings::IsLeftCorner(corner);
const auto isTop = Core::Settings::IsTopCorner(corner);
const auto x = (isLeft == rtl())
? (r.x() + r.width() - st::notifyWidth - st::notifyDeltaX)
auto x = (isLeft == rtl())
? (r.x() + r.width() - notifyWidth() - st::notifyDeltaX)
: (r.x() + st::notifyDeltaX);
const auto y = isTop ? r.y() : (r.y() + r.height());
if (Core::Settings::IsTopCenterCorner(corner)) {
x = (r.x() + r.width() / 2 - notifyWidth() / 2);
}
return QPoint(x, y);
}
@ -666,7 +676,7 @@ Notification::Notification(
}
auto position = computePosition(st::notifyMinHeight);
updateGeometry(position.x(), position.y(), st::notifyWidth, st::notifyMinHeight);
updateGeometry(position.x(), position.y(), notifyWidth(), st::notifyMinHeight);
_userpicLoaded = !Ui::PeerUserpicLoading(_userpicView);
updateNotifyDisplay();
@ -1238,7 +1248,7 @@ HideAllButton::HideAllButton(
setCursor(style::cur_pointer);
auto position = computePosition(st::notifyHideAllHeight);
updateGeometry(position.x(), position.y(), st::notifyWidth, st::notifyHideAllHeight);
updateGeometry(position.x(), position.y(), notifyWidth(), st::notifyHideAllHeight);
hide();
createWinId();