├── .gitignore ├── EToastr.sln ├── EToastr ├── EToastr.cpp ├── EToastr.h ├── EToastr.pro ├── EToastr.qrc ├── EToastr.vcxproj ├── EToastr.vcxproj.filters ├── EToastr.vcxproj.user ├── EWidget.cpp ├── EWidget.h ├── Ui │ ├── image.qrc │ ├── img │ │ ├── check.png │ │ ├── desktop.ini │ │ ├── error.png │ │ ├── info.png │ │ ├── message.png │ │ ├── shield.png │ │ └── warning.png │ └── toastr.ui └── main.cpp ├── Gifs ├── Bottom_parent_notimeout.gif ├── Left_noparent_info.gif ├── Left_parent_noicon.gif ├── Right_noparent_warning.gif ├── Right_parent.gif ├── Top_noparent.gif └── Top_parent.gif ├── LICENSE └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # This .gitignore file was automatically created by Microsoft(R) Visual Studio. 3 | ################################################################################ 4 | 5 | /.vs/EToastr 6 | /EToastr/Debug 7 | /Debug/EToastr.pdb 8 | /Debug/EToastr.ilk 9 | /Debug 10 | /EToastr/EToastr.pro.user 11 | /.vs -------------------------------------------------------------------------------- /EToastr.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 17 4 | VisualStudioVersion = 17.3.32804.467 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "EToastr", "EToastr\EToastr.vcxproj", "{0E6DDD96-6F4D-4AF4-96C2-7C487E80BAC3}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|x86 = Debug|x86 11 | Release|x86 = Release|x86 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {0E6DDD96-6F4D-4AF4-96C2-7C487E80BAC3}.Debug|x86.ActiveCfg = Debug|Win32 15 | {0E6DDD96-6F4D-4AF4-96C2-7C487E80BAC3}.Debug|x86.Build.0 = Debug|Win32 16 | {0E6DDD96-6F4D-4AF4-96C2-7C487E80BAC3}.Release|x86.ActiveCfg = Release|Win32 17 | {0E6DDD96-6F4D-4AF4-96C2-7C487E80BAC3}.Release|x86.Build.0 = Release|Win32 18 | EndGlobalSection 19 | GlobalSection(SolutionProperties) = preSolution 20 | HideSolutionNode = FALSE 21 | EndGlobalSection 22 | GlobalSection(ExtensibilityGlobals) = postSolution 23 | SolutionGuid = {0999E294-F4FF-44DA-BAB5-3A38B3279E7B} 24 | EndGlobalSection 25 | EndGlobal 26 | -------------------------------------------------------------------------------- /EToastr/EToastr.cpp: -------------------------------------------------------------------------------- 1 | #include "EToastr.h" 2 | #include "ui_toastr.h" 3 | #include 4 | 5 | uint EToastr::TIMEOUT = 2000; 6 | uint EToastr::COUNT_TOASTR = 0; 7 | QVector EToastr::vectorToastr; 8 | 9 | void EToastr::setPopupOpacity(float opacity) 10 | { 11 | popupOpacity = opacity; 12 | setWindowOpacity(opacity); 13 | } 14 | 15 | float EToastr::getPopupOpacity() const { return popupOpacity; } 16 | 17 | void EToastr::setTimelapse(float timelapse) 18 | { 19 | this->timeLapse = timelapse; 20 | if (timelapse == 0.0f) 21 | setPopupOpacity(0.85f); // set opacity when toastr slides (hiding) 22 | else 23 | setPopupOpacity(1.0f); 24 | } 25 | 26 | float EToastr::getTimelapse() const { return this->timeLapse; } 27 | 28 | QRect EToastr::getParentGeometry() const 29 | { 30 | if (parentIsDesktop())// is parent null (it means parent is Desktop) 31 | { 32 | QScreen* screen = QGuiApplication::primaryScreen(); 33 | QRect geometry = screen->geometry(); 34 | return geometry; 35 | //return QApplication::desktop()->geometry(); 36 | } 37 | else { 38 | //_parent->adjustSize(); 39 | //qDebug() << _parent->geometry(); 40 | auto geo = _parent->geometry(); 41 | return geo; 42 | } 43 | } 44 | void EToastr::SlotParentResized(QResizeEvent* event) { 45 | Q_UNUSED(event); 46 | updateLocations(); 47 | } 48 | void EToastr::SlotParentMoved(QMoveEvent* event) 49 | { 50 | Q_UNUSED(event); 51 | updateLocations(); 52 | } 53 | void EToastr::Quit() 54 | { 55 | QWidget::hide(); 56 | COUNT_TOASTR--; 57 | deleteFromList(this); 58 | All_updateLocations(); 59 | delete this; 60 | } 61 | bool EToastr::parentIsDesktop() const { return (this->_parent == nullptr); } 62 | 63 | void EToastr::calculateStartXY(QRect rect, TOASTR_DIRECTION direction, QRect& out_rect) 64 | { 65 | out_rect = rect; 66 | const QRect targetGeometry = getParentGeometry(); 67 | const int screen_w = targetGeometry.width(); 68 | const int screen_h = targetGeometry.height(); 69 | 70 | 71 | const int save_h = out_rect.height(); // when we use setY function, height too changes so we need to save it first then change Y coordinate and restore back height at the end. / setY kullanilinca height de degisiyor bunu cozmek icin height once bir degiskende sakliyorum, setY kullanildiktan sonra tekrar bu degiskendeki degeri yapiyorum 72 | 73 | if (direction == TOASTR_DIRECTION::RIGHT_TO_LEFT) { // SAGDAN GELECEK 74 | out_rect.setX(screen_w + MARGIN_WIDTH); 75 | out_rect.setY(MARGIN_WIDTH); 76 | } 77 | else if (direction == TOASTR_DIRECTION::LEFT_TO_RIGHT) { // SOLDAN GELECEK 78 | out_rect.setX(-MARGIN_WIDTH); 79 | out_rect.setY(MARGIN_WIDTH); 80 | } 81 | else if (direction == TOASTR_DIRECTION::TOP_TO_BOTTOM) { // YUKARDAN GELECEK 82 | out_rect.setX((screen_w - width())/2); 83 | out_rect.setY(-MARGIN_WIDTH); 84 | } 85 | else if (direction == TOASTR_DIRECTION::BOTTOM_TO_TOP) { // ASAGIDAN GELECEK 86 | out_rect.setX((screen_w - width())/2); 87 | out_rect.setY(screen_h+MARGIN_WIDTH); 88 | } 89 | out_rect.setHeight(save_h); // if we don't do that, height will return minmumSize always (30) 90 | } 91 | void EToastr::updateLocations() 92 | { 93 | if (m_closing) // Animasyon kayarak kapanacakken parent resize/move olursa bunlar çakışıyor bunu önlemek için 94 | return; 95 | const QRect targetGeometry = getParentGeometry(); 96 | const int screen_x = targetGeometry.x(); // for multiple monitors 97 | 98 | const int screen_w = targetGeometry.width(); 99 | const int screen_h = targetGeometry.height(); 100 | 101 | const int START_Y = MARGIN_WIDTH + (this->getCurrentIndex() * (this->height() + SPACE_BETWEEN)); 102 | 103 | switch (directionShow) { 104 | case TOASTR_DIRECTION::RIGHT_TO_LEFT: 105 | { 106 | moveanimated(screen_w - MARGIN_WIDTH - width(), 107 | START_Y); 108 | } break; 109 | case TOASTR_DIRECTION::LEFT_TO_RIGHT: 110 | { 111 | moveanimated(MARGIN_WIDTH, 112 | START_Y); 113 | }break; 114 | case TOASTR_DIRECTION::BOTTOM_TO_TOP: 115 | { 116 | moveanimated((screen_w - width())/2, 117 | screen_h - (START_Y + height())); 118 | }break; 119 | case TOASTR_DIRECTION::TOP_TO_BOTTOM: 120 | { 121 | moveanimated((screen_w - width())/ 2, 122 | START_Y); 123 | }break; 124 | } 125 | } 126 | 127 | void EToastr::All_updateLocations() 128 | { 129 | for (int i = 0; i < vectorToastr.length(); i++) { 130 | auto data = vectorToastr.at(i); 131 | data->updateLocations(); 132 | } 133 | } 134 | 135 | void EToastr::deleteFromList(EToastr* target) 136 | { 137 | const int myIndex = vectorToastr.indexOf(target); 138 | if (myIndex > -1 && myIndex < vectorToastr.count()) 139 | vectorToastr.remove(myIndex); 140 | } 141 | 142 | 143 | int EToastr::getCurrentIndex() const 144 | { 145 | auto it = std::find(this->vectorToastr.begin(), this->vectorToastr.end(), this); 146 | if (it != this->vectorToastr.end()) 147 | return (int)(it - this->vectorToastr.begin()); 148 | 149 | return -1; 150 | } 151 | 152 | EToastr::EToastr(EWidget* parent, bool showIcon) 153 | : QFrame(parent) 154 | , ui(new Ui::Toastr) 155 | { 156 | ui->setupUi(this); 157 | _parent = parent; 158 | setParent(_parent); 159 | if (parent) { 160 | QObject::connect(_parent, &EWidget::resizeEvent, this, &EToastr::SlotParentResized); 161 | QObject::connect(_parent, &EWidget::moveEvent, this, &EToastr::SlotParentMoved); 162 | } 163 | this->setAttribute(Qt::WA_Hover, true); 164 | setWindowFlags(Qt::FramelessWindowHint | 165 | (parentIsDesktop() ? Qt::Tool : Qt::Widget) | 166 | (parentIsDesktop() ? Qt::WindowStaysOnTopHint : Qt::Widget)); 167 | setAttribute(Qt::WA_TranslucentBackground); 168 | setAttribute(Qt::WA_ShowWithoutActivating); 169 | 170 | ui->textLabel->setStyleSheet(QString("QLabel {font: 600 10pt 'Segoe UI Semibold'; color: %1}").arg(textColor)); 171 | m_iconVisible = showIcon; ui->iconLabel->setVisible(showIcon); 172 | 173 | animationOpacity.setTargetObject(this); 174 | //animationOpacity.setPropertyName("popupOpacity"); 175 | animationOpacity.setPropertyName("timelapse"); 176 | connect(&animationOpacity, &QAbstractAnimation::finished, this, &EToastr::hide); 177 | 178 | 179 | 180 | timer = new QTimer(this); 181 | connect(timer, &QTimer::timeout, this, &EToastr::hideAnimation); 182 | } 183 | 184 | EToastr::~EToastr() { delete ui; } 185 | 186 | void EToastr::moveCustom(QPoint tarPoint, bool animated) 187 | { 188 | //qDebug() << "moveCustom: " << rect; 189 | if (!animated) 190 | move(tarPoint); 191 | else { 192 | QPoint curPoint = pos(); 193 | createAnimation(curPoint, tarPoint); 194 | } 195 | } 196 | 197 | QPropertyAnimation* EToastr::createAnimation(QPoint pointStart, QPoint pointEnd) { 198 | QPropertyAnimation* anim = new QPropertyAnimation(this, "pos"); 199 | anim->setStartValue(pointStart); 200 | anim->setEndValue(pointEnd); 201 | anim->setDuration(animateTimeout); 202 | anim->setEasingCurve(QEasingCurve::OutCubic); 203 | anim->start(QPropertyAnimation::DeleteWhenStopped); 204 | return anim; 205 | } 206 | 207 | void EToastr::setText(QString text) { ui->textLabel->setText(text); } 208 | 209 | void EToastr::setDuration(uint msec) { TIMEOUT = msec; } 210 | 211 | void EToastr::setShowDuration(uint msec) { this->showTimeout = msec; } 212 | 213 | void EToastr::setHideDuration(uint msec) { this->hideTimeout = msec; } 214 | 215 | void EToastr::setStyle(TOASTR_STYLE style) 216 | { 217 | #ifdef __MINGW32__ // Qt Creator 218 | QString imgpath = ":/img/"; 219 | #else // visual studio 220 | QString imgpath = "Ui/img/"; 221 | #endif 222 | switch (style) { 223 | case TOASTR_STYLE::MESSAGE: { 224 | backgroundColor = BLACK; 225 | setTextColor("#EFEFEF"); 226 | backgroundColor.setAlpha(this->opacity); 227 | QPixmap icon = QPixmap(imgpath+"message.png"); 228 | ui->iconLabel->setPixmap(icon); 229 | } break; 230 | case TOASTR_STYLE::SUCCESS: { 231 | backgroundColor = GREEN; 232 | setTextColor("#121212"); 233 | backgroundColor.setAlpha(this->opacity); 234 | QPixmap icon = QPixmap(imgpath+"check.png"); 235 | ui->iconLabel->setPixmap(icon); 236 | } break; 237 | case TOASTR_STYLE::WARNING: { 238 | backgroundColor = YELLOW; 239 | backgroundColor.setAlpha(this->opacity); 240 | QPixmap icon = QPixmap(imgpath+"warning.png"); 241 | ui->iconLabel->setPixmap(icon); 242 | } break; 243 | case TOASTR_STYLE::INFO: { 244 | backgroundColor = BLUE; 245 | backgroundColor.setAlpha(this->opacity); 246 | setTextColor("#EDEDED"); 247 | QPixmap icon = QPixmap(imgpath+"info.png"); 248 | ui->iconLabel->setPixmap(icon); 249 | } break; 250 | case TOASTR_STYLE::FAIL: { 251 | backgroundColor = RED; 252 | backgroundColor.setAlpha(this->opacity); 253 | setTextColor("#EFEFEF"); 254 | QPixmap icon = QPixmap(imgpath+"shield.png"); 255 | ui->iconLabel->setPixmap(icon); 256 | } break; 257 | } 258 | } 259 | 260 | void EToastr::setIcon(QPixmap pixmap) 261 | { 262 | ui->iconLabel->show(); 263 | ui->iconLabel->setPixmap(pixmap); 264 | } 265 | 266 | void EToastr::setBackgroundColor(QString color) { this->backgroundColor = color; } 267 | 268 | void EToastr::setOpacity(uint opacity) 269 | { 270 | this->backgroundColor.setAlpha(opacity); 271 | this->opacity = opacity; 272 | } 273 | 274 | void EToastr::setTextColor(QString color) { ui->textLabel->setStyleSheet(QString("QLabel {font: 600 10pt 'Segoe UI Semibold'; color: %1}").arg(color)); } 275 | 276 | void EToastr::hide() 277 | { 278 | //if (getPopupOpacity() == 0.0) { 279 | if (getTimelapse() == 0.0){ 280 | QPoint pointCurrent = pos(); 281 | QPoint pointEnd = pos(); 282 | int deltaX = 0, deltaY = 0; 283 | 284 | if (directionShow == TOASTR_DIRECTION::RIGHT_TO_LEFT) 285 | deltaX = (width() + MARGIN_WIDTH); 286 | else if (directionShow == TOASTR_DIRECTION::LEFT_TO_RIGHT) 287 | deltaX = -(width() + MARGIN_WIDTH); 288 | else if (directionShow == TOASTR_DIRECTION::BOTTOM_TO_TOP) 289 | deltaY = (height() + MARGIN_WIDTH); 290 | else if (directionShow == TOASTR_DIRECTION::TOP_TO_BOTTOM) 291 | deltaY = -(height() + MARGIN_WIDTH); 292 | 293 | 294 | 295 | pointEnd.setX(pointEnd.x() + deltaX); 296 | pointEnd.setY(pointEnd.y() + deltaY); 297 | 298 | //rectEnd.setWidth(geoCurrent.width()); // when rectEnd.x changes, rectEnd.width too changes. we don't want that. 299 | //rectEnd.setHeight(geoCurrent.height());// when rectEnd.y changes, rectEnd.height too changes. we don't want that. 300 | animationSlide = createAnimation(pointCurrent, pointEnd); 301 | 302 | m_closing = true; // Fix for Animation combine bug (2 animations at the same time) 303 | 304 | if(true)connect(animationSlide, &QPropertyAnimation::finished, 305 | [this]() { 306 | this->Quit(); 307 | }); 308 | } 309 | } 310 | 311 | void EToastr::show(TOASTR_DIRECTION direction) 312 | { 313 | directionShow = direction; 314 | vectorToastr.append(this); 315 | COUNT_TOASTR++; 316 | adjustSize(); 317 | 318 | QRect curRect = geometry(); QRect outRect; 319 | calculateStartXY(curRect, direction, outRect); 320 | setGeometry(outRect); 321 | 322 | 323 | //setWindowOpacity(0.0); 324 | 325 | animationOpacity.setDuration(this->showTimeout); 326 | animationOpacity.setStartValue(0.0); 327 | animationOpacity.setEndValue(1.0); 328 | 329 | updateLocations(); 330 | 331 | QWidget::show(); 332 | QObject::connect(&animationOpacity, &QPropertyAnimation::valueChanged, [this]() { 333 | this->update(); 334 | }); 335 | 336 | animationOpacity.start(); 337 | timer->start(TIMEOUT); 338 | } 339 | 340 | void EToastr::hideAnimation() 341 | { 342 | if (TIMEOUT == 0) 343 | return; 344 | timer->stop(); 345 | animationOpacity.setDuration(this->hideTimeout); 346 | animationOpacity.setStartValue(1.0f); 347 | animationOpacity.setEndValue(0.0f); 348 | animationOpacity.start(); 349 | } 350 | 351 | void EToastr::paintEvent(QPaintEvent* event) 352 | { 353 | Q_UNUSED(event); 354 | QPainter paint; 355 | paint.begin(this); 356 | paint.setRenderHints(QPainter::Antialiasing); 357 | paint.setBrush(QBrush(this->backgroundColor)); 358 | paint.setPen(Qt::NoPen); 359 | auto calcRect = this->rect(); 360 | /*calcRect.setX((calcRect.width() * animation.currentValue().toFloat()));*/ 361 | paint.drawRoundedRect(calcRect, ROUND_RECT, ROUND_RECT); 362 | paint.end(); 363 | } 364 | 365 | void EToastr::enterEvent(QEvent* event) 366 | { 367 | timer->stop(); 368 | this->backgroundColor.setAlpha(255); 369 | QWidget::enterEvent(event); 370 | } 371 | 372 | void EToastr::leaveEvent(QEvent* event) 373 | { 374 | timer->start(); 375 | this->backgroundColor.setAlpha(opacity); 376 | QWidget::leaveEvent(event); 377 | } 378 | 379 | void EToastr::mousePressEvent(QMouseEvent* event) 380 | { 381 | Q_UNUSED(event); 382 | Quit(); 383 | } 384 | QSize EToastr::sizeHint() const{ 385 | 386 | QSize result{maximumWidth(), MARGIN_WIDTH}; 387 | 388 | if (parentIsDesktop()) 389 | return result; 390 | 391 | auto cm = layout()->contentsMargins(); 392 | //result += QSize(0, cm.top() + cm.bottom()); 393 | 394 | 395 | ui->textLabel->adjustSize(); 396 | ui->iconLabel->adjustSize(); 397 | QSize size_label_text = ui->textLabel->size(); 398 | QSize size_label_icon = ui->iconLabel->size(); 399 | QFontMetrics fm(ui->textLabel->font()); 400 | int availableWidth = maximumWidth(); 401 | if (m_iconVisible) 402 | availableWidth -= ui->iconLabel->width(); 403 | 404 | // For calculate text height / Yazi uzun oldugunda asagi dogru widgetin uzamasi icin 405 | QRect text_rect = fm.boundingRect(QRect(0, 0, 406 | availableWidth - cm.top() - cm.bottom(), 0), 407 | Qt::TextDontClip | Qt::TextWordWrap, ui->textLabel->text()); 408 | 409 | 410 | result+= QSize(0, std::max(text_rect.height(), ui->iconLabel->height())); 411 | //return QSize(200,200); // test 412 | return result; 413 | } 414 | -------------------------------------------------------------------------------- /EToastr/EToastr.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/emrecpp/EToastr/0d2c3c412482d591114666c3a3005c9b89b970f9/EToastr/EToastr.h -------------------------------------------------------------------------------- /EToastr/EToastr.pro: -------------------------------------------------------------------------------- 1 | QT += widgets 2 | 3 | #TEMPLATE = lib 4 | DEFINES += TOASTR_LIBRARY 5 | 6 | CONFIG += c++11 7 | 8 | 9 | # You can make your code fail to compile if it uses deprecated APIs. 10 | # In order to do so, uncomment the following line. 11 | DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 12 | 13 | SOURCES += \ 14 | EToastr.cpp \ 15 | EWidget.cpp \ 16 | main.cpp 17 | 18 | HEADERS += \ 19 | EToastr.h \ 20 | EWidget.h 21 | 22 | FORMS += \ 23 | Ui/toastr.ui 24 | 25 | # Default rules for deployment. 26 | unix { 27 | target.path = /usr/lib 28 | } 29 | !isEmpty(target.path): INSTALLS += target 30 | 31 | RESOURCES += \ 32 | Ui/image.qrc 33 | -------------------------------------------------------------------------------- /EToastr/EToastr.qrc: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /EToastr/EToastr.vcxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | 14 | {0E6DDD96-6F4D-4AF4-96C2-7C487E80BAC3} 15 | QtVS_v304 16 | $(MSBuildProjectDirectory)\QtMsBuild 17 | 10.0 18 | 19 | 20 | 21 | Application 22 | v143 23 | 24 | 25 | Application 26 | v143 27 | 28 | 29 | 30 | 31 | 32 | 33 | Qt5.15.2 34 | core;gui;widgets 35 | debug 36 | 37 | 38 | Qt5.15.2 39 | core;gui;widgets 40 | release 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | stdcpp17 63 | 64 | 65 | 66 | 67 | stdcpp17 68 | 69 | 70 | 71 | 72 | true 73 | true 74 | ProgramDatabase 75 | Disabled 76 | MultiThreadedDebugDLL 77 | 78 | 79 | Windows 80 | true 81 | 82 | 83 | 84 | 85 | true 86 | true 87 | None 88 | MaxSpeed 89 | MultiThreadedDLL 90 | 91 | 92 | Windows 93 | false 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | -------------------------------------------------------------------------------- /EToastr/EToastr.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | qml;cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | qrc;rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | {99349809-55BA-4b9d-BF79-8FDBB0286EB3} 18 | ui 19 | 20 | 21 | {639EADAA-A684-42e4-A9AD-28FC9BCB8F7C} 22 | ts 23 | 24 | 25 | 26 | 27 | Resource Files 28 | 29 | 30 | Header Files 31 | 32 | 33 | Source Files 34 | 35 | 36 | 37 | 38 | Source Files 39 | 40 | 41 | Source Files 42 | 43 | 44 | 45 | 46 | Form Files 47 | 48 | 49 | 50 | 51 | Header Files 52 | 53 | 54 | -------------------------------------------------------------------------------- /EToastr/EToastr.vcxproj.user: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 2023-01-02T09:05:40.0039046Z 6 | 7 | 8 | 2023-01-02T09:05:40.1449036Z 9 | 10 | -------------------------------------------------------------------------------- /EToastr/EWidget.cpp: -------------------------------------------------------------------------------- 1 | #include "EWidget.h" 2 | 3 | EWidget::EWidget(QMainWindow *parent) : QMainWindow(parent) 4 | { 5 | 6 | } 7 | -------------------------------------------------------------------------------- /EToastr/EWidget.h: -------------------------------------------------------------------------------- 1 | #ifndef EWIDGET_H 2 | #define EWIDGET_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | class EWidget : public QMainWindow 10 | { 11 | Q_OBJECT 12 | public: 13 | explicit EWidget(QMainWindow *parent = nullptr); 14 | signals: 15 | void resizeEvent(QResizeEvent *event); 16 | void moveEvent(QMoveEvent *event); 17 | }; 18 | #endif // EWIDGET_H 19 | -------------------------------------------------------------------------------- /EToastr/Ui/image.qrc: -------------------------------------------------------------------------------- 1 | 2 | 3 | img/check.png 4 | img/error.png 5 | img/info.png 6 | img/message.png 7 | img/shield.png 8 | img/warning.png 9 | 10 | 11 | -------------------------------------------------------------------------------- /EToastr/Ui/img/check.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/emrecpp/EToastr/0d2c3c412482d591114666c3a3005c9b89b970f9/EToastr/Ui/img/check.png -------------------------------------------------------------------------------- /EToastr/Ui/img/desktop.ini: -------------------------------------------------------------------------------- 1 | [LocalizedFileNames] 2 | warning.png=@warning.png,0 3 | check.png=@check.png,0 4 | error.png=@error.png,0 5 | info.png=@info.png,0 6 | message.png=@message.png,0 7 | shield.png=@shield.png,0 8 | -------------------------------------------------------------------------------- /EToastr/Ui/img/error.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/emrecpp/EToastr/0d2c3c412482d591114666c3a3005c9b89b970f9/EToastr/Ui/img/error.png -------------------------------------------------------------------------------- /EToastr/Ui/img/info.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/emrecpp/EToastr/0d2c3c412482d591114666c3a3005c9b89b970f9/EToastr/Ui/img/info.png -------------------------------------------------------------------------------- /EToastr/Ui/img/message.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/emrecpp/EToastr/0d2c3c412482d591114666c3a3005c9b89b970f9/EToastr/Ui/img/message.png -------------------------------------------------------------------------------- /EToastr/Ui/img/shield.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/emrecpp/EToastr/0d2c3c412482d591114666c3a3005c9b89b970f9/EToastr/Ui/img/shield.png -------------------------------------------------------------------------------- /EToastr/Ui/img/warning.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/emrecpp/EToastr/0d2c3c412482d591114666c3a3005c9b89b970f9/EToastr/Ui/img/warning.png -------------------------------------------------------------------------------- /EToastr/Ui/toastr.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | Toastr 4 | 5 | 6 | 7 | 0 8 | 0 9 | 330 10 | 72 11 | 12 | 13 | 14 | 15 | 330 16 | 30 17 | 18 | 19 | 20 | 21 | 330 22 | 16777215 23 | 24 | 25 | 26 | Form 27 | 28 | 29 | 30 | 31 | 32 | 33 | 50 34 | 50 35 | 36 | 37 | 38 | 39 | 50 40 | 50 41 | 42 | 43 | 44 | 45 | 46 | 47 | true 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 0 56 | 0 57 | 58 | 59 | 60 | font: 600 10pt "Segoe UI Semibold"; 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | true 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | -------------------------------------------------------------------------------- /EToastr/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "EToastr.h" 4 | #include 5 | 6 | int main(int argc, char** argv) 7 | { 8 | QApplication app(argc, argv); 9 | 10 | 11 | EWidget* mainWin = new EWidget(); mainWin->setWindowTitle("EToastr | github.com/emrecpp"); 12 | if (1) 13 | mainWin->resize(640, 360); 14 | else 15 | mainWin->resize(1280, 720); 16 | 17 | bool test_wait_gui_load = 1; 18 | 19 | auto f = [mainWin](){ 20 | for (int i = 0; i < 3; i++) { 21 | 22 | // attr 23 | const bool PARENT_IS_DESKTOP = false; 24 | const bool NO_TIMEOUT = false; 25 | const bool SHOW_ICON = true; 26 | 27 | 28 | 29 | EToastr* toastr = new EToastr(((!PARENT_IS_DESKTOP) ? mainWin : nullptr), SHOW_ICON); 30 | toastr->setStyle(EToastr::TOASTR_STYLE::INFO); 31 | 32 | if (1) 33 | toastr->setText("Hello! " + QString::number(i + 1)); 34 | else 35 | toastr->setText(R"(Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.)" 36 | + QString::number(i + 1)); 37 | 38 | toastr->setDuration((!NO_TIMEOUT) ? (1000 * (i + 1)) : 0); 39 | if (1) 40 | toastr->show(EToastr::TOASTR_DIRECTION::RIGHT_TO_LEFT); 41 | else if (1) 42 | toastr->show(EToastr::TOASTR_DIRECTION::LEFT_TO_RIGHT); 43 | else if (0) 44 | toastr->show(EToastr::TOASTR_DIRECTION::BOTTOM_TO_TOP); 45 | else if (1) 46 | toastr->show(EToastr::TOASTR_DIRECTION::TOP_TO_BOTTOM); 47 | 48 | } 49 | }; 50 | 51 | if (test_wait_gui_load){ // waits GUI loading. 52 | QTimer::singleShot(500, [f]() {f();}); 53 | } 54 | else 55 | f(); 56 | mainWin->show(); 57 | return app.exec(); 58 | } 59 | -------------------------------------------------------------------------------- /Gifs/Bottom_parent_notimeout.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/emrecpp/EToastr/0d2c3c412482d591114666c3a3005c9b89b970f9/Gifs/Bottom_parent_notimeout.gif -------------------------------------------------------------------------------- /Gifs/Left_noparent_info.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/emrecpp/EToastr/0d2c3c412482d591114666c3a3005c9b89b970f9/Gifs/Left_noparent_info.gif -------------------------------------------------------------------------------- /Gifs/Left_parent_noicon.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/emrecpp/EToastr/0d2c3c412482d591114666c3a3005c9b89b970f9/Gifs/Left_parent_noicon.gif -------------------------------------------------------------------------------- /Gifs/Right_noparent_warning.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/emrecpp/EToastr/0d2c3c412482d591114666c3a3005c9b89b970f9/Gifs/Right_noparent_warning.gif -------------------------------------------------------------------------------- /Gifs/Right_parent.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/emrecpp/EToastr/0d2c3c412482d591114666c3a3005c9b89b970f9/Gifs/Right_parent.gif -------------------------------------------------------------------------------- /Gifs/Top_noparent.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/emrecpp/EToastr/0d2c3c412482d591114666c3a3005c9b89b970f9/Gifs/Top_noparent.gif -------------------------------------------------------------------------------- /Gifs/Top_parent.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/emrecpp/EToastr/0d2c3c412482d591114666c3a3005c9b89b970f9/Gifs/Top_parent.gif -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 Emre 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # EToastr 2 | Animated Notification/Toastr component for C++/Qt 3 | 4 | # EToastr Styles: 5 | + MESSAGE 6 | + SUCCESS 7 | + WARNING 8 | + INFO 9 | + FAIL 10 | 11 | 12 | # EToastr Directions: 13 | + RIGHT_TO_LEFT 14 | + TOP_TO_BOTTOM 15 | + BOTTOM_TO_TOP 16 | + LEFT_TO_RIGHT 17 | 18 | 19 | ## Direction = RIGHT_TO_LEFT, Style = SUCCESS, ParentIsDesktop = false, NoIcon = false, NoTimeout = false 20 | 21 | ![Message](Gifs/Right_parent.gif) 22 | 23 | 24 | ## Direction = LEFT_TO_RIGHT, Style = SUCCESS, ParentIsDesktop = false, NoIcon = ```true```, NoTimeout = false 25 | 26 | ![Message](Gifs/Left_parent_noicon.gif) 27 | 28 | 29 | ## Direction = BOTTOM_TO_TOP, Style = SUCCESS, ParentIsDesktop = false, NoIcon = false, NoTimeout = ```true``` 30 | 31 | ![Message](Gifs/Bottom_parent_notimeout.gif) 32 | 33 | 34 | 35 | ## Direction = TOP_TO_BOTTOM, Style = SUCCESS, ParentIsDesktop = ```true```, NoIcon = false, NoTimeout = false 36 | 37 | ![Message](Gifs/Top_noparent.gif) 38 | 39 | 40 | 41 | ## Direction = LEFT_TO_RIGHT, Style = ```INFO```, ParentIsDesktop = true, NoIcon = false, NoTimeout = false 42 | 43 | ![Message](Gifs/Left_noparent_info.gif) 44 | 45 | # Please don't forget to star the project, thanks :) 46 | --------------------------------------------------------------------------------