1 #define ROUNDED_PIXEL 5
2 #define SHADOW_COLOR palette().highlight().color()
3
4 #include "asemannativenotificationitem.h"
5
6 #include <QPainterPath>
7 #include <QPaintEvent>
8 #include <QSize>
9 #include <QPainter>
10 #include <QGraphicsBlurEffect>
11 #include <QLabel>
12 #include <QPushButton>
13 #include <QToolButton>
14 #include <QHBoxLayout>
15 #include <QVBoxLayout>
16 #include <QDesktopWidget>
17 #include <QApplication>
18 #include <QTimer>
19 #include <QPixmap>
20 #include <QStyleFactory>
21 #include <QDebug>
22
23 class DialogScene: public QWidget
24 {
25 public:
DialogScene(QWidget * parent=0)26 DialogScene( QWidget *parent = 0 ): QWidget(parent){ }
~DialogScene()27 ~DialogScene(){}
28
29 protected:
paintEvent(QPaintEvent * e)30 void paintEvent(QPaintEvent *e){
31 Q_UNUSED(e)
32 QPainter painter(this);
33 painter.setRenderHint( QPainter::Antialiasing , true );
34 painter.fillRect(e->rect(), palette().window());
35 }
36 };
37
38 class AsemanNativeNotificationItemPrivate
39 {
40 public:
41 DialogScene *scene;
42
43 QVBoxLayout *layout;
44 QHBoxLayout *body_layout;
45 QVBoxLayout *btns_layout;
46 QHBoxLayout *ttle_layout;
47
48 QLabel *title_lbl;
49 QLabel *body_lbl;
50 QLabel *icon_lbl;
51
52 QList<QPushButton*> buttons;
53 QHash<QPushButton*,QString> actions;
54
55 QToolButton *close_btn;
56
57 QColor color;
58 QColor backColor;
59 QColor textColor;
60 QColor buttonColor;
61 };
62
63
AsemanNativeNotificationItem(QWidget * parent)64 AsemanNativeNotificationItem::AsemanNativeNotificationItem(QWidget *parent) :
65 QWidget(parent)
66 {
67 p = new AsemanNativeNotificationItemPrivate;
68
69 QFont font;
70 font.setPointSize(10);
71
72 setFont(font);
73 setColor(palette().highlight().color());
74
75 p->scene = new DialogScene( this );
76
77 p->title_lbl = new QLabel();
78 p->title_lbl->setAlignment(Qt::AlignCenter);
79 p->title_lbl->setFixedHeight(26);
80
81 p->close_btn = new QToolButton();
82 p->close_btn->setText("X");
83 p->close_btn->setFixedSize(26, 26);
84 p->close_btn->setAutoRaise(true);
85
86 p->ttle_layout = new QHBoxLayout();
87 p->ttle_layout->addWidget(p->title_lbl);
88 p->ttle_layout->addWidget(p->close_btn);
89 p->ttle_layout->setContentsMargins(0,0,0,0);
90 p->ttle_layout->setSpacing(1);
91
92 p->icon_lbl = new QLabel();
93 p->icon_lbl->setFixedSize(64, 64);
94 p->icon_lbl->setScaledContents(true);
95
96 p->body_lbl = new QLabel();
97 p->body_lbl->setWordWrap(true);
98
99 p->btns_layout = new QVBoxLayout();
100 p->btns_layout->setContentsMargins(0,0,0,0);
101 p->btns_layout->setSpacing(1);
102
103 p->body_layout = new QHBoxLayout();
104 p->body_layout->addWidget(p->icon_lbl);
105 p->body_layout->addWidget(p->body_lbl, 10000);
106 p->body_layout->addLayout(p->btns_layout);
107 p->body_layout->setContentsMargins(0,0,0,0);
108 p->body_layout->setSpacing(8);
109
110 p->layout = new QVBoxLayout(this);
111 p->layout->addLayout(p->ttle_layout);
112 p->layout->addLayout(p->body_layout);
113 p->layout->setContentsMargins(10,8,10,8);
114 p->layout->setSpacing(1);
115
116 setWindowFlags( Qt::ToolTip );
117 setAttribute(Qt::WA_TranslucentBackground);
118 setAttribute(Qt::WA_NoSystemBackground);
119 setAttribute(Qt::WA_DeleteOnClose);
120 setMouseTracking( true );
121 setWindowOpacity(0.98);
122
123 refreshSize();
124
125 connect(p->close_btn, SIGNAL(clicked()), SLOT(close()) );
126 }
127
setColor(const QColor & color)128 void AsemanNativeNotificationItem::setColor(const QColor &color)
129 {
130 if(p->color == color)
131 return;
132
133 p->color = color;
134
135
136 p->backColor = QColor( p->color.red()*0.8, p->color.green()*0.8, p->color.blue()*0.8 );
137 p->buttonColor = QColor( p->color.red()*0.5, p->color.green()*0.5, p->color.blue()*0.5 );
138
139 qreal mid = (p->buttonColor.red()+p->buttonColor.green()+p->buttonColor.blue())/3.0;
140 p->textColor = mid>=128? QColor("#333333") : QColor("#ffffff");
141
142 QPalette palette;
143 palette.setColor(QPalette::Window, p->backColor);
144 palette.setColor(QPalette::WindowText, p->textColor);
145 palette.setColor(QPalette::ButtonText, "#ffffff");
146 palette.setColor(QPalette::Button, p->buttonColor);
147 setPalette(palette);
148
149 emit colorChanged();
150 }
151
color() const152 QColor AsemanNativeNotificationItem::color() const
153 {
154 return p->color;
155 }
156
setActions(const QStringList & actions)157 void AsemanNativeNotificationItem::setActions(const QStringList &actions)
158 {
159 for(int i=0; i<p->btns_layout->count(); i++)
160 delete p->btns_layout->takeAt(i);
161
162 for(int i=1 ;i<actions.count(); i+=2)
163 {
164 const QString &action = actions.at(i-1);
165 const QString &text = actions.at(i);
166
167 QPushButton *btn = new QPushButton();
168 btn->setText(text);
169 btn->setPalette(QPalette());
170 btn->setFont(QFont());
171
172 static QStyle *style = QStyleFactory::create("Fusion");
173 btn->setStyle(style);
174
175 p->actions.insert(btn, action);
176 p->buttons << btn;
177
178 p->btns_layout->addWidget(btn);
179
180 connect(btn, SIGNAL(clicked()), SLOT(buttonClicked()) );
181 }
182
183 p->body_layout->addStretch();
184 }
185
setTitle(const QString & title)186 void AsemanNativeNotificationItem::setTitle(const QString &title)
187 {
188 p->title_lbl->setText(title);
189 }
190
setBody(const QString & body)191 void AsemanNativeNotificationItem::setBody(const QString &body)
192 {
193 p->body_lbl->setText(body.left(100) + "...");
194 }
195
setIcon(const QString & icon)196 void AsemanNativeNotificationItem::setIcon(const QString &icon)
197 {
198 p->icon_lbl->setPixmap( QPixmap(icon) );
199 }
200
setTimeOut(int timeOut)201 void AsemanNativeNotificationItem::setTimeOut(int timeOut)
202 {
203 if(timeOut == 0)
204 return;
205
206 QTimer::singleShot(timeOut, this, SLOT(close()) );
207 }
208
resizeEvent(QResizeEvent * e)209 void AsemanNativeNotificationItem::resizeEvent(QResizeEvent *e)
210 {
211 refreshSize();
212 QWidget::resizeEvent(e);
213 }
214
mouseReleaseEvent(QMouseEvent * e)215 void AsemanNativeNotificationItem::mouseReleaseEvent(QMouseEvent *e)
216 {
217 Q_UNUSED(e)
218 close();
219 }
220
refreshSize()221 void AsemanNativeNotificationItem::refreshSize()
222 {
223 QRect rect( 0, 0, width(), height() );
224
225 const QRect &scr = QApplication::desktop()->availableGeometry();
226
227 p->scene->setGeometry( rect );
228
229 move(scr.x()+scr.width()-width() - 4, scr.y()+scr.height()-height() - 4);
230 }
231
setRaised()232 void AsemanNativeNotificationItem::setRaised()
233 {
234 raise();
235 }
236
buttonClicked()237 void AsemanNativeNotificationItem::buttonClicked()
238 {
239 QPushButton *btn = static_cast<QPushButton*>(sender());
240 if(!btn)
241 return;
242
243 const QString &action = p->actions.value(btn);
244 emit actionTriggered(action);
245 }
246
~AsemanNativeNotificationItem()247 AsemanNativeNotificationItem::~AsemanNativeNotificationItem()
248 {
249 delete p;
250 }
251
252