Notify и тайм менеджмент. Часть 2

В предыдущей статье было построено консольное приложение, отсчитывающее временные промежутки работы и отдыха. Так как при работе не предполагается постоянно «смотреть на часы», полезно добавить механизм оповещения. Для оповещений будем использовать библиотеку notify.

Что даёт notify?

Для нас принципиальной особенностью является то, что notify позволяет выводить небольшие сообщения поверх открытых окон. Причем каких-то действий в ответ эти сообщения не требуют. Если пользователь запустил наше консольное приложение и свернул его, о начале и конце перерыва он обязательно узнает.

Gnome notify example

Необходимые функции и переменные

Так как используемая библиотека написана на языке C, заголовочный файл для неё подключим следующим образом:

extern "C" {
#include <libnotify/notify.h>
}

Для использования оповещений нужно инициализировать библиотеку и создать оповещение:

NotifyNotification* hNotification;
notify_init("myPomodoro");
hNotification = notify_notification_new("", "", "dialog-information");
notify_notification_set_timeout(hNotification, 1);

Здесь первая строка — указатель на оповещение, вторая — инициализация с указанием заголовка приложения, третья — создание нового оповещения (первый параметр — заголовок оповещения, второй — текст оповещения, третий — имя иконки), четвертая — время присутствия на переднем плане.

Имена иконок можно подобрать с помощью этого ресурса. Что предпочтительнее — выбрать стандартную иконку или нарисовать свою, решать вам. Во всяком случае использование стандартных иконок повышает вероятность влиться в стилистику текущей темы.

Осталось отобразить сообщение:

notify_notification_update(hNotification, "Работа", "25 минут", "appointment-new");
notify_notification_show(hNotification, 0);

Здесь первая строка — обновление параметров сообщения, вторая — функция, отображающая сообщение. Параметр 0 говорит о том, что сообщение не исчезнет, пока пользователь не щелкнет по нему мышкой. Таким образом информация через 1 секунду пропадает с экрана, но останется доступной для прочтения, если «проглядел».

Makefile

Следует отметить, что notify является частью gtk. Следовательно необходимо учесть соответствующие параметры компиляции.

TARGET = myPomodoro
CC = g++
LIBS = -lnotify
CFLAGS = -std=c++11 `pkg-config gtk+-2.0 --cflags`
OBJ = main.o
app: ${OBJ}
	${CC} ${CFLAGS} ${OBJ} ${LIBS} -o ${TARGET}
main.o: main.cpp
	${CC} ${CFLAGS} -c main.cpp 
clean:
	rm -rf *.o ${TARGET}

Исходник

#include <chrono>
#include <stdio.h>
#include <thread>

extern "C" {
#include <libnotify/notify.h>
};


using namespace std;
using namespace std::chrono;

int main(int argc, char* argv[]) {

	high_resolution_clock::time_point t1;
	high_resolution_clock::time_point t2;

	double intervals[] = {25*60, 5*60, 15*60};
	const char* names[] = {"Working", "Break", "Long break"};
	char buf[10] = {0};
	int curInt = 0;
	int count = 4;
	bool timerOn = false;

	NotifyNotification* hNotification;
	notify_init("myPomodoro");
	hNotification = notify_notification_new("", "", "dialog-information");
	notify_notification_set_timeout(hNotification, 1);

	while(true) {
		if(timerOn) {
			t2 = high_resolution_clock::now();
			duration<double> timeSpan = duration_cast<duration<double>>(t2 - t1);
			double d = timeSpan.count();
			int timeLeft = (int)(intervals[curInt] - d);
			printf("\r%02d:%02d %s              ", timeLeft/60, timeLeft % 60, names[curInt]);
			fflush(stdout);

			if(d >= intervals[curInt]) {
				timerOn = false;
				curInt++;
			} else
				std::this_thread::sleep_for(std::chrono::milliseconds(1000));
		} else {

			if(curInt == 1) {
				if(count <= 0) {
					curInt = 2;
					count = 4;
				};
			} else 	if(curInt == 2 || curInt == 3) {
				while(buf[0] != 'n' && buf[0] != 'y') {
					printf("                          \r");
					printf("Start work? [y/n]");
					scanf("%9s", buf);
				};
				if(buf[0] == 'n') break;
				buf[0] = 0;
				curInt = 0;
				count--;
			};

			switch(curInt) {
				case 0:
					notify_notification_update(hNotification, "Test", "25 min work", "appointment-new");
					break;
				case 1:
					notify_notification_update(hNotification, "Test", "5 min break", "appointment-new");
					break;
				case 2:
					notify_notification_update(hNotification, "Test", "15 min break", "appointment-new");
					break;
				default:
					break;
			};

			notify_notification_show(hNotification, 0);
			
			t1 = high_resolution_clock::now();
			timerOn = true;
		};

	};

	return 0;
};

Теперь в момент начала периода работы или отдыха будет высвечиваться оповещение с соответствующим текстом.

Добавить комментарий

Ваш e-mail не будет опубликован.