Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <cstdlib>
- #include <gtk/gtk.h>
- #include <string>
- using namespace std;
- /* Надписи, в которых мы будем отображать текст */
- GtkWidget *labelVolume1, *labelVolume2, *label1, *label2, *labelDisplay1, *labelDisplay2;
- /* Максимальная ёмкость сосудов с жидкостью */
- const int MAX_VOLUME_1 = 10;
- const int MAX_VOLUME_2 = 23;
- /* Текущая ёмкость сосудов с жидкостью*/
- int v1 = 0;
- int v2 = 0;
- /* Обновить надписи в соответствии с текущей ёмкостью*/
- void updateLabels()
- {
- /* Буффер, в котором будем формировать строку для надписи */
- char buf[30];
- /* Формируем строку с объёмом первого сосуда в виде v1/MAX_VOLUME_1 */
- sprintf(buf, "%d/%d", v1, MAX_VOLUME_1);
- gtk_label_set_label(GTK_LABEL(labelVolume1), buf);
- /* Формируем строку с объёмом первого сосуда в виде v2/MAX_VOLUME_2 */
- sprintf(buf, "%d/%d", v2, MAX_VOLUME_2);
- gtk_label_set_label(GTK_LABEL(labelVolume2), buf);
- /* Формируем визуальное отображение первого сосуда */
- /* Тег <tt> делает так, что каждая буква занимает одинаковую ширину */
- /* Тег <span> используем, чтобы покрасить занятую часть в синий цвет */
- string s1 = "<tt>[<span bgcolor='blue'>";
- /* Добавляем вертикальные палочки по количеству жидкости в сосуде */
- for(int i=0;i<v1;i++)
- s1 += '|';
- /* закрываем тег с синим фоном */
- s1 += "</span>";
- /* незанятую часть заполняем символом точка */
- for(int i=v1;i<MAX_VOLUME_1;i++)
- s1 += '.';
- /* закрываем тег <tt> */
- s1 += "]</tt>";
- /* Устанавливаем содержимое надписи, указав, что в строке используется язык разметки */
- /* Поскольку s1 это строка, а на вход нужен массив символов, вызываем метод c_str(), чтобы его получить*/
- gtk_label_set_markup(GTK_LABEL(labelDisplay1), s1.c_str());
- /* Аналогично форматируем строку для второго сосуда */
- string s2 = "<tt>[<span bgcolor='blue'>";
- for(int i=0;i<v2;i++)
- s2 += '|';
- s2 += "</span>";
- for(int i=v2;i<MAX_VOLUME_2;i++)
- s2 += '.';
- s2 += "]</tt>";
- gtk_label_set_markup(GTK_LABEL(labelDisplay2), s2.c_str());
- }
- /* Функция, которая обрабатывает нажатие на кнопку "Наполнить 1"*/
- void fill1()
- {
- /* Заполняем ёмкость 1 до максимального объёма */
- v1 = MAX_VOLUME_1;
- /* Обновляем надписи в окне*/
- updateLabels();
- }
- /* Функция, которая обрабатывает нажатие на кнопку "Наполнить 2"*/
- void fill2()
- {
- /* Заполняем ёмкость 2 до максимального объёма */
- v2 = MAX_VOLUME_2;
- /* Обновляем надписи в окне */
- updateLabels();
- }
- /* Функция, которая обрабатывает нажатие на кнопку "Вылить из 1"*/
- void empty1()
- {
- /* Обнуляем ёмкость 1 */
- v1 = 0;
- /* Обновляем надписи в окне */
- updateLabels();
- }
- /* Функция, которая обрабатывает нажатие на кнопку "Вылить из 2"*/
- void empty2()
- {
- /* Обнуляем ёмкость 1 */
- v2 = 0;
- /* Обновляем надписи в окне */
- updateLabels();
- }
- /* Функция, которая обрабатывает нажатие на кнопку "Перелить из 1 в 2"*/
- void move1to2()
- {
- /* v1 -> v2 */
- /* Если v1 целиком поместится в незанятой ёмкости v2*/
- if ( v1 <= MAX_VOLUME_2 - v2 )
- {
- /* переливаем v1 целиком и обнуляем*/
- v2 += v1;
- v1 = 0;
- }
- else
- {
- /* иначе переливаем из v1 столько, сколько в v2 было незанято */
- v1 -= MAX_VOLUME_2 - v2;
- v2 = MAX_VOLUME_2;
- }
- /* Обновляем надписи в окне */
- updateLabels();
- }
- /* Функция, которая обрабатывает нажатие на кнопку "Перелить из 2 в 1"*/
- void move2to1()
- {
- /* v2 -> v1 */
- /* Если v1 целиком поместится в незанятой ёмкости v2*/
- if ( v2 <= MAX_VOLUME_1 - v1 )
- {
- /* переливаем v2 целиком и обнуляем*/
- v1 += v2;
- v2 = 0;
- }
- else
- {
- /* иначе переливаем из v2 столько, сколько в v1 было незанято */
- v2 -= MAX_VOLUME_1 - v1;
- /* v1 теперь целиком занят */
- v1 = MAX_VOLUME_1;
- }
- /* Обновляем надписи в окне */
- updateLabels();
- }
- /*
- *
- */
- int main(int argc, char** argv) {
- gtk_init(&argc, &argv);
- GtkWidget *window, *vbox, *grid1, *grid2;
- GtkWidget *buttonFill1, *buttonFill2, *buttonEmpty1, *buttonEmpty2, *buttonMove12, *buttonMove21, *exitButton;
- /* Создаём окно */
- window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
- /* Контейнер для вертикального выравнивания компонент окна */
- vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 1);
- /* Контейнер-таблица для надписей */
- grid1 = gtk_grid_new();
- /* Контейнер-таблица для кнопок */
- grid2 = gtk_grid_new();
- /* Создаём надписи с номерами ёмкостей*/
- label1 = gtk_label_new("1:");
- label2 = gtk_label_new("2:");
- /* Создаём надписи с текстом о текущем заполнении. Они будут заполнены после вызова updateLabels() */
- labelVolume1 = gtk_label_new("");
- labelVolume2 = gtk_label_new("");
- /* Создаём надписи с визуальным представлением текущего заполнения. Они будут заполнены после вызова updateLabels() */
- labelDisplay1 = gtk_label_new("");
- labelDisplay2 = gtk_label_new("");
- /* Создаём кнопки с управлением */
- buttonFill1 = gtk_button_new_with_label("Наполнить 1");
- buttonFill2 = gtk_button_new_with_label("Наполнить 2");
- buttonEmpty1 = gtk_button_new_with_label("Вылить из 1");
- buttonEmpty2 = gtk_button_new_with_label("Вылить из 2");
- buttonMove12= gtk_button_new_with_label("Перелить из 1 в 2");
- buttonMove21 = gtk_button_new_with_label("Перелить из 2 в 1");
- exitButton = gtk_button_new_with_label("Выход");
- /* Размещаем объекты */
- /* Размещаем vbox, чтобы вертикально выстроить все дочерние объекты */
- gtk_container_add(GTK_CONTAINER(window), vbox);
- /* Размещаем в нём сетку с надписями, сетку с кнопками управления и кнопку выход */
- gtk_box_pack_start(GTK_BOX(vbox), grid1, false, false, 1);
- gtk_box_pack_start(GTK_BOX(vbox), grid2, false, false, 1);
- gtk_box_pack_end(GTK_BOX(vbox), exitButton, false, false, 1);
- /* Размещаем надписи в сетке grid1 */
- /* label1 | label2
- * -----------------------------
- * labelDisplay1 | labelDisplay2
- * -----------------------------
- * labelVolume1 | labelVolume2
- */
- gtk_grid_attach(GTK_GRID(grid1), label1, 0, 0, 1, 1);
- gtk_grid_attach(GTK_GRID(grid1), labelDisplay1, 0, 1, 1, 1);
- gtk_grid_attach(GTK_GRID(grid1), labelVolume1, 0, 2, 1, 1);
- gtk_grid_attach(GTK_GRID(grid1), label2, 1, 0, 1, 1);
- gtk_grid_attach(GTK_GRID(grid1), labelDisplay2, 1, 1, 1, 1);
- gtk_grid_attach(GTK_GRID(grid1), labelVolume2, 1, 2, 1, 1);
- /* Размещаем кнопки в сетке grid2 */
- /* buttonFill1 | buttonFill2
- * -----------------------------
- * buttonEmpty1 | buttonEmpty2
- * -----------------------------
- * buttonMove12 | buttonMove21
- */
- gtk_grid_attach(GTK_GRID(grid2), buttonFill1, 0, 0, 1, 1);
- gtk_grid_attach(GTK_GRID(grid2), buttonEmpty1, 0, 1, 1, 1);
- gtk_grid_attach(GTK_GRID(grid2), buttonFill2, 1, 0, 1, 1);
- gtk_grid_attach(GTK_GRID(grid2), buttonEmpty2, 1, 1, 1, 1);
- gtk_grid_attach(GTK_GRID(grid2), buttonMove12, 0, 2, 1, 1);
- gtk_grid_attach(GTK_GRID(grid2), buttonMove21, 1, 2, 1, 1);
- /* Добавляем между колонками отступ в 3 пикселя */
- gtk_grid_set_column_spacing(GTK_GRID(grid1), 3);
- /* Добавляем выравнивание сеток по середине окна по горизонтали*/
- gtk_widget_set_halign(grid1, GTK_ALIGN_CENTER);
- gtk_widget_set_halign(grid2, GTK_ALIGN_CENTER);
- /* Поворачиваем надписи с уровнем жидкости на 90 градусов */
- gtk_label_set_angle(GTK_LABEL(labelDisplay1), 90);
- gtk_label_set_angle(GTK_LABEL(labelDisplay2), 90);
- /* Выравниваем надписи так, чтобы они прилегали к нижней границе */
- gtk_widget_set_valign(labelDisplay1, GTK_ALIGN_END);
- gtk_widget_set_valign(labelDisplay2, GTK_ALIGN_END);
- /* Заполняем содержимое надписей в окне */
- updateLabels();
- /* Отображаем окно*/
- gtk_widget_show_all(window);
- /* Добавляем функции для обработки нажатия на кнопки управления */
- g_signal_connect(G_OBJECT(buttonFill1), "clicked", (GCallback)fill1, NULL);
- g_signal_connect(G_OBJECT(buttonFill2), "clicked", (GCallback)fill2, NULL);
- g_signal_connect(G_OBJECT(buttonEmpty1), "clicked", (GCallback)empty1, NULL);
- g_signal_connect(G_OBJECT(buttonEmpty2), "clicked", (GCallback)empty2, NULL);
- g_signal_connect(G_OBJECT(buttonMove12), "clicked", (GCallback)move1to2, NULL);
- g_signal_connect(G_OBJECT(buttonMove21), "clicked", (GCallback)move2to1, NULL);
- /* Указываем, что при нажатии кнопки выход и уничтожении окна необходимо прервать цикл обработки событий с помощью gtk_main_quit */
- g_signal_connect(G_OBJECT(exitButton), "clicked", (GCallback)gtk_main_quit, NULL);
- g_signal_connect(G_OBJECT(window), "destroy", (GCallback)gtk_main_quit, NULL);
- /* Запускаем цикл обработки событий */
- gtk_main();
- return 0;
- }
Add Comment
Please, Sign In to add comment