Line data Source code
1 : #include "NotificationOverlay.hpp"
2 :
3 8 : NotificationOverlay::NotificationOverlay(QWidget* parent)
4 8 : : QWidget(parent)
5 : {
6 8 : setAttribute(Qt::WA_TransparentForMouseEvents);
7 8 : setAttribute(Qt::WA_NoSystemBackground);
8 8 : setAttribute(Qt::WA_TranslucentBackground);
9 8 : setWindowFlags(Qt::FramelessWindowHint | Qt::ToolTip);
10 8 : if (parent)
11 8 : resize(parent->size());
12 : //resize(parent->size());
13 8 : opacityEffect = new QGraphicsOpacityEffect(this);
14 8 : setGraphicsEffect(opacityEffect);
15 :
16 8 : fadeAnimation = new QPropertyAnimation(opacityEffect, "opacity");
17 8 : fadeAnimation->setDuration(500); // 500ms fade duration
18 :
19 8 : fadeOutTimer = new QTimer(this);
20 8 : fadeOutTimer->setSingleShot(true);
21 8 : }
22 :
23 : NotificationOverlay::~NotificationOverlay() = default;
24 :
25 8 : void NotificationOverlay::showNotification(const QString& text, NotificationLevel notificationLevel, int durationMs)
26 : {
27 8 : message = text;
28 8 : level = notificationLevel;
29 :
30 8 : fadeAnimation->stop();
31 8 : disconnect(fadeAnimation, nullptr, nullptr, nullptr);
32 :
33 8 : persistent = (durationMs == 0); // Persist if duration is 0
34 :
35 8 : if (!persistent) {
36 4 : fadeOutTimer->stop();
37 4 : fadeOutTimer->start(durationMs);
38 4 : connect(fadeOutTimer, &QTimer::timeout, this, [this]() {
39 2 : startFadeOut();
40 2 : });
41 : }
42 :
43 8 : show();
44 8 : update();
45 :
46 : // Fade in
47 8 : fadeAnimation->setStartValue(0.0);
48 8 : fadeAnimation->setEndValue(1.0);
49 8 : fadeAnimation->start();
50 :
51 8 : connect(fadeOutTimer, &QTimer::timeout, this, [this]() {
52 2 : fadeAnimation->stop();
53 2 : disconnect(fadeAnimation, nullptr, nullptr, nullptr);
54 :
55 2 : fadeAnimation->setStartValue(1.0);
56 2 : fadeAnimation->setEndValue(0.0);
57 2 : fadeAnimation->start();
58 :
59 2 : connect(fadeAnimation, &QPropertyAnimation::finished, this, [this]() {
60 2 : if (opacityEffect->opacity() == 0.0)
61 2 : hide();
62 2 : });
63 2 : });
64 8 : }
65 :
66 4 : void NotificationOverlay::startFadeOut() {
67 4 : fadeAnimation->stop();
68 4 : disconnect(fadeAnimation, nullptr, nullptr, nullptr);
69 :
70 4 : fadeAnimation->setStartValue(1.0);
71 4 : fadeAnimation->setEndValue(0.0);
72 4 : fadeAnimation->start();
73 :
74 4 : connect(fadeAnimation, &QPropertyAnimation::finished, this, [this]() {
75 2 : if (opacityEffect->opacity() == 0.0)
76 2 : hide();
77 2 : });
78 4 : }
79 :
80 2 : void NotificationOverlay::hideNotification() {
81 2 : if (persistent) {
82 2 : persistent = false;
83 2 : startFadeOut();
84 : }
85 2 : }
86 :
87 235 : void NotificationOverlay::paintEvent(QPaintEvent*)
88 : {
89 470 : QPainter painter(this);
90 235 : painter.setRenderHint(QPainter::Antialiasing);
91 :
92 : // Setup font
93 470 : QFont font = painter.font();
94 235 : font.setPointSize(12);
95 235 : painter.setFont(font);
96 :
97 : // Measure text width
98 470 : QFontMetrics metrics(font);
99 235 : int textWidth = metrics.horizontalAdvance(message);
100 :
101 : // Icon parameters
102 235 : int iconSize = 30;
103 235 : int iconMargin = 20;
104 :
105 : // Compute box width based on text and icon
106 235 : int boxWidth = iconMargin + iconSize + 10 + textWidth + 20; // iconMargin + icon + spacing + text + right margin
107 235 : int maxWidth = width() * 0.8;
108 235 : boxWidth = std::min(boxWidth, maxWidth);
109 :
110 235 : int boxHeight = 80;
111 235 : int boxX = (width() - boxWidth) / 2;
112 235 : int boxY = 50;
113 :
114 235 : QRect rect(boxX, boxY, boxWidth, boxHeight);
115 :
116 : // Background
117 235 : QColor backgroundColor(1, 32, 44, 255);
118 235 : painter.setBrush(backgroundColor);
119 235 : painter.setPen(Qt::NoPen);
120 235 : painter.drawRoundedRect(rect, 20, 20);
121 :
122 : // Icon
123 470 : QString iconPath;
124 235 : switch (level) {
125 110 : case NotificationLevel::Info:
126 110 : iconPath = ":/images/info.png";
127 110 : break;
128 125 : case NotificationLevel::Warning:
129 125 : iconPath = ":/images/warning.png";
130 125 : break;
131 : }
132 235 : QPixmap icon(iconPath);
133 235 : int iconX = rect.left() + iconMargin;
134 235 : int iconY = rect.top() + (rect.height() - iconSize) / 2;
135 235 : painter.drawPixmap(iconX, iconY, iconSize, iconSize, icon);
136 :
137 : // Text
138 235 : QRect textRect = rect.adjusted(iconMargin + iconSize + 10, 0, -20, 0);
139 235 : painter.setPen(Qt::white);
140 235 : painter.drawText(textRect, Qt::AlignVCenter | Qt::AlignLeft, message);
141 235 : }
|