@@ -49,15 +49,26 @@ namespace easy_plot {
4949 /* * цвет рамки (R G B) */
5050 double fr = 1.0 , fg = 1.0 , fb = 1.0 ;
5151 // @}
52+ // @{
53+ /* * цвет текста (R G B) */
54+ double tr = 0.5 , tg = 0.5 , tb = 0.5 ;
55+ // @}
56+ // @{
57+ /* * цвет указателя мыши (R G B) */
58+ double mr = 0.3 , mg = 0.3 , mb = 0.3 ;
59+ // @}
5260 bool is_zero_x_line = false ; /* *< Линия нуля, если true то линия рисуется */
5361 bool is_zero_y_line = false ; /* *< Линия нуля, если true то линия рисуется */
54- bool is_grid = true ;
62+ bool is_grid = true ; /* *< Сетка */
5563 double grid_period = 0.1 ; /* *< Период сетки */
64+ void *font = GLUT_BITMAP_8_BY_13; /* *< Шрифт текста */
5665
5766 /* * \brief Инициализация параметров Окна по умолчанию
5867 */
5968 WindowSpec () { };
6069 };
70+
71+ static WindowSpec default_window_style; /* *< Стиль окна по умолчанию */
6172// ------------------------------------------------------------------------------
6273 /* * \brief Класс для хранения данных стиля линии
6374 */
@@ -98,9 +109,13 @@ namespace easy_plot {
98109 std::vector<std::vector<double >> raw_data_y; /* *< Данные для рисования всех графиков */
99110 std::vector<std::vector<double >> raw_data_x; /* *< Данные для рисования всез графиков */
100111 std::vector<LineSpec> line_style; /* *< Стили линий для всех графиков */
101- std::atomic<bool > is_raw_data;
102- double min_x, max_x, min_y, max_y; /* *< Минимумы и максимумы данных для рисования графиков */
103- std::atomic<bool > is_window_init;
112+ // @{
113+ /* * Минимумы и максимумы данных для рисования графиков */
114+ double min_x = 0.0 , max_x = 0.0 , min_y = 0.0 , max_y = 0.0 ;
115+ // @}
116+ bool is_window_init = false ; /* *< Флаг инициализации окна */
117+ bool is_raw_data = false ; /* *< Флаг инициализации данных графика */
118+
104119 /* * \brief Получить нормализованное значение Y
105120 * \param ny не нормализованное значение
106121 * \return Нормализованное значение Y
@@ -160,19 +175,61 @@ namespace easy_plot {
160175 return temp;
161176 }
162177
163- void set_start_state () {
164- is_raw_data = false ;
165- is_window_init = false ;
178+ /* * \brief Напечатать текст
179+ * \param x позиция в окне по оси X
180+ * \param y позиция в окне по оси Y
181+ * \param spacing дополнителный пробел
182+ * \param font шрифт
183+ * \param str строка
184+ */
185+ void render_spaced_bitmap_string (
186+ float x,
187+ float y,
188+ float spacing,
189+ void *font,
190+ std::string str) {
191+ glRasterPos2f (x, y);
192+ for (size_t i = 0 ; i < str.size (); ++i) {
193+ glutBitmapCharacter (font, (int )str[i]);
194+ x = x + glutBitmapWidth (font, (int )str[i]) + spacing;
195+ }
166196 }
167197
168198 public:
169199 static Drawing* current_instance; /* *< Указатель на класс */
170200 std::string window_name; /* *< Имя окна графика */
171201 int win_id = -1 ; /* *< Униклаьный ID графика */
202+ // @{
203+ /* * Актуальные ширина и высота окна */
204+ int width = 0 , height = 0 ;
205+ // @}
206+ // @{
207+ /* * Позиция мыши */
208+ double mouse_x = 0.0 , mouse_y = 0.0 ;
209+ // @}
210+ bool is_use_mouse = false ; /* *< Флаг использования мыши в окне */
172211
173- Drawing () {
174- set_start_state ();
175- };
212+ /* * \brief Установить позицию мыши
213+ * \param x координаты по оси X
214+ * \param y координаты по оси Y
215+ */
216+ void set_mouse_position (int x, int y) {
217+ if (width == 0 || height == 0 ) return ;
218+ double max_len = 2.0 + window_style.indent * 2.0 ;
219+ mouse_x = ((double )x / (double ) width) * max_len - max_len / 2.0 ;
220+ mouse_y = ((double )y / (double ) height) * max_len - max_len / 2.0 ;
221+ is_use_mouse = true ;
222+ }
223+
224+ /* * \brief Закрыть окно
225+ * Данная функция нужна для внутреннего использования
226+ */
227+ void close () {
228+ is_window_init = false ;
229+ is_raw_data = false ;
230+ }
231+
232+ Drawing () { };
176233
177234 /* * \brief Инициализация графика
178235 * \param name имя окна
@@ -228,7 +285,6 @@ namespace easy_plot {
228285
229286 template <typename T1>
230287 Drawing (std::string name, WindowSpec wstyle, std::vector<T1> &y, LineSpec style) {
231- set_start_state ();
232288 init (name, wstyle, y, style);
233289 };
234290
@@ -249,7 +305,6 @@ namespace easy_plot {
249305
250306 template <typename T1, typename T2>
251307 Drawing (std::string name, WindowSpec wstyle, std::vector<T1> &x, std::vector<T2> &y, LineSpec style) {
252- set_start_state ();
253308 init (name, wstyle, x, y, style);
254309 };
255310
@@ -266,7 +321,6 @@ namespace easy_plot {
266321
267322 template <typename T1>
268323 Drawing (std::string name, WindowSpec wstyle, std::vector<std::vector<T1>> &vec, std::vector<LineSpec> &styles) {
269- set_start_state ();
270324 init (name, wstyle, vec, styles);
271325 };
272326
@@ -305,6 +359,16 @@ namespace easy_plot {
305359 glVertex2f (get_x (raw_data_x[nl][i + 1 ]), get_y (raw_data_y[nl][i + 1 ]));
306360 }
307361 }
362+
363+ // рисуем мышь
364+ if (is_use_mouse) {
365+ glColor3f (window_style.mr , window_style.mg , window_style.mb );
366+ glVertex2f (-1 , mouse_y);
367+ glVertex2f (1 , mouse_y);
368+ glVertex2f (mouse_x, -1 );
369+ glVertex2f (mouse_x, 1 );
370+ }
371+
308372 // рисуем рамку
309373 glColor3f (window_style.fr , window_style.fg , window_style.fb );
310374 glVertex2f (-1 , 1 );
@@ -323,6 +387,8 @@ namespace easy_plot {
323387 glFlush ();
324388 }
325389
390+ /* * \brief Обработчик перерисовки экрана
391+ */
326392 static void update () {
327393 int win_id = glutGetWindow ();
328394 for (size_t i = 0 ; i < drawings.size (); ++i) {
@@ -333,6 +399,45 @@ namespace easy_plot {
333399 }
334400 }
335401
402+ /* * \brief Событие закрытия окна
403+ */
404+ static void event_closing () {
405+ int win_id = glutGetWindow ();
406+ for (size_t i = 0 ; i < drawings.size (); ++i) {
407+ if (drawings[i]->win_id == win_id) {
408+ drawings[i]->close ();
409+ drawings.erase (drawings.begin () + i);
410+ break ;
411+ }
412+ }
413+ }
414+
415+ /* * \brief Событие движения мыши внутри окна
416+ */
417+ static void event_mouse_move (int x, int y) {
418+ int win_id = glutGetWindow ();
419+ for (size_t i = 0 ; i < drawings.size (); ++i) {
420+ if (drawings[i]->win_id == win_id) {
421+ drawings[i]->set_mouse_position (x, y);
422+ } else {
423+ drawings[i]->is_use_mouse = false ;
424+ }
425+ }
426+ }
427+
428+ /* * \brief Обработчик изменения размера окна
429+ */
430+ static void event_reshape (int width, int height) {
431+ int win_id = glutGetWindow ();
432+ for (size_t i = 0 ; i < drawings.size (); ++i) {
433+ if (drawings[i]->win_id == win_id) {
434+ drawings[i]->width = width;
435+ drawings[i]->height = height;
436+ break ;
437+ }
438+ }
439+ }
440+
336441 /* * \brief Обновить состояние окна
337442 */
338443 void update_window () {
@@ -357,6 +462,9 @@ namespace easy_plot {
357462 -1.0 - window_style.indent , 1.0 + window_style.indent ,
358463 -1.0 , 1.0 );
359464 ::glutDisplayFunc (update);
465+ ::glutCloseFunc (event_closing);
466+ ::glutReshapeFunc (event_reshape);
467+ ::glutMotionFunc (event_mouse_move);
360468 glutMainLoopEvent ();
361469 is_window_init = true ;
362470 }
@@ -442,7 +550,7 @@ namespace easy_plot {
442550 int plot (std::string name, int count, ...) {
443551 va_list args;
444552 va_start (args, count);
445- int err = plot<T1>(name, WindowSpec () , count, args);
553+ int err = plot<T1>(name, default_window_style , count, args);
446554 va_end (args);
447555 return err;
448556 }
@@ -462,9 +570,9 @@ namespace easy_plot {
462570 drawings_mutex.lock ();
463571 int pos = get_pos_plot (name);
464572 if (pos >= 0 ) {
465- drawings[pos]->init (name, WindowSpec () , x, y, style);
573+ drawings[pos]->init (name, default_window_style , x, y, style);
466574 } else {
467- drawings.push_back (new Drawing (name, WindowSpec () , x, y, style));
575+ drawings.push_back (new Drawing (name, default_window_style , x, y, style));
468576 }
469577 drawings_mutex.unlock ();
470578 return EASY_PLOT_OK;
@@ -484,9 +592,11 @@ namespace easy_plot {
484592 drawings_mutex.lock ();
485593 int pos = get_pos_plot (name);
486594 if (pos >= 0 ) {
487- drawings[pos]->init (name, WindowSpec () , y, style);
595+ drawings[pos]->init (name, default_window_style , y, style);
488596 } else {
489- drawings.push_back (new Drawing (name, WindowSpec (), y, style));
597+ std::cout << " push_back" << std::endl;
598+ drawings.push_back (new Drawing (name, default_window_style, y, style));
599+ std::cout << " push_back 2" << std::endl;
490600 }
491601 drawings_mutex.unlock ();
492602 return EASY_PLOT_OK;
0 commit comments