gboolean set_widgets_defaults(GtkWidget *mvbox, track_t *t, GdkRGBA *color) { GtkWidget *hbox, *vbox, *label, *hbox2, *sep, *button, *img, *eventBox; gint i = 0; GdkRGBA buttonNormal = {1, 1, 1, 0.2}; GdkRGBA buttonSelected = {1, 1, 1, 0.6}; hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 10); gtk_box_pack_start(GTK_BOX(mvbox), hbox, 0, 0, 1); /* album image */ eventBox = gtk_event_box_new(); gtk_event_box_set_visible_window(GTK_EVENT_BOX(eventBox), 0); gtk_widget_set_events(eventBox, GDK_BUTTON_PRESS_MASK); t->trackw.image = gtk_image_new(); gtk_container_add(GTK_CONTAINER(eventBox), t->trackw.image); g_signal_connect(eventBox, "button_press_event", G_CALLBACK(show_player_callback), NULL); gtk_box_pack_start(GTK_BOX(hbox), eventBox, 0, 0, 0); /* track info: name, artist, album */ vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0); gtk_box_pack_start(GTK_BOX(hbox), vbox, 0, 0, 0); t->trackw.label.name = gtk_label_new(NULL); gtk_misc_set_alignment(GTK_MISC(t->trackw.label.name), 0, 0); /* create the layout to be able to scrol the label's contents */ t->trackw.layout.name = gtk_layout_new(NULL, NULL); /* set size otherwise it won't show up */ gtk_widget_set_size_request(t->trackw.layout.name, SCROLL_SIZE_W, SCROLL_SIZE_H); /* make layout's color the same as the window's */ gtk_widget_override_background_color(t->trackw.layout.name, GTK_STATE_FLAG_NORMAL, color); gtk_layout_put(GTK_LAYOUT(t->trackw.layout.name), t->trackw.label.name, 0, 0); t->trackw.label.artist = gtk_label_new(NULL); gtk_misc_set_alignment(GTK_MISC(t->trackw.label.artist), 0, 0); t->trackw.layout.artist = gtk_layout_new(NULL, NULL); gtk_widget_set_size_request(t->trackw.layout.artist, SCROLL_SIZE_W-23, SCROLL_SIZE_H); gtk_widget_override_background_color(t->trackw.layout.artist, GTK_STATE_FLAG_NORMAL, color); gtk_layout_put(GTK_LAYOUT(t->trackw.layout.artist), t->trackw.label.artist, 0, 0); t->trackw.label.album = gtk_label_new(NULL); gtk_misc_set_alignment(GTK_MISC(t->trackw.label.album), 0, 0); t->trackw.layout.album = gtk_layout_new(NULL, NULL); gtk_widget_set_size_request(t->trackw.layout.album, SCROLL_SIZE_W-40, SCROLL_SIZE_H); gtk_widget_override_background_color(t->trackw.layout.album, GTK_STATE_FLAG_NORMAL, color); gtk_layout_put(GTK_LAYOUT(t->trackw.layout.album), t->trackw.label.album, 0, 0); /* put the name, artist and album at their places */ gtk_box_pack_start(GTK_BOX(vbox), t->trackw.layout.name, 0, 0, 0); hbox2 = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0); gtk_box_pack_start(GTK_BOX(vbox), hbox2, 0, 0, 0); label = gtk_label_new(NULL); gtk_misc_set_alignment(GTK_MISC(label), 0, 0); gtk_label_set_markup(GTK_LABEL(label), "<span font='Sans 11' font_style='italic'" "color='#FFFFFF'>by </span>"); gtk_box_pack_start(GTK_BOX(hbox2), label, 0, 0, 0); gtk_box_pack_start(GTK_BOX(hbox2), t->trackw.layout.artist, 0, 0, 0); hbox2 = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0); gtk_box_pack_start(GTK_BOX(vbox), hbox2, 0, 0, 0); label = gtk_label_new(NULL); gtk_misc_set_alignment(GTK_MISC(label), 0, 0); gtk_label_set_markup(GTK_LABEL(label), "<span font='Sans 11' font_style='italic'" "color='#FFFFFF'>from </span>"); gtk_box_pack_start(GTK_BOX(hbox2), label, 0, 0, 0); gtk_box_pack_start(GTK_BOX(hbox2), t->trackw.layout.album, 0, 0, 0); /* puts the genre, rating, year, and playcount */ hbox2 = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0); gtk_box_pack_start(GTK_BOX(vbox), hbox2, 0, 0, 0); t->trackw.genre = gtk_label_new(NULL); gtk_misc_set_alignment(GTK_MISC(t->trackw.genre), 0, 0); gtk_box_pack_start(GTK_BOX(hbox2), t->trackw.genre, 0, 0, 0); sep = gtk_separator_new(GTK_ORIENTATION_VERTICAL); gtk_box_pack_start(GTK_BOX(hbox2), sep, 0, 0, 3); for (i = 0; i < 5; i++) { t->trackw.stars[i] = gtk_image_new(); gtk_box_pack_start(GTK_BOX(hbox2), t->trackw.stars[i], 0, 0, 1); } sep = gtk_separator_new(GTK_ORIENTATION_VERTICAL); gtk_box_pack_start(GTK_BOX(hbox2), sep, 0, 0, 3); t->trackw.year = gtk_label_new(NULL); gtk_misc_set_alignment(GTK_MISC(t->trackw.year), 0, 0); gtk_box_pack_start(GTK_BOX(hbox2), t->trackw.year, 0, 0, 0); sep = gtk_separator_new(GTK_ORIENTATION_VERTICAL); gtk_box_pack_start(GTK_BOX(hbox2), sep, 0, 0, 3); t->trackw.playcount = gtk_label_new(NULL); gtk_misc_set_alignment(GTK_MISC(t->trackw.playcount), 0, 0); gtk_box_pack_start(GTK_BOX(hbox2), t->trackw.playcount, 0, 0, 0); /* puts the current position, the slider showing the progress * and track length */ hbox2 = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0); gtk_box_pack_start(GTK_BOX(vbox), hbox2, 0, 0, 0); t->trackw.position = gtk_label_new(NULL); gtk_misc_set_alignment(GTK_MISC(t->trackw.position), 0, 0); gtk_box_pack_start(GTK_BOX(hbox2), t->trackw.position, 0, 0, 0); t->trackw.slider = gtk_scale_new(GTK_ORIENTATION_HORIZONTAL, NULL); gtk_widget_set_size_request(t->trackw.slider, 170, -1); gtk_scale_set_draw_value(GTK_SCALE(t->trackw.slider), 0); gtk_range_set_show_fill_level(GTK_RANGE(t->trackw.slider), 1); gtk_range_set_restrict_to_fill_level(GTK_RANGE(t->trackw.slider), 0); /*g_signal_connect(t->trackw.slider, "value-changed", G_CALLBACK(slider_value_changed), NULL);*/ gtk_box_pack_start(GTK_BOX(hbox2), t->trackw.slider, 0, 0, 0); t->trackw.length = gtk_label_new(NULL); gtk_misc_set_alignment(GTK_MISC(t->trackw.length), 0, 0); gtk_box_pack_start(GTK_BOX(hbox2), t->trackw.length, 0, 0, 0); /* the player controls */ hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 5); gtk_box_pack_start(GTK_BOX(mvbox), hbox, 0, 0, 0); img = gtk_image_new_from_pixbuf(gdk_pixbuf_new_from_xpm_data(prev_xpm)); button = gtk_button_new(); gtk_widget_override_background_color(button, GTK_STATE_FLAG_NORMAL, &buttonNormal); gtk_widget_override_background_color(button, GTK_STATE_FLAG_ACTIVE, &buttonSelected); gtk_container_add(GTK_CONTAINER(button), img); g_signal_connect(button, "clicked", G_CALLBACK(button_callback), GINT_TO_POINTER(BUTTON_PREV)); gtk_box_pack_start(GTK_BOX(hbox), button, 0, 0, 0); t->playerControls.playPause = gtk_image_new(); button = gtk_button_new(); gtk_widget_override_background_color(button, GTK_STATE_FLAG_NORMAL, &buttonNormal); gtk_widget_override_background_color(button, GTK_STATE_FLAG_ACTIVE, &buttonSelected); gtk_container_add(GTK_CONTAINER(button), t->playerControls.playPause); g_signal_connect(button, "clicked", G_CALLBACK(button_callback), GINT_TO_POINTER(BUTTON_PLAY_PAUSE)); gtk_box_pack_start(GTK_BOX(hbox), button, 0, 0, 0); img = gtk_image_new_from_pixbuf(gdk_pixbuf_new_from_xpm_data(next_xpm)); button = gtk_button_new(); gtk_widget_override_background_color(button, GTK_STATE_FLAG_NORMAL, &buttonNormal); gtk_widget_override_background_color(button, GTK_STATE_FLAG_ACTIVE, &buttonSelected); gtk_container_add(GTK_CONTAINER(button), img); g_signal_connect(button, "clicked", G_CALLBACK(button_callback), GINT_TO_POINTER(BUTTON_NEXT)); gtk_box_pack_start(GTK_BOX(hbox), button, 0, 0, 0); sep = gtk_separator_new(GTK_ORIENTATION_VERTICAL); gtk_box_pack_start(GTK_BOX(hbox), sep, 0, 0, 2); t->playerControls.repeat = gtk_image_new(); button = gtk_button_new(); gtk_widget_override_background_color(button, GTK_STATE_FLAG_NORMAL, &buttonNormal); gtk_widget_override_background_color(button, GTK_STATE_FLAG_ACTIVE, &buttonSelected); gtk_container_add(GTK_CONTAINER(button), t->playerControls.repeat); g_signal_connect(button, "clicked", G_CALLBACK(button_callback), GINT_TO_POINTER(BUTTON_REPEAT)); gtk_box_pack_start(GTK_BOX(hbox), button, 0, 0, 0); t->playerControls.shuffle = gtk_image_new(); button = gtk_button_new(); gtk_widget_override_background_color(button, GTK_STATE_FLAG_NORMAL, &buttonNormal); gtk_widget_override_background_color(button, GTK_STATE_FLAG_ACTIVE, &buttonSelected); gtk_container_add(GTK_CONTAINER(button), t->playerControls.shuffle); g_signal_connect(button, "clicked", G_CALLBACK(button_callback), GINT_TO_POINTER(BUTTON_SHUFFLE)); gtk_box_pack_start(GTK_BOX(hbox), button, 0, 0, 0); return TRUE; }
// Основная функция построения класса, в которой происходит заполнение окна виджетами. void cMainWin::Create() { // Создаём объект, если ранее он был не создан или был уничтожен. if(mbIsCreated) return; // Общие виджеты. Будут использованы несколько раз. GtkWidget *awHBox; // Горизонтальный бокс. GtkWidget *awVBox; // Вертикальный бокс. GtkWidget *awLabel; // Заголовок. GtkWidget *awFrame; // Фрейм для виджетов. GtkWidget *awMenuBar; // Виджет для основного меню. GtkWidget *awSubmenu; // Подменю. GtkWidget *awMenuitem; // Пункт основного меню. GtkWidget *awSubMenuitem; // Пункт подменю. GtkWidget *awOpenFileButton; // Кнопка открытия файла. GtkWidget *awAdditionButton; // Кнопка доп. настроек. GtkWidget *awConvertButton; // Кнопка конвертации. // Настраиваем виджет главного окна. mwWindow = gtk_window_new(GTK_WINDOW_TOPLEVEL); gtk_window_set_default_size ((GtkWindow *)mwWindow, 800, 400); // Задаём размер. gtk_window_move((GtkWindow *)mwWindow, 50, 50); // Перемещаем окно. gtk_window_set_title((GtkWindow *)mwWindow, msTitle.c_str()); // Задаём имя. // Устанавливаем обработчик события уничтожения окна. g_signal_connect( G_OBJECT(mwWindow), "delete_event", G_CALLBACK(gtk_main_quit), this); // Создаём новый вертикальный бокс и забиваем его в основное окно. mwMainBox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0); gtk_container_add((GtkContainer *)mwWindow, mwMainBox); // Создаём новый виджет основного меню. awMenuBar = gtk_menu_bar_new (); gtk_box_pack_start (GTK_BOX (mwMainBox), awMenuBar, FALSE, TRUE, 0); // Забиваем меню в главный бокс. // Создаём новый пункт меню Справка и заполняем его подменю. awMenuitem = gtk_menu_item_new_with_label ("Справка"); awSubmenu = gtk_menu_new(); // Добавляем в подменю новый пункт. awSubMenuitem = gtk_menu_item_new_with_label ("О программе"); gtk_menu_shell_append (GTK_MENU_SHELL (awSubmenu), awSubMenuitem); // Не забываем связать этот пункт с подменю. // Устанавливаем обработчик нажатия на пункт подменю. g_signal_connect(awSubMenuitem, "activate", G_CALLBACK(OnAbout), this); gtk_menu_item_set_submenu (GTK_MENU_ITEM (awMenuitem), awSubmenu); // Связываем подменю с главным. gtk_menu_shell_append (GTK_MENU_SHELL (awMenuBar), awMenuitem); // И добавляем пунтк меню в главное меню. // Добавляем в главный бокс разделитель виджетов(простая длинная линия). gtk_box_pack_start (GTK_BOX (mwMainBox), gtk_separator_new(GTK_ORIENTATION_HORIZONTAL), FALSE, TRUE, 5); // Задаём вертикальный бокс для первого пункта процесса конвертации и забиваем его в главный бокс. awVBox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0); gtk_box_pack_start(GTK_BOX(mwMainBox), awVBox, FALSE, FALSE, 1); // Задаём горизонтальный бокс для первого пункта процесса конвертации и забиваем его в предыдущий вертикальный бокс. awHBox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0); gtk_box_pack_start(GTK_BOX(awVBox), awHBox, FALSE, FALSE, 1); // Задаём виджет для отображения текста и добавляем в горизонтальный бокс. awLabel = gtk_label_new ("1."); //gtk_widget_set_halign (awLabel, GTK_ALIGN_START); // Выравнивание. Не нужно, если использовать горизонтальный бокс. gtk_box_pack_start(GTK_BOX(awHBox), awLabel, FALSE, FALSE, 5); // Создаём кнопку Открыть файл и добавляем в горизонтальный бокс. awOpenFileButton = gtk_button_new_with_label ("Открыть файл"); gtk_box_pack_start(GTK_BOX(awHBox), awOpenFileButton, FALSE, FALSE, 10); // Устанавливаем обработчик нажатия на кнопку Открыть файл. g_signal_connect(awOpenFileButton, "clicked", G_CALLBACK(OnOpenFile), this); // Создаём бокс для списка всех записей и добавляем в горизонтальный бокс. mwTrackNameBox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0); gtk_box_pack_start(GTK_BOX(awHBox), mwTrackNameBox, FALSE, FALSE, 5); // Переходим ко второму пункту меню // Задаём вертикальный бокс для второго пункта процесса конвертации и забиваем его в главный бокс. awVBox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0); gtk_box_pack_start(GTK_BOX(mwMainBox), awVBox, FALSE, FALSE, 10); // Задаём горизонтальный бокс для второго пункта процесса конвертации и забиваем его в предыдущий вертикальный бокс. awHBox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0); gtk_box_pack_start(GTK_BOX(awVBox), awHBox, FALSE, FALSE, 1); // Задаём виджет для отображения текста и добавляем в горизонтальный бокс. awLabel = gtk_label_new ("2. "); gtk_box_pack_start(GTK_BOX(awHBox), awLabel, FALSE, FALSE, 5); // Создаём комбо бокс для выбора формата конвертации. mwFormat = gtk_combo_box_text_new (); for(int i = eFormat_MP3; i < eFormat_Unknown; i++) { // Для каждого пункта из enum добавляем пункт в комбо боксе со своим текстом из asFormat. gtk_combo_box_text_insert_text ((GtkComboBoxText *)mwFormat, -1, asFormat[i].c_str()); } gtk_combo_box_set_active((GtkComboBox *)mwFormat, 0); // Устанавливаем активный элемент на первый в списке. // Задаём обработчик события смены формата. g_signal_connect (mwFormat, "changed", G_CALLBACK (OnChangeFormat), this); gtk_box_pack_start(GTK_BOX(awHBox), mwFormat, FALSE, FALSE, 5); // Добавляем комбо бокс в горизонтальный бокс. // Теперь настроим виджеты, которые будут соответствовать формату конвертации из комбо бокса. // Виджеты, соответствующие формату, будут показываться, только при выборе этого формата в комбо боксе. // Задаём горизонтальный бокс для настроек под определённый формат и добавляем его в вертикальный бокс. awHBox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0); gtk_box_pack_start(GTK_BOX(awVBox), awHBox, FALSE, FALSE, 10); // Настроим MP3 виджеты. // Задаём слайдер качества с определённым количеством меток. mMP3Widgets.mwQuality = gtk_scale_new_with_range (GTK_ORIENTATION_HORIZONTAL, 0, eMP3Quality_count-1, 1); gtk_scale_set_draw_value ((GtkScale *)mMP3Widgets.mwQuality, FALSE); // Не будем рисовать текущее значение. // Добавим метки на шкалу слайдера для визуализации. for(int i = 0; i < eMP3Quality_count; i++) { std::string asQ = asMP3Quality[i] +"kbps"; // Значения мток берём из asMP3Quality массива. gtk_scale_add_mark ((GtkScale *)mMP3Widgets.mwQuality, i, GTK_POS_TOP, asQ.c_str()); } gtk_box_pack_start(GTK_BOX(awHBox), mMP3Widgets.mwQuality, TRUE, TRUE, 30); // Добавляем слайдер в горизонтальный бокс. gtk_range_set_show_fill_level ((GtkRange *)mMP3Widgets.mwQuality, TRUE); // Заполняем слайдер другим цветом. gtk_range_set_restrict_to_fill_level ((GtkRange *)mMP3Widgets.mwQuality, TRUE); // Устанавливаем указатель слайдера до уровня заполнения слайдера. gtk_range_set_fill_level ((GtkRange *)mMP3Widgets.mwQuality, eMP3Quality_count-1); // Полностью заполняем слайдер цветом. gtk_range_set_value ((GtkRange *)mMP3Widgets.mwQuality, eMP3Quality_count-1); // Ставим значение слайдера на последнее из массива значений. // Указатель теперь связан с уровнем заполнения, но указатель всё ещё можно двигать, не меняя уровень заполнения. // Для этого необходимо ввести 2 обработчика событий - изменение значение слайдера и изменение границ указателя, для перемещения уровня заполнения. g_signal_connect (mMP3Widgets.mwQuality, "value-changed", G_CALLBACK (OnQualityChanged), this); g_signal_connect (mMP3Widgets.mwQuality, "adjust-bounds", G_CALLBACK (OnAdjustBoundsQuality), this); gtk_widget_show(mMP3Widgets.mwQuality); // Показываем виджеты страницы MP3 конвертера. // Настраиваем OGG виджеты. // Задаём слайдер качества с определённым количеством меток. mOGGWidgets.mwQuality = gtk_scale_new_with_range (GTK_ORIENTATION_HORIZONTAL, 0, eOGGQuality_count-1, 1); gtk_scale_set_draw_value ((GtkScale *)mOGGWidgets.mwQuality, FALSE); // Добавим метки на шкалу слайдера для визуализации. for(int i = 0; i < eOGGQuality_count; i++) { std::string asQ = asOGGQuality[i] +"kbps"; // Значения мток берём из asOGGQuality массива. gtk_scale_add_mark ((GtkScale *)mOGGWidgets.mwQuality, i, GTK_POS_TOP, asQ.c_str()); } gtk_box_pack_start(GTK_BOX(awHBox), mOGGWidgets.mwQuality, TRUE, TRUE, 30); // Добавляем слайдер в горизонтальный бокс. gtk_range_set_show_fill_level ((GtkRange *)mOGGWidgets.mwQuality, TRUE); // Заполняем слайдер другим цветом. gtk_range_set_restrict_to_fill_level ((GtkRange *)mOGGWidgets.mwQuality, TRUE); // Устанавливаем указатель слайдера до уровня заполнения слайдера. gtk_range_set_fill_level ((GtkRange *)mOGGWidgets.mwQuality, eOGGQuality_count-1); // Полностью заполняем слайдер цветом. gtk_range_set_value ((GtkRange *)mOGGWidgets.mwQuality, eOGGQuality_count-1); // Ставим значение слайдера на последнее из массива значений. // Снова вводим 2 обработчика событий, один на изменение значения слайдера и друго для изменения границ указателя, для перемещения уровня заполнения. g_signal_connect (mOGGWidgets.mwQuality, "value-changed", G_CALLBACK (OnQualityChanged), this); g_signal_connect (mOGGWidgets.mwQuality, "adjust-bounds", G_CALLBACK (OnAdjustBoundsQuality), this); // Добавим новую кнопку Дополнительно для отображения дополнительных параметров и добавим его в горизонтальный бокс. awAdditionButton = gtk_button_new_with_label ("Дополнительно"); gtk_box_pack_end(GTK_BOX(awHBox), awAdditionButton, FALSE, FALSE, 30); // Введём обработчик нажатия на кнопку Дополнительно. g_signal_connect(awAdditionButton, "clicked", G_CALLBACK(OnShowAdditionalSettings), this); // Переходим к третьему пункту меню. // Задаём вертикальный бокс для третьего пункта процесса конвертации и забиваем его в главный бокс. awVBox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0); gtk_box_pack_start(GTK_BOX(mwMainBox), awVBox, FALSE, FALSE, 1); // Задаём горизонтальный бокс для третьего пункта процесса конвертации и забиваем его в предыдущий вертикальный бокс. awHBox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0); gtk_box_pack_start(GTK_BOX(awVBox), awHBox, FALSE, FALSE, 10); // Задаём виджет для отображения текста и добавляем в горизонтальный бокс. awLabel = gtk_label_new ("3."); gtk_box_pack_start(GTK_BOX(awHBox), awLabel, FALSE, FALSE, 5); // Добавим кнопку Конвертировать - для начала процесса конвертации ваших аудио файлов. Добавим кнопку в горизонтальный бокс. awConvertButton = gtk_button_new_with_label ("Конвертировать"); gtk_box_pack_start(GTK_BOX(awHBox), awConvertButton, FALSE, FALSE, 10); // Создадим спиннер для визуального отображения процесса конвертации. // Это просто необходимо, т.к. программа как бы подвисает, из-за того что мы конвертируем в одном потоке с программой. // Серъёзно нагружает процессор =( mwSpinner = gtk_spinner_new (); gtk_box_pack_start(GTK_BOX(awHBox), mwSpinner, FALSE, FALSE, 5); // Обработчик события нажатие на кнопку Конвертация. g_signal_connect(awConvertButton, "clicked", G_CALLBACK(OnConvert), this); gtk_widget_show_all (mwWindow); // Покажем все виджеты в окне. gtk_widget_hide(mOGGWidgets.mwQuality); // Скроем виджеты со страницы OGG. По умолчанию отображаем конвертацию в MP3. gtk_widget_hide(mwSpinner); // Скроем спиннер, т.к. мы хотим его показать только в момент конвертации файлов. mbIsCreated = true; // Объект создан. }