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