39 #include "player_window.h"
41 #define DRAWING_AREA_WIDTH 400
42 #define DRAWING_AREA_HEIGHT 123
43 #define DRAWING_AREA_HEIGHT_WITH_SILENCE_WAVE 232
52 static void draw_small_rectangle(gint time_left, gint time_right,
53 GdkColor color, cairo_t *cairo_surface,
ui_state *ui);
57 static void get_silence_level(
long time,
float level,
void *user_data)
61 gint converted_level = (gint)floorf(abs(level));
62 if (converted_level < 0)
70 if (!ui->infos->silence_points)
72 ui->infos->silence_points = g_malloc(
sizeof(
silence_wave) * 3000);
73 ui->infos->malloced_num_of_silence_points = 3000;
75 else if (ui->infos->number_of_silence_points >= ui->infos->malloced_num_of_silence_points)
77 ui->infos->silence_points = g_realloc(ui->infos->silence_points,
78 sizeof(
silence_wave) * (ui->infos->number_of_silence_points + 3000));
79 ui->infos->malloced_num_of_silence_points = ui->infos->number_of_silence_points + 3000;
82 ui->infos->silence_points[ui->infos->number_of_silence_points].time = time;
83 ui->infos->silence_points[ui->infos->number_of_silence_points].level = abs(level);
85 ui->infos->number_of_silence_points++;
88 static GArray *build_gdk_points_for_douglas_peucker(
ui_infos *infos)
90 GArray *points = g_array_new(TRUE, TRUE,
sizeof(GdkPoint));
93 for (i = 0;i < infos->number_of_silence_points;i++)
95 long time = infos->silence_points[i].time;
96 float level = infos->silence_points[i].level;
100 point.y = (gint)floorf(level);
101 g_array_append_val(points, point);
107 static void douglas_peucker_callback(
ui_state *ui)
109 ui->status->douglas_callback_counter++;
111 if (ui->status->douglas_callback_counter % 400 != 0)
116 gtk_progress_bar_pulse(ui->gui->percent_progress_bar);
117 gtk_progress_bar_set_text(ui->gui->percent_progress_bar,
118 _(
"Processing Douglas-Peucker filters ..."));
119 gtk_widget_queue_draw(GTK_WIDGET(ui->gui->percent_progress_bar));
120 while (gtk_events_pending())
122 gtk_main_iteration();
125 ui->status->douglas_callback_counter = 0;
128 void compute_douglas_peucker_filters(
ui_state *ui)
130 if (!ui->status->show_silence_wave || ui->status->currently_compute_douglas_peucker_filters)
138 status->currently_compute_douglas_peucker_filters = TRUE;
140 status->douglas_callback_counter = 0;
142 GArray *gdk_points_for_douglas_peucker = build_gdk_points_for_douglas_peucker(infos);
144 splt_douglas_peucker_free(infos->filtered_points_presence);
146 infos->filtered_points_presence =
147 splt_douglas_peucker(gdk_points_for_douglas_peucker, douglas_peucker_callback, ui,
148 infos->douglas_peucker_thresholds[0], infos->douglas_peucker_thresholds[1],
149 infos->douglas_peucker_thresholds[2], infos->douglas_peucker_thresholds[3],
150 infos->douglas_peucker_thresholds[4], -1.0);
152 g_array_free(gdk_points_for_douglas_peucker, TRUE);
156 status->currently_compute_douglas_peucker_filters = FALSE;
159 void set_currently_scanning_for_silence_safe(gint value,
ui_state *ui)
161 lock_mutex(&ui->variables_mutex);
162 ui->status->currently_scanning_for_silence = value;
163 unlock_mutex(&ui->variables_mutex);
166 gint get_currently_scanning_for_silence_safe(
ui_state *ui)
168 lock_mutex(&ui->variables_mutex);
169 gint currently_scanning_for_silence = ui->status->currently_scanning_for_silence;
170 unlock_mutex(&ui->variables_mutex);
172 return currently_scanning_for_silence;
175 static gboolean detect_silence_end(
ui_with_err *ui_err)
179 mp3splt_set_silence_level_function(ui->mp3splt_state, NULL, NULL);
181 set_is_splitting_safe(FALSE, ui);
182 set_currently_scanning_for_silence_safe(FALSE, ui);
184 compute_douglas_peucker_filters(ui);
187 gtk_widget_set_sensitive(ui->gui->cancel_button, FALSE);
189 refresh_drawing_area(ui->gui);
190 refresh_preview_drawing_areas(ui->gui);
192 set_process_in_progress_and_wait_safe(FALSE, ui_err->ui);
199 static gpointer detect_silence(
ui_state *ui)
201 set_process_in_progress_and_wait_safe(TRUE, ui);
203 set_is_splitting_safe(TRUE, ui);
204 set_currently_scanning_for_silence_safe(TRUE, ui);
206 if (ui->infos->silence_points)
208 g_free(ui->infos->silence_points);
209 ui->infos->silence_points = NULL;
210 ui->infos->number_of_silence_points = 0;
214 gtk_widget_set_sensitive(ui->gui->cancel_button, TRUE);
217 lock_mutex(&ui->variables_mutex);
219 unlock_mutex(&ui->variables_mutex);
221 mp3splt_set_silence_level_function(ui->mp3splt_state, get_silence_level, ui);
224 mp3splt_set_silence_points(ui->mp3splt_state, &err);
230 gdk_threads_add_idle_full(G_PRIORITY_HIGH_IDLE, (GSourceFunc)detect_silence_end, ui_err, NULL);
235 static void detect_silence_action(
ui_state *ui)
237 create_thread((GThreadFunc)detect_silence, ui);
244 static void scan_for_silence_wave(
ui_state *ui)
246 if (get_currently_scanning_for_silence_safe(ui))
251 if (ui->status->timer_active)
253 detect_silence_action(ui);
269 if (ui->status->show_silence_wave)
271 scan_for_silence_wave(ui);
274 if (gtk_toggle_button_get_active(ui->gui->names_from_filename))
276 copy_filename_to_current_description(fname, ui);
282 if (strcmp(old_fname, fname) == 0)
288 if (ui->status->show_silence_wave)
290 scan_for_silence_wave(ui);
293 if (gtk_toggle_button_get_active(ui->gui->names_from_filename))
295 copy_filename_to_current_description(fname, ui);
300 static void reset_inactive_progress_bar(
gui_state *gui)
302 gtk_widget_set_sensitive(GTK_WIDGET(gui->progress_bar), FALSE);
303 gtk_adjustment_set_value(gui->progress_adj, 0);
307 static void reset_inactive_volume_button(
gui_state *gui)
309 gtk_widget_set_sensitive(GTK_WIDGET(gui->volume_button), FALSE);
310 gtk_scale_button_set_value(GTK_SCALE_BUTTON(gui->volume_button), 0);
314 static void reset_label_time(
gui_state *gui)
316 gtk_label_set_text(GTK_LABEL(gui->label_time),
"");
320 static void reset_song_infos(
gui_state *gui)
322 gtk_label_set_text(GTK_LABEL(gui->song_infos),
"");
326 static void reset_song_name_label(
gui_state *gui)
328 gtk_label_set_text(GTK_LABEL(gui->song_name_label),
"");
332 static void clear_data_player(
gui_state *gui)
334 reset_song_name_label(gui);
335 reset_song_infos(gui);
336 reset_inactive_volume_button(gui);
337 reset_inactive_progress_bar(gui);
338 reset_label_time(gui);
346 gtk_widget_set_sensitive(gui->stop_button, TRUE);
347 wh_set_image_on_button(GTK_BUTTON(gui->stop_button), g_object_ref(gui->StopButton_active));
349 gtk_widget_set_sensitive(gui->pause_button, TRUE);
350 wh_set_image_on_button(GTK_BUTTON(gui->pause_button), g_object_ref(gui->PauseButton_active));
352 if (ui->infos->selected_player != PLAYER_GSTREAMER)
354 gtk_widget_set_sensitive(gui->go_beg_button, TRUE);
355 wh_set_image_on_button(GTK_BUTTON(gui->go_beg_button), g_object_ref(gui->Go_BegButton_active));
357 gtk_widget_set_sensitive(gui->go_end_button, TRUE);
358 wh_set_image_on_button(GTK_BUTTON(gui->go_end_button), g_object_ref(gui->Go_EndButton_active));
361 gtk_widget_set_sensitive(gui->play_button, TRUE);
362 wh_set_image_on_button(GTK_BUTTON(gui->play_button), g_object_ref(gui->PlayButton_active));
364 player_key_actions_set_sensitivity(TRUE, gui);
368 static void disable_player_buttons(
gui_state *gui)
370 gtk_widget_set_sensitive(gui->stop_button, FALSE);
371 wh_set_image_on_button(GTK_BUTTON(gui->stop_button), g_object_ref(gui->StopButton_inactive));
373 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(gui->pause_button), FALSE);
374 gtk_widget_set_sensitive(gui->pause_button, FALSE);
375 wh_set_image_on_button(GTK_BUTTON(gui->pause_button), g_object_ref(gui->PauseButton_inactive));
377 gtk_widget_set_sensitive(gui->go_beg_button, FALSE);
378 wh_set_image_on_button(GTK_BUTTON(gui->go_beg_button), g_object_ref(gui->Go_BegButton_inactive));
380 gtk_widget_set_sensitive(gui->go_end_button, FALSE);
381 wh_set_image_on_button(GTK_BUTTON(gui->go_end_button), g_object_ref(gui->Go_EndButton_inactive));
383 gtk_widget_set_sensitive(gui->play_button, FALSE);
384 wh_set_image_on_button(GTK_BUTTON(gui->play_button), g_object_ref(gui->PlayButton_inactive));
386 gtk_widget_set_sensitive(gui->player_add_button, FALSE);
387 gtk_widget_set_sensitive(gui->silence_wave_check_button, FALSE);
389 player_key_actions_set_sensitivity(FALSE, gui);
393 static void show_disconnect_button(
gui_state *gui)
397 gtk_box_pack_start(gui->player_buttons_hbox, gui->disconnect_button, FALSE, FALSE, 7);
400 gtk_widget_show_all(gui->disconnect_button);
406 gtk_widget_hide(gui->connect_button);
410 static void connect_change_buttons(
ui_state *ui)
412 if (ui->infos->selected_player == PLAYER_GSTREAMER)
417 show_disconnect_button(ui->gui);
422 static void hide_disconnect_button(
gui_state *gui)
424 gtk_widget_hide(gui->disconnect_button);
432 gtk_box_pack_start(gui->player_buttons_hbox, gui->connect_button, FALSE, FALSE, 7);
435 gtk_widget_show_all(gui->connect_button);
439 static void disconnect_change_buttons(
ui_state *ui)
441 if (ui->infos->selected_player == PLAYER_GSTREAMER)
446 hide_disconnect_button(ui->gui);
457 static void connect_with_song(
const gchar *fname, gint start_playing,
ui_state *ui)
466 GList *song_list = NULL;
467 song_list = g_list_append(song_list, strdup(fname));
469 if (start_playing == 0)
482 if (status->file_browsed)
492 if (!status->playing)
506 if (!status->timer_active)
508 status->timeout_id = g_timeout_add(ui->infos->timeout_value, (GSourceFunc)mytimer, ui);
509 status->timer_active = TRUE;
516 connect_change_buttons(ui);
519 g_list_foreach(song_list, (GFunc)g_free, NULL);
520 g_list_free(song_list);
545 if (!status->timer_active)
547 if (ui->infos->selected_player == PLAYER_SNACKAMP)
552 status->timeout_id = g_timeout_add(ui->infos->timeout_value, (GSourceFunc)mytimer, ui);
553 status->timer_active = TRUE;
562 status->file_browsed = FALSE;
563 status->change_volume = TRUE;
568 connect_change_buttons(ui);
573 switch (ui->infos->selected_player)
575 case PLAYER_SNACKAMP:
576 label = gtk_label_new
577 (_(
"\n Cannot connect to snackAmp player.\n"
578 " Please download and install snackamp from\n"
579 "\thttp://snackamp.sourceforge.net\n\n"
580 " Verify that snackamp is running.\n"
581 " Verify that your snackamp version is >= 3.1.3\n\n"
582 " Verify that you have enabled socket interface in snackamp:\n"
583 " You have to go to\n"
584 "\tTools->Preferences->Miscellaneous\n"
585 " from the snackamp menu and check\n"
586 "\tEnable Socket Interface\n"
587 " Only default port is supported for now(8775)\n"
588 " After that, restart snackamp and mp3splt-gtk should work.\n"));
590 case PLAYER_AUDACIOUS:
591 label = gtk_label_new
592 (_(
"\n Cannot connect to Audacious player.\n"
593 " Verify that you have installed audacious.\n\n"
594 " Put in your PATH variable the directory where the audacious"
596 " If you don't know how to do that, start audacious manually"
597 " and then try to connect.\n"));
600 label = gtk_label_new(_(
"Cannot connect to player"));
604 GtkWidget *dialog = gtk_dialog_new_with_buttons(_(
"Cannot connect to player"),
605 GTK_WINDOW(ui->gui->window), GTK_DIALOG_MODAL, GTK_STOCK_OK, GTK_RESPONSE_NONE, NULL);
606 g_signal_connect_swapped(dialog,
"response", G_CALLBACK(gtk_widget_destroy), dialog);
607 gtk_container_add(GTK_CONTAINER(gtk_dialog_get_content_area(GTK_DIALOG(dialog))), label);
608 gtk_widget_show_all(dialog);
611 ui->infos->current_time = -1;
614 if (ui->status->show_silence_wave)
616 scan_for_silence_wave(ui);
620 refresh_drawing_area(ui->gui);
624 static void check_stream(
ui_state *ui)
626 if (((gint)ui->infos->total_time) == -1)
628 ui->status->stream = TRUE;
629 reset_inactive_progress_bar(ui->gui);
633 ui->status->stream = FALSE;
642 if (ui->status->timer_active)
644 if (ui->infos->selected_player == PLAYER_SNACKAMP)
649 g_source_remove(ui->status->timeout_id);
650 ui->status->timer_active = FALSE;
653 clear_data_player(gui);
654 disconnect_change_buttons(ui);
655 disable_player_buttons(gui);
658 if (!get_is_splitting_safe(ui))
660 gtk_progress_bar_set_fraction(gui->percent_progress_bar, 0);
661 gtk_progress_bar_set_text(gui->percent_progress_bar,
"");
667 gtk_widget_set_sensitive(gui->play_button, TRUE);
668 wh_set_image_on_button(GTK_BUTTON(gui->play_button), g_object_ref(gui->PlayButton_active));
673 if (get_currently_scanning_for_silence_safe(ui))
678 refresh_drawing_area(ui->gui);
681 void restart_player_timer(
ui_state *ui)
683 if (ui->status->timer_active)
685 g_source_remove(ui->status->timeout_id);
686 ui->status->timeout_id = g_timeout_add(ui->infos->timeout_value, (GSourceFunc)mytimer, ui);
691 static void play_event(GtkWidget *widget,
ui_state *ui)
696 if (status->timer_active)
711 gtk_widget_set_sensitive(gui->pause_button, TRUE);
712 wh_set_image_on_button(GTK_BUTTON(gui->pause_button), g_object_ref(gui->PauseButton_active));
714 gtk_widget_set_sensitive(gui->stop_button, TRUE);
715 wh_set_image_on_button(GTK_BUTTON(gui->stop_button), g_object_ref(gui->StopButton_active));
719 static void stop_event(GtkWidget *widget,
ui_state *ui)
723 if (!ui->status->timer_active)
728 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(gui->pause_button), FALSE);
732 ui->status->playing = FALSE;
737 gtk_widget_set_sensitive(gui->pause_button, FALSE);
738 wh_set_image_on_button(GTK_BUTTON(gui->pause_button), g_object_ref(gui->PauseButton_inactive));
740 gtk_widget_set_sensitive(gui->stop_button, FALSE);
741 wh_set_image_on_button(GTK_BUTTON(gui->stop_button), g_object_ref(gui->StopButton_inactive));
747 if (!ui->status->timer_active) {
return; }
749 if (ui->status->only_press_pause) {
return; }
755 static void prev_button_event(GtkWidget *widget,
ui_state *ui)
757 if (!ui->status->timer_active) {
return; }
763 static void next_button_event(GtkWidget *widget,
ui_state *ui)
765 if (!ui->status->timer_active)
779 static void change_song_position(
ui_state *ui)
782 ui->infos->player_seconds2 * 1000 +
783 ui->infos->player_minutes2 * 60000 +
784 ui->infos->player_hundr_secs2 * 10;
790 static void toggle_show_silence_wave(GtkToggleButton *show_silence_toggle_button,
ui_state *ui)
795 if (gtk_toggle_button_get_active(show_silence_toggle_button))
797 status->show_silence_wave = TRUE;
798 scan_for_silence_wave(ui);
802 status->show_silence_wave = FALSE;
803 if (get_currently_scanning_for_silence_safe(ui))
808 refresh_drawing_area(ui->gui);
809 refresh_preview_drawing_areas(ui->gui);
813 static gboolean volume_button_unclick_event(GtkWidget *widget, GdkEventCrossing *event,
ui_state *ui)
815 ui->status->change_volume = TRUE;
820 static gboolean volume_button_click_event(GtkWidget *widget, GdkEventCrossing *event,
ui_state *ui)
822 ui->status->change_volume = FALSE;
827 static gboolean volume_button_enter_event(GtkWidget *widget, GdkEventCrossing *event,
ui_state *ui)
829 ui->status->on_the_volume_button = TRUE;
834 static gboolean volume_button_leave_event(GtkWidget *widget, GdkEventCrossing *event,
ui_state *ui)
836 ui->status->on_the_volume_button = FALSE;
841 static void change_volume_event(GtkScaleButton *volume_button, gdouble value,
ui_state *ui)
843 if (!gtk_widget_get_sensitive(GTK_WIDGET(volume_button)))
851 static GtkWidget *create_volume_button(
ui_state *ui)
853 GtkWidget *volume_button = gtk_volume_button_new();
854 ui->gui->volume_button = volume_button;
856 g_signal_connect(G_OBJECT(volume_button),
"button-press-event",
857 G_CALLBACK(volume_button_click_event), ui);
858 g_signal_connect(G_OBJECT(volume_button),
"button-release-event",
859 G_CALLBACK(volume_button_unclick_event), ui);
860 g_signal_connect(G_OBJECT(volume_button),
"enter-notify-event",
861 G_CALLBACK(volume_button_enter_event), ui);
862 g_signal_connect(G_OBJECT(volume_button),
"leave-notify-event",
863 G_CALLBACK(volume_button_leave_event), ui);
865 g_signal_connect(GTK_SCALE_BUTTON(volume_button),
"value_changed",
866 G_CALLBACK(change_volume_event), ui);
868 gtk_widget_set_sensitive(GTK_WIDGET(volume_button), FALSE);
870 return volume_button;
874 static GtkWidget *create_player_buttons_hbox(
ui_state *ui)
876 GtkBox *player_buttons_hbox = GTK_BOX(wh_hbox_new());
877 ui->gui->player_buttons_hbox = player_buttons_hbox;
879 GString *imagefile = g_string_new(
"");
880 build_path(imagefile, IMAGEDIR,
"backward"ICON_EXT);
881 GtkWidget *Go_BegButton_active = gtk_image_new_from_file(imagefile->str);
882 ui->gui->Go_BegButton_active = Go_BegButton_active;
884 build_path(imagefile, IMAGEDIR,
"backward_inactive"ICON_EXT);
885 GtkWidget *Go_BegButton_inactive = gtk_image_new_from_file(imagefile->str);
886 ui->gui->Go_BegButton_inactive = Go_BegButton_inactive;
887 GtkWidget *go_beg_button = gtk_button_new();
888 ui->gui->go_beg_button = go_beg_button;
889 wh_set_image_on_button(GTK_BUTTON(go_beg_button), g_object_ref(Go_BegButton_inactive));
891 gtk_box_pack_start(player_buttons_hbox, go_beg_button, FALSE, FALSE, 0);
892 gtk_button_set_relief(GTK_BUTTON(go_beg_button), GTK_RELIEF_NONE);
893 g_signal_connect(G_OBJECT(go_beg_button),
"clicked", G_CALLBACK(prev_button_event), ui);
894 gtk_widget_set_sensitive(go_beg_button, FALSE);
895 gtk_widget_set_tooltip_text(go_beg_button, _(
"Previous"));
898 build_path(imagefile, IMAGEDIR,
"play"ICON_EXT);
899 GtkWidget *PlayButton_active = gtk_image_new_from_file(imagefile->str);
900 ui->gui->PlayButton_active = PlayButton_active;
902 build_path(imagefile, IMAGEDIR,
"play_inactive"ICON_EXT);
903 GtkWidget *PlayButton_inactive = gtk_image_new_from_file(imagefile->str);
904 ui->gui->PlayButton_inactive = PlayButton_inactive;
905 GtkWidget *play_button = gtk_button_new();
906 ui->gui->play_button = play_button;
907 wh_set_image_on_button(GTK_BUTTON(play_button), g_object_ref(PlayButton_inactive));
909 gtk_box_pack_start(player_buttons_hbox, play_button, FALSE, FALSE, 0);
910 gtk_button_set_relief(GTK_BUTTON(play_button), GTK_RELIEF_NONE);
911 g_signal_connect(G_OBJECT(play_button),
"clicked", G_CALLBACK(play_event), ui);
912 gtk_widget_set_sensitive(play_button, FALSE);
913 gtk_widget_set_tooltip_text(play_button, _(
"Play"));
916 build_path(imagefile, IMAGEDIR,
"pause"ICON_EXT);
917 GtkWidget *PauseButton_active = gtk_image_new_from_file(imagefile->str);
918 ui->gui->PauseButton_active = PauseButton_active;
920 build_path(imagefile, IMAGEDIR,
"pause_inactive"ICON_EXT);
921 GtkWidget *PauseButton_inactive = gtk_image_new_from_file(imagefile->str);
922 ui->gui->PauseButton_inactive = PauseButton_inactive;
923 GtkWidget *pause_button = gtk_toggle_button_new();
924 ui->gui->pause_button = pause_button;
925 wh_set_image_on_button(GTK_BUTTON(pause_button), g_object_ref(PauseButton_inactive));
926 gtk_box_pack_start(player_buttons_hbox, pause_button, FALSE, FALSE, 0);
927 gtk_button_set_relief(GTK_BUTTON(pause_button), GTK_RELIEF_NONE);
928 g_signal_connect(G_OBJECT(pause_button),
"clicked", G_CALLBACK(
pause_event), ui);
929 gtk_widget_set_sensitive(pause_button, FALSE);
930 gtk_widget_set_tooltip_text(pause_button,_(
"Pause"));
933 build_path(imagefile, IMAGEDIR,
"stop"ICON_EXT);
934 GtkWidget *StopButton_active = gtk_image_new_from_file(imagefile->str);
935 ui->gui->StopButton_active = StopButton_active;
937 build_path(imagefile, IMAGEDIR,
"stop_inactive"ICON_EXT);
938 GtkWidget *StopButton_inactive = gtk_image_new_from_file(imagefile->str);
939 ui->gui->StopButton_inactive = StopButton_inactive;
940 GtkWidget *stop_button = gtk_button_new();
941 ui->gui->stop_button = stop_button;
942 wh_set_image_on_button(GTK_BUTTON(stop_button), g_object_ref(StopButton_inactive));
943 gtk_box_pack_start(player_buttons_hbox, stop_button, FALSE, FALSE, 0);
944 gtk_button_set_relief(GTK_BUTTON(stop_button), GTK_RELIEF_NONE);
945 g_signal_connect(G_OBJECT(stop_button),
"clicked", G_CALLBACK(stop_event), ui);
946 gtk_widget_set_sensitive(stop_button, FALSE);
947 gtk_widget_set_tooltip_text(stop_button,_(
"Stop"));
950 build_path(imagefile, IMAGEDIR,
"forward"ICON_EXT);
951 GtkWidget *Go_EndButton_active = gtk_image_new_from_file(imagefile->str);
952 ui->gui->Go_EndButton_active = Go_EndButton_active;
954 build_path(imagefile, IMAGEDIR,
"forward_inactive"ICON_EXT);
955 GtkWidget *Go_EndButton_inactive = gtk_image_new_from_file(imagefile->str);
956 ui->gui->Go_EndButton_inactive = Go_EndButton_inactive;
957 GtkWidget *go_end_button = gtk_button_new();
958 ui->gui->go_end_button = go_end_button;
959 wh_set_image_on_button(GTK_BUTTON(go_end_button), g_object_ref(Go_EndButton_inactive));
960 gtk_box_pack_start(player_buttons_hbox, go_end_button, FALSE, FALSE, 0);
961 gtk_button_set_relief(GTK_BUTTON(go_end_button), GTK_RELIEF_NONE);
962 g_signal_connect(G_OBJECT(go_end_button),
"clicked", G_CALLBACK(next_button_event), ui);
963 gtk_widget_set_sensitive(go_end_button, FALSE);
964 gtk_widget_set_tooltip_text(go_end_button,_(
"Next"));
965 g_string_free(imagefile,TRUE);
967 GtkWidget *vol_button = create_volume_button(ui);
968 gtk_box_pack_start(player_buttons_hbox, vol_button, FALSE, FALSE, 5);
972 ui->gui->player_add_button = player_add_button;
973 gtk_box_pack_start(player_buttons_hbox, player_add_button, FALSE, FALSE, 0);
974 gtk_button_set_relief(GTK_BUTTON(player_add_button), GTK_RELIEF_NONE);
975 g_signal_connect(G_OBJECT(player_add_button),
"clicked",
976 G_CALLBACK(add_splitpoint_from_player), ui);
977 gtk_widget_set_sensitive(player_add_button, FALSE);
978 gtk_widget_set_tooltip_text(player_add_button,_(
"Add splitpoint from player"));
982 ui->gui->scan_trim_silence_button_player = scan_trim_silence_button;
983 gtk_widget_set_sensitive(scan_trim_silence_button, TRUE);
984 g_signal_connect(G_OBJECT(scan_trim_silence_button),
"clicked",
985 G_CALLBACK(create_trim_silence_window), ui);
986 gtk_widget_set_tooltip_text(scan_trim_silence_button,
987 _(
"Set trim splitpoints using silence detection"));
988 gtk_box_pack_start(player_buttons_hbox, scan_trim_silence_button, FALSE, FALSE, 0);
989 gtk_button_set_relief(GTK_BUTTON(scan_trim_silence_button), GTK_RELIEF_NONE);
993 ui->gui->scan_silence_button_player = scan_silence_button;
994 gtk_widget_set_sensitive(scan_silence_button, TRUE);
995 g_signal_connect(G_OBJECT(scan_silence_button),
"clicked",
997 gtk_widget_set_tooltip_text(scan_silence_button,
998 _(
"Set splitpoints from silence detection"));
999 gtk_box_pack_start(player_buttons_hbox, scan_silence_button, FALSE, FALSE, 0);
1000 gtk_button_set_relief(GTK_BUTTON(scan_silence_button), GTK_RELIEF_NONE);
1003 GtkWidget *silence_wave_check_button = gtk_check_button_new_with_mnemonic(_(
"Amplitude _wave"));
1004 ui->gui->silence_wave_check_button = silence_wave_check_button;
1005 gtk_box_pack_end(player_buttons_hbox, silence_wave_check_button, FALSE, FALSE, 5);
1006 g_signal_connect(G_OBJECT(silence_wave_check_button),
"toggled",
1007 G_CALLBACK(toggle_show_silence_wave), ui);
1008 gtk_widget_set_sensitive(silence_wave_check_button, FALSE);
1009 gtk_widget_set_tooltip_text(silence_wave_check_button, _(
"Shows the amplitude level wave"));
1013 ui->gui->connect_button = connect_button;
1015 gtk_widget_set_tooltip_text(connect_button,_(
"Connect to player"));
1019 ui->gui->disconnect_button = disconnect_button;
1021 gtk_widget_set_tooltip_text(disconnect_button,_(
"Disconnect from player"));
1023 return GTK_WIDGET(player_buttons_hbox);
1027 static GtkWidget *create_song_informations_hbox(
gui_state *gui)
1029 GtkWidget *song_info_hbox = wh_hbox_new();
1031 GtkWidget *song_infos = gtk_label_new(
"");
1032 gui->song_infos = song_infos;
1033 gtk_box_pack_start(GTK_BOX(song_info_hbox), song_infos, FALSE, FALSE, 40);
1035 GtkWidget *label_time = gtk_label_new(
"");
1036 gui->label_time = label_time;
1037 gtk_box_pack_start(GTK_BOX(song_info_hbox), label_time, FALSE, FALSE, 5);
1039 return song_info_hbox;
1043 static gboolean progress_bar_unclick_event(GtkWidget *widget, GdkEventCrossing *event,
ui_state *ui)
1045 change_song_position(ui);
1049 infos->player_minutes = infos->player_minutes2;
1050 infos->player_seconds = infos->player_seconds2;
1051 infos->player_hundr_secs = infos->player_hundr_secs2;
1053 ui->status->mouse_on_progress_bar = FALSE;
1059 static gboolean progress_bar_click_event(GtkWidget *widget, GdkEventCrossing *event,
ui_state *ui)
1061 ui->status->mouse_on_progress_bar = TRUE;
1066 static gfloat get_elapsed_time(
ui_state *ui)
1068 gfloat adj_position = gtk_adjustment_get_value(ui->gui->progress_adj);
1069 return (adj_position * ui->infos->total_time) / 100000;
1072 void refresh_drawing_area(
gui_state *gui)
1074 gtk_widget_queue_draw(gui->drawing_area);
1080 if (get_is_splitting_safe(ui) ||
1081 get_currently_scanning_for_silence_safe(ui) ||
1082 ui->status->currently_compute_douglas_peucker_filters)
1087 gfloat progress_time = 0;
1088 gint splitpoint_time_left = -1;
1089 gint splitpoint_time_right = -1;
1090 gint splitpoint_left_index = -1;
1091 get_current_splitpoints_time_left_right(&splitpoint_time_left, &splitpoint_time_right,
1092 &splitpoint_left_index, ui);
1094 if ((splitpoint_time_left != -1) && (splitpoint_time_right != -1))
1096 gfloat total_interval = splitpoint_time_right - splitpoint_time_left;
1097 if (((gint)total_interval) != 0)
1099 progress_time = (ui->infos->current_time-splitpoint_time_left) / total_interval;
1104 if (splitpoint_time_right == -1)
1106 gfloat total_interval = ui->infos->total_time - splitpoint_time_left;
1107 if (((gint)total_interval) != 0)
1109 progress_time = (ui->infos->current_time-splitpoint_time_left)/ total_interval;
1114 gfloat total_interval = splitpoint_time_right;
1115 if (((gint)total_interval) != 0)
1117 progress_time = ui->infos->current_time/total_interval;
1122 if (progress_time < 0)
1126 if (progress_time > 1)
1130 if ((progress_time >= 0) && (progress_time <= 1))
1132 gtk_progress_bar_set_fraction(ui->gui->percent_progress_bar, progress_time);
1136 gchar description_shorted[512] = {
'\0' };
1138 if (splitpoint_time_right != -1)
1140 if (splitpoint_time_left == -1)
1142 if (progress_description != NULL)
1144 g_snprintf(description_shorted, 60, _(
"before %s"), progress_description);
1149 if (progress_description != NULL)
1151 g_snprintf(description_shorted, 60,
"%s", progress_description);
1157 if (splitpoint_time_left != -1)
1159 if (progress_description != NULL)
1161 g_snprintf(description_shorted, 60,
"%s", progress_description);
1171 if (strlen(description_shorted) > 55)
1173 description_shorted[56] =
'.';
1174 description_shorted[57] =
'.';
1175 description_shorted[58] =
'.';
1176 description_shorted[59] =
'\0';
1179 gtk_progress_bar_set_text(ui->gui->percent_progress_bar, description_shorted);
1180 g_free(progress_description);
1184 static void progress_bar_value_changed_event(GtkRange *range,
ui_state *ui)
1186 refresh_drawing_area(ui->gui);
1190 infos->player_hundr_secs2 = (gint)infos->current_time % 100;
1192 gint tt2 = infos->total_time / 100;
1193 gfloat adj_position = (gint)gtk_adjustment_get_value(ui->gui->progress_adj);
1194 infos->current_time = (adj_position * tt2) / 100000;
1196 infos->player_seconds2 = (gint)infos->current_time % 60;
1197 infos->player_minutes2 = (gint)infos->current_time / 60;
1199 infos->current_time = get_elapsed_time(ui);
1205 static gboolean progress_bar_scroll_event(GtkWidget *widget, GdkEventScroll *event, gpointer user_data)
1211 static gboolean progress_bar_enter_event(GtkWidget *widget, GdkEventCrossing *event, gpointer user_data)
1217 static gboolean progress_bar_leave_event(GtkWidget *widget, GdkEventCrossing *event, gpointer user_data)
1223 static GtkWidget *create_song_bar_hbox(
ui_state *ui)
1225 GtkAdjustment *progress_adj =
1226 GTK_ADJUSTMENT(gtk_adjustment_new(0.0, 0.0, 100001.0, 0, 10000, 1000));
1227 ui->gui->progress_adj = progress_adj;
1229 GtkWidget *progress_bar = wh_hscale_new(progress_adj);
1230 ui->gui->progress_bar = progress_bar;
1231 g_object_set(progress_bar,
"draw-value", FALSE, NULL);
1233 g_signal_connect(G_OBJECT(progress_bar),
"button-press-event",
1234 G_CALLBACK(progress_bar_click_event), ui);
1235 g_signal_connect(G_OBJECT(progress_bar),
"button-release-event",
1236 G_CALLBACK(progress_bar_unclick_event), ui);
1237 g_signal_connect(G_OBJECT(progress_bar),
"value-changed",
1238 G_CALLBACK(progress_bar_value_changed_event), ui);
1240 g_signal_connect(G_OBJECT(progress_bar),
"enter-notify-event",
1241 G_CALLBACK(progress_bar_enter_event), NULL);
1242 g_signal_connect(G_OBJECT(progress_bar),
"leave-notify-event",
1243 G_CALLBACK(progress_bar_leave_event), NULL);
1244 g_signal_connect(G_OBJECT(progress_bar),
"scroll-event",
1245 G_CALLBACK(progress_bar_scroll_event), NULL);
1247 gtk_widget_set_sensitive(GTK_WIDGET(progress_bar), FALSE);
1249 GtkWidget *song_bar_hbox = wh_hbox_new();
1250 gtk_box_pack_start(GTK_BOX(song_bar_hbox), progress_bar, TRUE, TRUE, 5);
1251 return song_bar_hbox;
1255 static void print_about_the_song(
ui_state *ui)
1257 gchar total_infos[512];
1260 gtk_label_set_text(GTK_LABEL(ui->gui->song_infos), total_infos);
1264 static void print_player_filename(
ui_state *ui)
1269 if (strcmp(fname,
"disconnect"))
1279 gtk_label_set_text(GTK_LABEL(ui->gui->song_name_label), title);
1288 static void print_all_song_infos(
ui_state *ui)
1290 print_about_the_song(ui);
1291 print_player_filename(ui);
1300 static void print_song_time_elapsed(
ui_state *ui)
1302 gchar seconds[16], minutes[16], seconds_minutes[64];
1305 ui->infos->player_hundr_secs = (time % 1000) / 10;
1307 gint temp = (time/1000)/60;
1308 ui->infos->player_minutes = temp;
1309 ui->infos->player_seconds = (time/1000) - (temp*60);
1311 g_snprintf(minutes, 16,
"%d", temp);
1312 g_snprintf(seconds, 16,
"%d", (time/1000) - (temp*60));
1314 gchar total_seconds[16], total_minutes[16];
1316 gint tt = ui->infos->total_time * 10;
1317 temp = (tt / 1000) / 60;
1319 g_snprintf(total_minutes, 16,
"%d", temp);
1320 g_snprintf(total_seconds, 16,
"%d", (tt/1000) - (temp*60));
1321 g_snprintf(seconds_minutes, 64,
"%s : %s / %s : %s",
1322 minutes, seconds, total_minutes, total_seconds);
1324 gtk_label_set_text(GTK_LABEL(ui->gui->label_time), seconds_minutes);
1328 static void change_volume_button(
ui_state *ui)
1341 gtk_scale_button_set_value(GTK_SCALE_BUTTON(ui->gui->volume_button), volume / 100.0);
1344 void set_quick_preview_end_splitpoint_safe(gint value,
ui_state *ui)
1346 lock_mutex(&ui->variables_mutex);
1347 ui->status->quick_preview_end_splitpoint = value;
1348 unlock_mutex(&ui->variables_mutex);
1351 gint get_quick_preview_end_splitpoint_safe(
ui_state *ui)
1353 lock_mutex(&ui->variables_mutex);
1354 gint quick_preview_end_splitpoint = ui->status->quick_preview_end_splitpoint;
1355 unlock_mutex(&ui->variables_mutex);
1356 return quick_preview_end_splitpoint;
1360 static void change_progress_bar(
ui_state *ui)
1367 refresh_drawing_area(ui->gui);
1373 infos->current_time = infos->player_seconds * 100 +
1374 infos->player_minutes * 6000 +
1375 infos->player_hundr_secs;
1377 gdouble adj_position = (infos->current_time * 100000) / infos->total_time;
1378 gtk_adjustment_set_value(ui->gui->progress_adj, adj_position);
1380 infos->current_time = get_elapsed_time(ui);
1382 gint stop_splitpoint =
get_splitpoint_time(get_quick_preview_end_splitpoint_safe(ui), ui);
1384 if ((stop_splitpoint < (gint)(infos->current_time-150)) ||
1385 (start_splitpoint > (gint)(infos->current_time+150)))
1392 static GtkWidget *create_filename_player_hbox(
gui_state *gui)
1394 GtkWidget *song_name_label = gtk_label_new(
"");
1395 gtk_label_set_selectable(GTK_LABEL(song_name_label), TRUE);
1396 gui->song_name_label = song_name_label;
1398 g_object_set(G_OBJECT(song_name_label),
"selectable", FALSE, NULL);
1400 gtk_label_set_ellipsize(GTK_LABEL(song_name_label), PANGO_ELLIPSIZE_END);
1402 GtkWidget *filename_player_hbox = wh_hbox_new();
1404 #if GTK_MAJOR_VERSION <= 2
1406 gtk_box_pack_start(GTK_BOX(filename_player_hbox), song_name_label,
1409 gtk_box_pack_start(GTK_BOX(filename_player_hbox), song_name_label, FALSE, FALSE, 15);
1412 return filename_player_hbox;
1418 gfloat right = total_time / zoom_coeff;
1419 gfloat center = right/2;
1420 gfloat offset = current_time - center;
1421 return right + offset;
1427 gfloat right = total_time / zoom_coeff;
1428 gfloat center = right/2;
1429 return current_time - center;
1437 static gchar *get_time_for_drawing(gchar *str, gint time, gboolean hundr_or_not, gint *number_of_chars)
1439 gint mins = time / 6000;
1440 gint secs = (time / 100) % 60;
1444 gint hundr = time % 100;
1445 *number_of_chars = g_snprintf(str, 30,
"%d:%02d:%02d", mins, secs, hundr);
1449 *number_of_chars = g_snprintf(str, 30,
"%d:%02d", mins, secs);
1456 static gfloat pixels_to_time(gfloat width, gint pixels,
ui_state *ui)
1458 return (ui->infos->total_time * (gfloat)pixels)/(width * ui->infos->zoom_coeff);
1461 static gint time_to_pixels(gint width, gfloat time, gfloat total_time, gfloat zoom_coeff)
1463 return (width * time * zoom_coeff) / total_time;
1471 static gint convert_time_to_pixels(gint width, gfloat time,
1472 gfloat current_time, gfloat total_time, gfloat zoom_coeff)
1474 return width/2 + time_to_pixels(width, time - current_time, total_time, zoom_coeff);
1477 static void draw_motif(GtkWidget *da, cairo_t *gc, gint ylimit, gint x, gint time_interval)
1480 switch (time_interval)
1483 color.red = 65000;color.green = 0;color.blue = 0;
1485 case TENS_OF_SECONDS:
1486 color.red = 0;color.green = 0;color.blue = 65000;
1489 color.red = 0;color.green = 65000;color.blue = 0;
1492 color.red = 65000;color.green = 0;color.blue = 40000;
1495 color.red = 1000;color.green = 10000;color.blue = 65000;
1498 color.red = 65000;color.green = 0;color.blue = 0;
1501 color.red = 0;color.green = 0;color.blue = 0;
1507 dh_set_color(gc, &color);
1509 draw_point(gc, x, ylimit+6);
1510 draw_point(gc, x, ylimit+7);
1511 draw_point(gc, x, ylimit+8);
1512 draw_point(gc, x-1, ylimit+8);
1513 draw_point(gc, x+1, ylimit+8);
1514 draw_point(gc, x, ylimit+9);
1515 draw_point(gc, x-1, ylimit+9);
1516 draw_point(gc, x+1, ylimit+9);
1517 draw_point(gc, x-2, ylimit+9);
1518 draw_point(gc, x+2, ylimit+9);
1519 draw_point(gc, x-3, ylimit+9);
1520 draw_point(gc, x+3, ylimit+9);
1521 draw_point(gc, x, ylimit+10);
1522 draw_point(gc, x-1, ylimit+10);
1523 draw_point(gc, x+1, ylimit+10);
1524 draw_point(gc, x-2, ylimit+10);
1525 draw_point(gc, x+2, ylimit+10);
1526 draw_point(gc, x-3, ylimit+10);
1527 draw_point(gc, x+3, ylimit+10);
1533 static void draw_marks(gint time_interval, gint left_mark,
1534 gint right_mark, gint ylimit, GtkWidget *da, cairo_t *gc,
ui_state *ui)
1536 gint left2 = (left_mark / time_interval) * time_interval;
1537 if (left2 < left_mark)
1539 left2 += time_interval;
1544 for (i = left2; i <= right_mark; i += time_interval)
1546 i_pixel = convert_time_to_pixels(ui->infos->width_drawing_area, i,
1547 ui->infos->current_time, ui->infos->total_time, ui->infos->zoom_coeff);
1549 draw_motif(da, gc, ylimit, i_pixel, time_interval);
1557 set_quick_preview_end_splitpoint_safe(-1, ui);
1558 ui->status->preview_start_splitpoint = -1;
1564 status->quick_preview = FALSE;
1575 static void draw_motif_splitpoints(GtkWidget *da, cairo_t *gc,
1576 gint x, gint draw, gint current_point_hundr_secs,
1577 gboolean move, gint number_splitpoint,
ui_state *ui)
1579 int m = ui->gui->margin - 1;
1582 gboolean splitpoint_checked = point.checked;
1585 color.red = 255 * 212; color.green = 255 * 100; color.blue = 255 * 200;
1586 dh_set_color(gc, &color);
1591 dh_draw_rectangle(gc, FALSE, x-6,4, 11,11);
1595 dh_draw_rectangle(gc, TRUE, x-6,4, 12,12);
1599 color.red = 255 * 220; color.green = 255 * 220; color.blue = 255 * 255;
1600 dh_set_color(gc, &color);
1602 dh_draw_rectangle(gc, TRUE, x-4,6, 8,8);
1606 color.red = 255 * 212; color.green = 255 * 196; color.blue = 255 * 221;
1607 dh_set_color(gc, &color);
1610 for(i = 0;i < 5;i++)
1612 draw_point(gc, x+i, ui->gui->erase_split_ylimit + m + 3);
1613 draw_point(gc, x-i, ui->gui->erase_split_ylimit + m + 3);
1614 draw_point(gc, x+i, ui->gui->erase_split_ylimit + m + 4);
1615 draw_point(gc, x-i, ui->gui->erase_split_ylimit + m + 4);
1621 if (splitpoint_checked)
1623 color.red = 15000;color.green = 40000;color.blue = 25000;
1627 color.red = 25000;color.green = 25000;color.blue = 40000;
1629 dh_set_color(gc, &color);
1631 dh_draw_line(gc, x, ui->gui->erase_split_ylimit + m -8, x, ui->gui->progress_ylimit + m, TRUE, TRUE);
1634 color.red = 255 * 22; color.green = 255 * 35; color.blue = 255 * 91;
1635 dh_set_color(gc, &color);
1638 for (i = -3;i <= 1;i++)
1640 draw_point(gc, x, ui->gui->erase_split_ylimit + m +i);
1642 for (i = 2;i <= 5;i++)
1644 draw_point(gc, x, ui->gui->erase_split_ylimit + m + i);
1646 for (i = 3;i <= 4;i++)
1648 draw_point(gc, x-1, ui->gui->erase_split_ylimit + m + i);
1649 draw_point(gc, x+1, ui->gui->erase_split_ylimit + m + i);
1651 for (i = 6;i <= 11;i++)
1653 draw_point(gc, x, ui->gui->erase_split_ylimit + m + i);
1657 for (i = 0;i < ui->gui->margin;i++)
1659 draw_point(gc, x, ui->gui->progress_ylimit + m - i);
1663 for (i = 0;i < ui->gui->margin;i++)
1665 draw_point(gc, x, ui->gui->splitpoint_ypos + m - i - 1);
1670 dh_set_color(gc, &color);
1671 color.red = 25000;color.green = 25000;color.blue = 25000;
1672 dh_draw_rectangle(gc, FALSE, x-6, ui->gui->splitpoint_ypos + m, 12,12);
1675 if (splitpoint_checked)
1679 gint top = ui->gui->splitpoint_ypos + m;
1680 gint bottom = ui->gui->splitpoint_ypos + m + 12;
1681 dh_draw_line(gc, left, top, right, bottom, FALSE, TRUE);
1682 dh_draw_line(gc, left, bottom, right, top, FALSE, TRUE);
1686 if (splitpoint_checked)
1688 color.red = 15000;color.green = 40000;color.blue = 25000;
1692 color.red = 25000;color.green = 25000;color.blue = 40000;
1694 dh_set_color(gc, &color);
1696 dh_draw_arc(gc, FALSE, x, ui->gui->progress_ylimit + m+ 1 + 7, 14 / 2, 0, 2 * G_PI);
1701 dh_draw_arc(gc, TRUE, x, ui->gui->progress_ylimit + m + 1 + 8, 16 / 2, 0, 2 * G_PI);
1706 gint number_of_chars = 0;
1707 gchar str[30] = {
'\0' };
1708 get_time_for_drawing(str, current_point_hundr_secs, TRUE, &number_of_chars);
1709 dh_draw_text(gc, str, x - (number_of_chars * 3), ui->gui->checkbox_ypos + ui->gui->margin - 1);
1712 if (ui->status->show_silence_wave)
1714 color.red = 0;color.green = 0;color.blue = 0;
1715 dh_set_color(gc, &color);
1716 dh_draw_line(gc, x,ui->gui->text_ypos + ui->gui->margin, x,ui->gui->wave_ypos, move, TRUE);
1721 static void draw_splitpoints(gint left_mark, gint right_mark, GtkWidget *da, cairo_t *gc,
1725 for(i = 0; i < ui->infos->splitnumber; i++ )
1728 if ((current_point_hundr_secs <= right_mark) &&
1729 (current_point_hundr_secs >= left_mark))
1732 convert_time_to_pixels(ui->infos->width_drawing_area, current_point_hundr_secs,
1733 ui->infos->current_time, ui->infos->total_time, ui->infos->zoom_coeff);
1736 gboolean draw = TRUE;
1737 if (ui->status->splitpoint_to_move == i)
1742 draw_motif_splitpoints(da, gc, split_pixel, draw, current_point_hundr_secs, FALSE, i, ui);
1747 static gint get_silence_filtered_presence_index(gfloat draw_time,
ui_infos *infos)
1750 gfloat num_of_points_coeff_f =
1751 ceil((infos->number_of_silence_points / infos->total_time) * 10);
1752 gint num_of_points_coeff = (gint)num_of_points_coeff_f;
1754 if (draw_time > infos->fourty_minutes_time)
1756 if (num_of_points_coeff < 3)
1763 if (draw_time > infos->twenty_minutes_time)
1765 if (num_of_points_coeff < 3)
1772 if (draw_time > infos->ten_minutes_time)
1774 if (num_of_points_coeff < 3)
1781 if (draw_time > infos->six_minutes_time)
1783 if (num_of_points_coeff < 3)
1790 if (draw_time > infos->three_minutes_time)
1792 if (num_of_points_coeff < 3)
1802 static gint point_is_filtered(gint index, gint filtered_index,
ui_infos *infos)
1804 if (!infos->filtered_points_presence)
1809 GArray *points_presence = g_ptr_array_index(infos->filtered_points_presence, filtered_index);
1810 return !g_array_index(points_presence, gint, index);
1813 static gint adjust_filtered_index_according_to_number_of_points(gint filtered_index,
1814 gint left_mark, gint right_mark,
ui_state *ui)
1818 if (filtered_index == 4)
1820 return filtered_index;
1823 gint number_of_points = 0;
1824 gint number_of_filtered_points = 0;
1827 for (i = 0;i < infos->number_of_silence_points;i++)
1829 long time = infos->silence_points[i].time;
1830 if ((time > right_mark) || (time < left_mark))
1835 if (filtered_index >= 0 && point_is_filtered(i, filtered_index, infos))
1837 number_of_filtered_points++;
1843 if (number_of_points <= ui->infos->silence_wave_number_of_points_threshold)
1848 if (number_of_points - number_of_filtered_points > ui->infos->silence_wave_number_of_points_threshold)
1850 return filtered_index + 1;
1853 return filtered_index;
1858 gint interpolation_text_x, gint interpolation_text_y,
1859 gfloat draw_time, gint width_drawing_area, gint y_margin,
1860 gfloat current_time, gfloat total_time, gfloat zoom_coeff,
1861 GtkWidget *da, cairo_t *gc,
ui_state *ui)
1863 if (ui->status->currently_compute_douglas_peucker_filters ||
1864 get_currently_scanning_for_silence_safe(ui))
1871 if (!ui->infos->silence_points)
1873 color.red = 0;color.green = 0;color.blue = 0;
1874 dh_set_color(gc, &color);
1875 dh_draw_text_with_size(gc,_(
"No available wave"),
1876 interpolation_text_x, interpolation_text_y, 13);
1880 double dashes[] = { 1.0, 3.0 };
1881 cairo_set_dash(gc, dashes, 0, 0.0);
1882 cairo_set_line_width(gc, 1.0);
1883 cairo_set_line_cap(gc, CAIRO_LINE_CAP_ROUND);
1885 color.red = 0;color.green = 0;color.blue = 0;
1886 dh_set_color(gc, &color);
1890 gint filtered_index = get_silence_filtered_presence_index(draw_time, ui->infos);
1891 gint interpolation_level =
1892 adjust_filtered_index_according_to_number_of_points(filtered_index,
1893 left_mark, right_mark, ui);
1895 gint stroke_counter = 0;
1898 for (i = 0;i < ui->infos->number_of_silence_points;i++)
1900 if (interpolation_level >= 0 && point_is_filtered(i, interpolation_level, ui->infos))
1905 long time = ui->infos->silence_points[i].time;
1906 if ((time > right_mark) || (time < left_mark))
1911 float level = ui->infos->silence_points[i].level;
1913 gint x = convert_time_to_pixels(width_drawing_area,
1914 (gfloat)time, current_time, total_time, zoom_coeff);
1915 gint y = y_margin + (gint)floorf(level);
1919 cairo_move_to(gc, x, y);
1924 cairo_line_to(gc, x, y);
1928 if (stroke_counter % 4 == 0)
1931 cairo_move_to(gc, x, y);
1937 color.red = 0;color.green = 0;color.blue = 0;
1938 dh_set_color(gc, &color);
1940 if (interpolation_level < 0)
1942 dh_draw_text_with_size(gc,_(
"No wave interpolation"),
1943 interpolation_text_x, interpolation_text_y, 13);
1947 gchar interpolation_text[128] = {
'\0' };
1948 g_snprintf(interpolation_text, 128, _(
"Wave interpolation level %d"), interpolation_level + 1);
1949 dh_draw_text_with_size(gc, interpolation_text, interpolation_text_x, interpolation_text_y, 13);
1952 return interpolation_level;
1955 static void draw_rectangles_between_splitpoints(cairo_t *cairo_surface,
ui_state *ui)
1960 gint point_time_left = -1;
1961 gint point_time_right = -1;
1962 get_current_splitpoints_time_left_right(&point_time_left, &point_time_right, NULL, ui);
1963 color.red = 255 * 255;color.green = 255 * 255;color.blue = 255 * 210;
1964 draw_small_rectangle(point_time_left, point_time_right, color, cairo_surface, ui);
1966 gint gray_factor = 210;
1967 color.red = 255 * gray_factor;color.green = 255 * gray_factor;color.blue = 255 * gray_factor;
1970 if (ui->infos->splitnumber == 0)
1972 draw_small_rectangle(0, ui->infos->total_time, color, cairo_surface, ui);
1977 draw_small_rectangle(
get_splitpoint_time(ui->infos->splitnumber-1, ui), ui->infos->total_time,
1978 color, cairo_surface, ui);
1980 for (i = 0; i < ui->infos->splitnumber - 1; i++ )
1987 draw_small_rectangle(left_time, right_time, color, cairo_surface, ui);
1992 #if GTK_MAJOR_VERSION <= 2
1993 static gboolean da_draw_event(GtkWidget *da, GdkEventExpose *event,
ui_state *ui)
1995 cairo_t *gc = gdk_cairo_create(da->window);
1997 static gboolean da_draw_event(GtkWidget *da, cairo_t *gc,
ui_state *ui)
2006 if ((status->playing || status->timer_active) &&
2007 get_process_in_progress_safe(ui))
2010 mycolor.red = 255 * 0; mycolor.green = 255 * 0; mycolor.blue = 255 * 255;
2011 dh_set_color(gc, &mycolor);
2012 dh_draw_text_with_size(gc, _(
" Please wait for the process to finish ..."),
2013 30, gui->margin - 3, 13);
2019 set_process_in_progress_safe(TRUE, ui);
2021 if (gui->drawing_area_expander != NULL &&
2022 !gtk_expander_get_expanded(GTK_EXPANDER(gui->drawing_area_expander)))
2024 set_process_in_progress_safe(FALSE, ui);
2029 if (status->currently_compute_douglas_peucker_filters)
2032 mycolor.red = 255 * 0; mycolor.green = 255 * 0; mycolor.blue = 255 * 255;
2033 dh_set_color(gc, &mycolor);
2034 dh_draw_text_with_size(gc, _(
" Please wait ... currently computing Douglas Peucker filters."),
2035 30, gui->margin - 3, 13);
2037 set_process_in_progress_safe(FALSE, ui);
2041 gint old_width_drawing_area = infos->width_drawing_area;
2043 int width = 0, height = 0;
2044 wh_get_widget_size(da, &width, &height);
2045 if (status->show_silence_wave)
2047 if (height != DRAWING_AREA_HEIGHT_WITH_SILENCE_WAVE)
2049 gtk_widget_set_size_request(da, DRAWING_AREA_WIDTH, DRAWING_AREA_HEIGHT_WITH_SILENCE_WAVE);
2054 if (height != DRAWING_AREA_HEIGHT)
2056 gtk_widget_set_size_request(da, DRAWING_AREA_WIDTH, DRAWING_AREA_HEIGHT);
2060 gint real_progress_length = 26;
2061 gint real_text_length = 12;
2063 gint erase_splitpoint_length = gui->real_erase_split_length + (gui->margin * 2);
2064 gint progress_length = real_progress_length + gui->margin;
2065 gint move_split_length = gui->real_move_split_length + gui->margin;
2066 gint text_length = real_text_length + gui->margin;
2067 gint checkbox_length = gui->real_checkbox_length + gui->margin;
2068 gint wave_length = gui->real_wave_length + gui->margin;
2071 gui->erase_split_ylimit = erase_splitpoint_length;
2072 gui->progress_ylimit = gui->erase_split_ylimit + progress_length;
2073 gui->splitpoint_ypos = gui->progress_ylimit + move_split_length;
2074 gui->checkbox_ypos = gui->splitpoint_ypos + checkbox_length;
2075 gui->text_ypos = gui->checkbox_ypos + text_length + gui->margin;
2076 gui->wave_ypos = gui->text_ypos + wave_length + gui->margin;
2078 gint bottom_left_middle_right_text_ypos = gui->text_ypos;
2079 if (status->show_silence_wave)
2081 bottom_left_middle_right_text_ypos = gui->wave_ypos;
2086 wh_get_widget_size(da, &infos->width_drawing_area, NULL);
2088 if (infos->width_drawing_area != old_width_drawing_area)
2090 refresh_preview_drawing_areas(gui);
2094 color.red = 255 * 235;color.green = 255 * 235; color.blue = 255 * 235;
2095 dh_set_color(gc, &color);
2098 dh_draw_rectangle(gc, TRUE, 0,0, infos->width_drawing_area, gui->wave_ypos + text_length + 2);
2100 color.red = 255 * 255;color.green = 255 * 255;color.blue = 255 * 255;
2101 dh_set_color(gc, &color);
2104 dh_draw_rectangle(gc, TRUE, 0, gui->margin, infos->width_drawing_area, gui->real_erase_split_length);
2105 dh_draw_rectangle(gc, TRUE, 0, gui->erase_split_ylimit, infos->width_drawing_area, progress_length);
2106 dh_draw_rectangle(gc, TRUE, 0, gui->progress_ylimit+gui->margin, infos->width_drawing_area, gui->real_move_split_length);
2107 dh_draw_rectangle(gc, TRUE, 0, gui->splitpoint_ypos+gui->margin, infos->width_drawing_area, gui->real_checkbox_length);
2108 dh_draw_rectangle(gc, TRUE, 0, gui->checkbox_ypos+gui->margin, infos->width_drawing_area, text_length);
2109 if (status->show_silence_wave)
2111 dh_draw_rectangle(gc, TRUE, 0, gui->text_ypos + gui->margin, infos->width_drawing_area, wave_length);
2114 if (!status->playing || !status->timer_active)
2116 color.red = 255 * 212; color.green = 255 * 100; color.blue = 255 * 200;
2117 dh_set_color(gc, &color);
2118 dh_draw_text(gc, _(
" left click on splitpoint selects it, right click erases it"),
2119 0, gui->margin - 3);
2121 color.red = 0;color.green = 0;color.blue = 0;
2122 dh_set_color(gc, &color);
2123 dh_draw_text(gc, _(
" left click + move changes song position, right click + move changes zoom"),
2124 0, gui->erase_split_ylimit + gui->margin);
2126 color.red = 15000;color.green = 40000;color.blue = 25000;
2127 dh_set_color(gc, &color);
2129 _(
" left click on point + move changes point position, right click play preview"),
2130 0, gui->progress_ylimit + gui->margin);
2132 color.red = 0; color.green = 0; color.blue = 0;
2133 dh_set_color(gc, &color);
2134 dh_draw_text(gc, _(
" left click on rectangle checks/unchecks 'keep splitpoint'"),
2135 0, gui->splitpoint_ypos + 1);
2137 set_process_in_progress_safe(FALSE, ui);
2141 gfloat left_time =
get_left_drawing_time(infos->current_time, infos->total_time, infos->zoom_coeff);
2145 gint left_mark = (gint)left_time;
2146 gint right_mark = (gint)right_time;
2151 if (right_mark > infos->total_time)
2153 right_mark = (gint)infos->total_time;
2156 gfloat total_draw_time = right_time - left_time;
2158 gchar str[30] = {
'\0' };
2159 gint beg_pixel = convert_time_to_pixels(infos->width_drawing_area, 0,
2160 infos->current_time, infos->total_time, infos->zoom_coeff);
2162 draw_rectangles_between_splitpoints(gc, ui);
2165 color.red = 255 * 150; color.green = 255 * 150; color.blue = 255 * 255;
2166 dh_set_color(gc, &color);
2169 if (get_quick_preview_end_splitpoint_safe(ui) != -1)
2172 convert_time_to_pixels(infos->width_drawing_area,
2174 infos->current_time, infos->total_time, infos->zoom_coeff);
2176 convert_time_to_pixels(infos->width_drawing_area,
2178 infos->current_time, infos->total_time, infos->zoom_coeff);
2180 gint preview_splitpoint_length = right_pixel - left_pixel + 1;
2183 dh_draw_rectangle(gc, TRUE, left_pixel, gui->progress_ylimit-2, preview_splitpoint_length, 3);
2186 if (status->quick_preview)
2188 color.red = 255 * 255;color.green = 255 * 160;color.blue = 255 * 160;
2189 dh_set_color(gc, &color);
2190 dh_draw_rectangle(gc, TRUE, left_pixel, gui->erase_split_ylimit, preview_splitpoint_length, 3);
2196 if ((status->preview_start_splitpoint != -1) &&
2197 (status->preview_start_splitpoint != (infos->splitnumber-1)))
2200 convert_time_to_pixels(infos->width_drawing_area,
2202 infos->current_time, infos->total_time, infos->zoom_coeff);
2203 dh_draw_rectangle(gc, TRUE, left_pixel, gui->progress_ylimit-2, infos->width_drawing_area-left_pixel, 3);
2206 if (status->quick_preview)
2208 color.red = 255 * 255;color.green = 255 * 160;color.blue = 255 * 160;
2209 dh_set_color(gc, &color);
2210 dh_draw_rectangle(gc, TRUE, left_pixel, gui->erase_split_ylimit, infos->width_drawing_area-left_pixel, 3);
2218 color.red = 255 * 235;color.green = 255 * 235; color.blue = 255 * 235;
2219 dh_set_color(gc, &color);
2220 dh_draw_rectangle(gc, TRUE, 0,0, beg_pixel, gui->wave_ypos);
2224 color.red = 30000;color.green = 0;color.blue = 30000;
2225 dh_set_color(gc, &color);
2227 get_time_for_drawing(str, left_time, FALSE, &nbr_chars);
2228 dh_draw_text(gc, str, 15, bottom_left_middle_right_text_ypos);
2232 convert_time_to_pixels(infos->width_drawing_area, infos->total_time,
2233 infos->current_time, infos->total_time, infos->zoom_coeff);
2235 if (right_time >= infos->total_time)
2237 color.red = 255 * 235;color.green = 255 * 235;color.blue = 255 * 235;
2238 dh_set_color(gc, &color);
2239 dh_draw_rectangle(gc, TRUE, end_pixel,0, infos->width_drawing_area, bottom_left_middle_right_text_ypos);
2243 color.red = 30000;color.green = 0;color.blue = 30000;
2244 dh_set_color(gc, &color);
2246 get_time_for_drawing(str, right_time, FALSE, &nbr_chars);
2247 dh_draw_text(gc, str, infos->width_drawing_area - 52, bottom_left_middle_right_text_ypos);
2250 if (total_draw_time < infos->hundr_secs_th)
2252 draw_marks(HUNDR_SECONDS, left_mark, right_mark,
2253 gui->erase_split_ylimit + progress_length/4, da, gc, ui);
2255 if (total_draw_time < infos->tens_of_secs_th)
2257 draw_marks(TENS_OF_SECONDS, left_mark, right_mark,
2258 gui->erase_split_ylimit + progress_length/4, da, gc, ui);
2260 if (total_draw_time < infos->secs_th)
2262 draw_marks(SECONDS, left_mark, right_mark,
2263 gui->erase_split_ylimit + progress_length/4, da, gc, ui);
2265 if (total_draw_time < infos->ten_secs_th)
2267 draw_marks(TEN_SECONDS, left_mark, right_mark,
2268 gui->erase_split_ylimit + progress_length/4, da, gc, ui);
2270 if (total_draw_time < infos->minutes_th)
2272 draw_marks(MINUTES, left_mark, right_mark,
2273 gui->erase_split_ylimit + progress_length/4, da, gc, ui);
2275 if (total_draw_time < infos->ten_minutes_th)
2277 draw_marks(TEN_MINUTES, left_mark, right_mark,
2278 gui->erase_split_ylimit + progress_length/4, da, gc, ui);
2280 draw_marks(HOURS, left_mark, right_mark,
2281 gui->erase_split_ylimit + progress_length/4, da, gc, ui);
2284 if (status->button1_pressed)
2286 gint move_pixel = convert_time_to_pixels(infos->width_drawing_area,
2287 status->move_time, infos->current_time,
2288 infos->total_time, infos->zoom_coeff);
2290 if (status->move_splitpoints)
2292 draw_motif_splitpoints(da, gc, move_pixel,TRUE, status->move_time,
2293 TRUE, status->splitpoint_to_move, ui);
2295 color.red = 0;color.green = 0;color.blue = 0;
2296 dh_set_color(gc, &color);
2298 get_time_for_drawing(str, infos->current_time, FALSE, &nbr_chars);
2299 dh_draw_text(gc, str, infos->width_drawing_area/2-11, bottom_left_middle_right_text_ypos);
2303 color.red = 255 * 255;color.green = 0;color.blue = 0;
2304 dh_set_color(gc, &color);
2305 dh_draw_line(gc, move_pixel, gui->erase_split_ylimit, move_pixel, gui->progress_ylimit, TRUE, TRUE);
2307 if (status->show_silence_wave)
2309 dh_draw_line(gc, move_pixel, gui->text_ypos + gui->margin, move_pixel, gui->wave_ypos, TRUE, TRUE);
2312 color.red = 0;color.green = 0;color.blue = 0;
2313 dh_set_color(gc, &color);
2315 get_time_for_drawing(str, status->move_time, FALSE, &nbr_chars);
2316 dh_draw_text(gc, str, infos->width_drawing_area/2-11, bottom_left_middle_right_text_ypos);
2321 color.red = 0;color.green = 0;color.blue = 0;
2322 dh_set_color(gc, &color);
2324 get_time_for_drawing(str, infos->current_time, FALSE, &nbr_chars);
2325 dh_draw_text(gc, str, infos->width_drawing_area/2-11, bottom_left_middle_right_text_ypos);
2328 color.red = 255 * 255;color.green = 0;color.blue = 0;
2329 dh_set_color(gc, &color);
2332 dh_draw_line(gc, infos->width_drawing_area/2, gui->erase_split_ylimit,
2333 infos->width_drawing_area/2, gui->progress_ylimit, FALSE, TRUE);
2336 if (status->show_silence_wave)
2339 infos->width_drawing_area/2 + 3, gui->wave_ypos - gui->margin * 4,
2341 infos->width_drawing_area, gui->text_ypos + gui->margin,
2342 infos->current_time, infos->total_time, infos->zoom_coeff,
2346 color.red = 255 * 255;color.green = 0;color.blue = 0;
2347 dh_set_color(gc, &color);
2348 dh_draw_line(gc, infos->width_drawing_area/2, gui->text_ypos + gui->margin,
2349 infos->width_drawing_area/2, gui->wave_ypos, FALSE, TRUE);
2352 draw_splitpoints(left_mark, right_mark, da, gc, ui);
2354 #if GTK_MAJOR_VERSION <= 2
2358 set_process_in_progress_safe(FALSE, ui);
2363 static void draw_small_rectangle(gint time_left, gint time_right,
2364 GdkColor color, cairo_t *cairo_surface,
ui_state *ui)
2366 if (time_left == -1 || time_right == -1)
2371 gint pixels_left = convert_time_to_pixels(ui->infos->width_drawing_area, time_left,
2372 ui->infos->current_time, ui->infos->total_time, ui->infos->zoom_coeff);
2373 gint pixels_right = convert_time_to_pixels(ui->infos->width_drawing_area, time_right,
2374 ui->infos->current_time, ui->infos->total_time, ui->infos->zoom_coeff);
2375 gint pixels_length = pixels_right - pixels_left;
2377 dh_set_color(cairo_surface, &color);
2378 dh_draw_rectangle(cairo_surface, TRUE, pixels_left, ui->gui->erase_split_ylimit,
2379 pixels_length, ui->gui->progress_ylimit - ui->gui->erase_split_ylimit+1);
2381 if (ui->status->show_silence_wave)
2383 dh_draw_rectangle(cairo_surface, TRUE, pixels_left, ui->gui->text_ypos + ui->gui->margin,
2384 pixels_length, ui->gui->real_wave_length + ui->gui->margin);
2388 void get_current_splitpoints_time_left_right(gint *time_left, gint *time_right,
2389 gint *splitpoint_left,
ui_state *ui)
2394 for (i = 0; i < infos->splitnumber; i++ )
2397 if (current_point_hundr_secs < infos->current_time - (DELTA * 2))
2399 *time_left = current_point_hundr_secs;
2403 if (current_point_hundr_secs > infos->current_time + (DELTA * 2))
2405 *time_right = current_point_hundr_secs;
2406 if (splitpoint_left != NULL) { *splitpoint_left = i; }
2411 if (splitpoint_left != NULL && *splitpoint_left == -1)
2413 *splitpoint_left = infos->splitnumber;
2427 static gint get_splitpoint_clicked(gint button_y, gint type_clicked, gint type,
ui_state *ui)
2429 gint time_pos, time_right_pos;
2430 gint left_time =
get_left_drawing_time(ui->infos->current_time, ui->infos->total_time, ui->infos->zoom_coeff);
2434 if (type_clicked != 3)
2437 time_pos = left_time + pixels_to_time(ui->infos->width_drawing_area, ui->status->button_x, ui);
2441 but_y = ui->status->button_y2;
2442 time_pos = left_time + pixels_to_time(ui->infos->width_drawing_area, ui->status->button_x2, ui);
2447 gint pixels_to_look_for = ui->gui->real_erase_split_length / 2;
2450 pixels_to_look_for = ui->gui->real_move_split_length / 2;
2453 if (type_clicked != 3)
2455 time_right_pos = left_time +
2456 pixels_to_time(ui->infos->width_drawing_area, ui->status->button_x + pixels_to_look_for, ui);
2460 time_right_pos = left_time +
2461 pixels_to_time(ui->infos->width_drawing_area, ui->status->button_x2 + pixels_to_look_for, ui);
2466 gint time_margin = time_right_pos - time_pos;
2468 gint margin1, margin2;
2472 margin1 = ui->gui->progress_ylimit + ui->gui->margin;
2473 margin2 = ui->gui->progress_ylimit + ui->gui->margin + ui->gui->real_move_split_length;
2477 margin1 = ui->gui->margin;
2478 margin2 = ui->gui->margin + ui->gui->real_erase_split_length;
2482 margin1 = ui->gui->splitpoint_ypos + ui->gui->margin;
2483 margin2 = ui->gui->splitpoint_ypos + ui->gui->margin + ui->gui->real_checkbox_length;
2487 if ((but_y < margin1) || (but_y > margin2))
2493 for(i = 0; i < ui->infos->splitnumber; i++ )
2496 gint current_point_left = current_point_hundr_secs - time_margin;
2497 gint current_point_right = current_point_hundr_secs + time_margin;
2499 if ((time_pos >= current_point_left) && (time_pos <= current_point_right))
2508 void set_preview_start_position_safe(gint value,
ui_state *ui)
2510 lock_mutex(&ui->variables_mutex);
2511 ui->status->preview_start_position = value;
2512 unlock_mutex(&ui->variables_mutex);
2515 gint get_preview_start_position_safe(
ui_state *ui)
2517 lock_mutex(&ui->variables_mutex);
2518 gint preview_start_position = ui->status->preview_start_position;
2519 unlock_mutex(&ui->variables_mutex);
2521 return preview_start_position;
2527 if (splitpoint_to_preview == -1)
2535 status->preview_start_splitpoint = splitpoint_to_preview;
2545 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(ui->gui->pause_button), FALSE);
2548 if (splitpoint_to_preview < ui->infos->splitnumber-1)
2550 set_quick_preview_end_splitpoint_safe(splitpoint_to_preview + 1, ui);
2554 set_quick_preview_end_splitpoint_safe(-1, ui);
2557 player_seek(get_preview_start_position_safe(ui) * 10, ui);
2558 change_progress_bar(ui);
2561 status->quick_preview = FALSE;
2562 if (get_quick_preview_end_splitpoint_safe(ui) != -1)
2564 status->quick_preview = TRUE;
2567 if (status->preview_start_splitpoint == (ui->infos->splitnumber-1))
2574 static gboolean da_press_event(GtkWidget *da, GdkEventButton *event,
ui_state *ui)
2576 if (!ui->status->playing || !ui->status->timer_active)
2586 if (event->button == 1)
2588 status->button_x =
event->x;
2589 status->button_y =
event->y;
2590 status->button1_pressed = TRUE;
2592 if ((status->button_y > gui->progress_ylimit + gui->margin) &&
2593 (status->button_y < gui->progress_ylimit + gui->margin + gui->real_move_split_length))
2595 status->splitpoint_to_move = get_splitpoint_clicked(status->button_y, 1, 2, ui);
2596 if (status->splitpoint_to_move != -1)
2598 status->move_splitpoints = TRUE;
2604 if ((status->button_y > gui->margin) &&
2605 (status->button_y < gui->margin + gui->real_erase_split_length))
2607 gint splitpoint_selected = get_splitpoint_clicked(status->button_y, 1, 1, ui);
2608 if (splitpoint_selected != -1)
2610 status->select_splitpoints = TRUE;
2613 refresh_drawing_area(gui);
2618 if ((status->button_y > gui->splitpoint_ypos + gui->margin) &&
2619 (status->button_y < gui->splitpoint_ypos + gui->margin + gui->real_checkbox_length))
2621 gint splitpoint_selected = get_splitpoint_clicked(status->button_y, 1, 3, ui);
2622 if (splitpoint_selected != -1)
2624 status->check_splitpoint = TRUE;
2627 refresh_drawing_area(gui);
2632 if (!status->move_splitpoints)
2634 status->move_time = infos->current_time;
2645 if (event->button == 3)
2647 status->button_x2 =
event->x;
2648 status->button_y2 =
event->y;
2649 status->button2_pressed = TRUE;
2650 infos->zoom_coeff_old = infos->zoom_coeff;
2652 if ((status->button_y2 > gui->progress_ylimit + gui->margin) &&
2653 (status->button_y2 < gui->progress_ylimit + gui->margin + gui->real_move_split_length))
2660 if ((status->button_y2 > gui->margin) &&
2661 (status->button_y2 < gui->margin + gui->real_erase_split_length))
2663 gint splitpoint_to_erase = get_splitpoint_clicked(status->button_y2, 3, 1, ui);
2664 if (splitpoint_to_erase != -1)
2666 status->remove_splitpoints = TRUE;
2670 refresh_drawing_area(gui);
2679 static gboolean da_unpress_event(GtkWidget *da, GdkEventButton *event,
ui_state *ui)
2683 if (!status->playing || !status->timer_active)
2688 if (event->button == 1)
2690 status->button1_pressed = FALSE;
2693 if (!status->move_splitpoints && !status->remove_splitpoints &&
2694 !status->select_splitpoints && !status->check_splitpoint)
2698 change_progress_bar(ui);
2701 if (get_quick_preview_end_splitpoint_safe(ui) == -1)
2718 if (get_quick_preview_end_splitpoint_safe(ui) != -1)
2724 status->quick_preview = TRUE;
2729 else if (status->move_splitpoints)
2732 status->splitpoint_to_move = -1;
2735 status->move_splitpoints = FALSE;
2736 status->select_splitpoints = FALSE;
2737 status->check_splitpoint = FALSE;
2739 else if (event->button == 3)
2741 status->button2_pressed = FALSE;
2742 status->remove_splitpoints = FALSE;
2746 refresh_drawing_area(ui->gui);
2751 static gboolean da_notify_event(GtkWidget *da, GdkEventMotion *event,
ui_state *ui)
2756 if ((status->playing && status->timer_active) &&
2757 (status->button1_pressed || status->button2_pressed))
2760 GdkModifierType state;
2761 wh_get_pointer(event, &x, &y, &state);
2764 wh_get_widget_size(ui->gui->drawing_area, &width, NULL);
2765 gfloat width_drawing_area = (gfloat) width;
2772 if (status->button1_pressed)
2774 if (status->move_splitpoints)
2777 status->move_time = splitpoint_time +
2778 pixels_to_time(width_drawing_area, (x - status->button_x), ui);
2782 if (status->remove_splitpoints || status->select_splitpoints || status->check_splitpoint)
2784 status->move_time = infos->current_time;
2789 infos->current_time + pixels_to_time(width_drawing_area, (x - status->button_x), ui);
2793 if (status->move_time < 0)
2795 status->move_time = 0;
2797 if (status->move_time > infos->total_time)
2799 status->move_time = infos->total_time;
2802 refresh_drawing_area(ui->gui);
2806 if (status->button2_pressed)
2808 gint diff = -((
event->x - status->button_x2) * 1);
2809 if (diff < (-width_drawing_area + 1))
2811 diff = -width_drawing_area + 1;
2813 if (diff > (width_drawing_area - 1))
2815 diff = width_drawing_area - 1;
2818 infos->zoom_coeff = diff / (width_drawing_area);
2820 if (infos->zoom_coeff < 0)
2822 infos->zoom_coeff = 1 / (infos->zoom_coeff + 1);
2826 infos->zoom_coeff = 1 - infos->zoom_coeff;
2829 infos->zoom_coeff = infos->zoom_coeff_old * infos->zoom_coeff;
2831 adjust_zoom_coeff(infos);
2833 refresh_drawing_area(ui->gui);
2841 void adjust_zoom_coeff(
ui_infos *infos)
2843 if (infos->zoom_coeff < 0.2)
2845 infos->zoom_coeff = 0.2;
2847 if (infos->zoom_coeff > 10 * infos->total_time / 6000)
2849 infos->zoom_coeff = 10 * infos->total_time / 6000;
2853 static void drawing_area_expander_event(GObject *
object, GParamSpec *param_spec,
ui_state *ui)
2860 GtkExpander *expander = GTK_EXPANDER(
object);
2861 if (gtk_expander_get_expanded(expander))
2863 gtk_widget_show(ui->gui->silence_wave_check_button);
2867 gtk_widget_hide(ui->gui->silence_wave_check_button);
2871 static GtkWidget *create_drawing_area(
ui_state *ui)
2873 GtkWidget *frame = gtk_frame_new(NULL);
2876 color.red = 65000; color.green = 0; color.blue = 0;
2877 gtk_widget_modify_bg(frame, GTK_STATE_NORMAL, &color);
2879 gtk_frame_set_shadow_type(GTK_FRAME(frame), GTK_SHADOW_NONE);
2881 GtkWidget *drawing_area = gtk_drawing_area_new();
2882 dnd_add_drag_data_received_to_widget(drawing_area,
2883 DND_SINGLE_MODE_AUDIO_FILE_AND_DATA_FILES, ui);
2885 ui->gui->drawing_area = drawing_area;
2887 gtk_widget_set_size_request(drawing_area, DRAWING_AREA_WIDTH, DRAWING_AREA_HEIGHT);
2889 #if GTK_MAJOR_VERSION <= 2
2890 g_signal_connect(drawing_area,
"expose_event", G_CALLBACK(da_draw_event), ui);
2892 g_signal_connect(drawing_area,
"draw", G_CALLBACK(da_draw_event), ui);
2895 g_signal_connect(drawing_area,
"button_press_event", G_CALLBACK(da_press_event), ui);
2896 g_signal_connect(drawing_area,
"button_release_event", G_CALLBACK(da_unpress_event), ui);
2897 g_signal_connect(drawing_area,
"motion_notify_event", G_CALLBACK(da_notify_event), ui);
2899 gtk_widget_set_events(drawing_area, gtk_widget_get_events(drawing_area)
2900 | GDK_LEAVE_NOTIFY_MASK | GDK_BUTTON_PRESS_MASK
2901 | GDK_BUTTON_RELEASE_MASK | GDK_POINTER_MOTION_MASK
2902 | GDK_POINTER_MOTION_HINT_MASK);
2904 gtk_container_add(GTK_CONTAINER(frame), drawing_area);
2906 GtkWidget *drawing_area_expander =
2907 gtk_expander_new_with_mnemonic(_(
"Splitpoints and amplitude wave v_iew"));
2908 ui->gui->drawing_area_expander = drawing_area_expander;
2909 gtk_expander_set_expanded(GTK_EXPANDER(drawing_area_expander), TRUE);
2910 g_signal_connect(drawing_area_expander,
"notify::expanded",
2911 G_CALLBACK(drawing_area_expander_event), ui);
2912 gtk_container_add(GTK_CONTAINER(drawing_area_expander), frame);
2914 return drawing_area_expander;
2920 GtkWidget *main_hbox = wh_hbox_new();
2922 GtkWidget *vbox = wh_vbox_new();
2923 gtk_box_pack_start(GTK_BOX(main_hbox), vbox, TRUE, TRUE, 0);
2926 GtkWidget *hbox = create_filename_player_hbox(ui->gui);
2927 gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 5);
2930 hbox = create_song_informations_hbox(ui->gui);
2931 gtk_container_set_border_width(GTK_CONTAINER (hbox), 0);
2932 gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 3);
2935 hbox = create_song_bar_hbox(ui);
2936 gtk_container_set_border_width(GTK_CONTAINER(hbox), 0);
2937 gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
2940 GtkWidget *drawing_area = create_drawing_area(ui);
2941 gtk_container_set_border_width(GTK_CONTAINER(drawing_area), 0);
2942 gtk_box_pack_start(GTK_BOX(vbox), drawing_area, FALSE, FALSE, 0);
2945 hbox = create_player_buttons_hbox(ui);
2946 gtk_container_set_border_width(GTK_CONTAINER(hbox), 0);
2947 gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
2960 gboolean name_already_exists_in_playlist = FALSE;
2962 GtkTreeModel *model = gtk_tree_view_get_model(ui->gui->playlist_tree);
2964 gchar *filename = NULL;
2969 while (i < ui->infos->playlist_tree_number)
2971 GtkTreePath *path = gtk_tree_path_new_from_indices(i ,-1);
2972 gtk_tree_model_get_iter(model, &iter, path);
2973 gtk_tree_model_get(model, &iter, COL_FILENAME, &filename, -1);
2975 if (strcmp(filename, name) == 0)
2977 name_already_exists_in_playlist = TRUE;
2985 if (! name_already_exists_in_playlist)
2987 gtk_widget_set_sensitive(ui->gui->playlist_remove_all_files_button,TRUE);
2988 gtk_list_store_append(GTK_LIST_STORE(model), &iter);
2991 gtk_list_store_set (GTK_LIST_STORE(model),
2996 ui->infos->playlist_tree_number++;
3000 static GtkTreeModel *create_playlist_model()
3003 GtkListStore * model = gtk_list_store_new(PLAYLIST_COLUMNS, G_TYPE_STRING, G_TYPE_STRING);
3004 return GTK_TREE_MODEL(model);
3008 static GtkTreeView *create_playlist_tree()
3010 GtkTreeModel *model = create_playlist_model();
3011 GtkTreeView *playlist_tree = GTK_TREE_VIEW(gtk_tree_view_new_with_model(model));
3012 gtk_tree_view_set_headers_visible(playlist_tree, FALSE);
3013 return playlist_tree;
3019 GtkCellRendererText *renderer = GTK_CELL_RENDERER_TEXT(gtk_cell_renderer_text_new());
3020 g_object_set_data(G_OBJECT(renderer),
"col", GINT_TO_POINTER(COL_NAME));
3022 GtkTreeViewColumn *name_column = gtk_tree_view_column_new_with_attributes
3023 (_(
"History"), GTK_CELL_RENDERER(renderer),
"text", COL_NAME, NULL);
3024 gtk_tree_view_insert_column(playlist_tree, GTK_TREE_VIEW_COLUMN(name_column), COL_NAME);
3026 gtk_tree_view_column_set_alignment(GTK_TREE_VIEW_COLUMN(name_column), 0.5);
3027 gtk_tree_view_column_set_sizing(GTK_TREE_VIEW_COLUMN(name_column), GTK_TREE_VIEW_COLUMN_AUTOSIZE);
3031 static void playlist_selection_changed(GtkTreeSelection *selec,
ui_state *ui)
3033 GtkTreeModel *model = gtk_tree_view_get_model(ui->gui->playlist_tree);
3034 GtkTreeSelection *selection = gtk_tree_view_get_selection(ui->gui->playlist_tree);
3035 GList *selected_list = gtk_tree_selection_get_selected_rows(selection, &model);
3036 if (g_list_length(selected_list) > 0)
3038 gtk_widget_set_sensitive(ui->gui->playlist_remove_file_button, TRUE);
3042 gtk_widget_set_sensitive(ui->gui->playlist_remove_file_button, FALSE);
3047 static void playlist_remove_file_button_event(GtkWidget *widget,
ui_state *ui)
3049 GtkTreeModel *model = gtk_tree_view_get_model(ui->gui->playlist_tree);
3050 GtkTreeSelection *selection = gtk_tree_view_get_selection(ui->gui->playlist_tree);
3051 GList *selected_list = gtk_tree_selection_get_selected_rows(selection, &model);
3053 gchar *filename = NULL;
3055 while (g_list_length(selected_list) > 0)
3057 GList *current_element = g_list_last(selected_list);
3058 GtkTreePath *path = current_element->data;
3061 gtk_tree_model_get_iter(model, &iter, path);
3062 gtk_tree_model_get(model, &iter,
3063 COL_FILENAME, &filename, -1);
3066 gtk_list_store_remove(GTK_LIST_STORE(model), &iter);
3067 selected_list = g_list_remove(selected_list, path);
3069 ui->infos->playlist_tree_number--;
3071 gtk_tree_path_free(path);
3075 if (ui->infos->playlist_tree_number == 0)
3077 gtk_widget_set_sensitive(ui->gui->playlist_remove_all_files_button, FALSE);
3080 gtk_widget_set_sensitive(ui->gui->playlist_remove_file_button,FALSE);
3082 g_list_foreach(selected_list, (GFunc)gtk_tree_path_free, NULL);
3083 g_list_free(selected_list);
3087 static void playlist_remove_all_files_button_event(GtkWidget *widget,
ui_state *ui)
3089 GtkTreeModel *model = gtk_tree_view_get_model(ui->gui->playlist_tree);
3091 gchar *filename = NULL;
3092 while (ui->infos->playlist_tree_number > 0)
3095 gtk_tree_model_get_iter_first(model, &iter);
3096 gtk_tree_model_get(model, &iter,
3097 COL_FILENAME, &filename, -1);
3098 gtk_list_store_remove(GTK_LIST_STORE(model), &iter);
3099 ui->infos->playlist_tree_number--;
3103 gtk_widget_set_sensitive(ui->gui->playlist_remove_all_files_button, FALSE);
3104 gtk_widget_set_sensitive(ui->gui->playlist_remove_file_button, FALSE);
3108 static GtkWidget *create_delete_buttons_hbox(
ui_state *ui)
3110 GtkWidget *hbox = wh_hbox_new();
3112 GtkWidget *playlist_remove_file_button =
3114 ui->gui->playlist_remove_file_button = playlist_remove_file_button;
3115 gtk_box_pack_start(GTK_BOX(hbox), playlist_remove_file_button, FALSE, FALSE, 5);
3116 gtk_widget_set_sensitive(playlist_remove_file_button,FALSE);
3117 g_signal_connect(G_OBJECT(playlist_remove_file_button),
"clicked",
3118 G_CALLBACK(playlist_remove_file_button_event), ui);
3120 GtkWidget *playlist_remove_all_files_button =
3122 ui->gui->playlist_remove_all_files_button = playlist_remove_all_files_button;
3123 gtk_box_pack_start(GTK_BOX(hbox), playlist_remove_all_files_button, FALSE, FALSE, 5);
3124 gtk_widget_set_sensitive(playlist_remove_all_files_button,FALSE);
3125 g_signal_connect(G_OBJECT(playlist_remove_all_files_button),
"clicked",
3126 G_CALLBACK(playlist_remove_all_files_button_event), ui);
3134 GtkWidget *vbox = wh_vbox_new();
3138 GtkTreeView *playlist_tree = create_playlist_tree();
3139 dnd_add_drag_data_received_to_widget(GTK_WIDGET(playlist_tree), DND_SINGLE_MODE_AUDIO_FILE, ui);
3141 ui->gui->playlist_tree = playlist_tree;
3142 GtkWidget *scrolled_window = gtk_scrolled_window_new(NULL, NULL);
3143 gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scrolled_window), GTK_SHADOW_NONE);
3144 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled_window),
3145 GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
3146 gtk_box_pack_start(GTK_BOX(vbox), scrolled_window, TRUE, TRUE, 0);
3149 gtk_container_add(GTK_CONTAINER(scrolled_window), GTK_WIDGET(playlist_tree));
3150 g_signal_connect(G_OBJECT(playlist_tree),
"row-activated",
3154 GtkTreeSelection *playlist_tree_selection = gtk_tree_view_get_selection(playlist_tree);
3155 g_signal_connect(G_OBJECT(playlist_tree_selection),
"changed",
3156 G_CALLBACK(playlist_selection_changed), ui);
3157 gtk_tree_selection_set_mode(GTK_TREE_SELECTION(playlist_tree_selection), GTK_SELECTION_MULTIPLE);
3160 GtkWidget *delete_buttons_hbox = create_delete_buttons_hbox(ui);
3161 gtk_box_pack_start(GTK_BOX(vbox), delete_buttons_hbox, FALSE, FALSE, 2);
3163 GtkWidget *history_expander = gtk_expander_new_with_mnemonic(_(
"Files h_istory"));
3164 gtk_expander_set_expanded(GTK_EXPANDER(history_expander), FALSE);
3165 gtk_container_add(GTK_CONTAINER(history_expander), vbox);
3167 GtkWidget *main_hbox = wh_hbox_new();
3168 gtk_box_pack_start(GTK_BOX(main_hbox), history_expander, TRUE, TRUE, 4);
3173 static void action_set_sensitivity(gchar *name, gboolean sensitivity,
gui_state *gui)
3175 GtkAction *action = gtk_action_group_get_action(gui->action_group, name);
3176 gtk_action_set_sensitive(action, sensitivity);
3179 void player_key_actions_set_sensitivity(gboolean sensitivity,
gui_state *gui)
3181 action_set_sensitivity(
"Player_pause", sensitivity, gui);
3182 action_set_sensitivity(
"Player_forward", sensitivity, gui);
3183 action_set_sensitivity(
"Player_backward", sensitivity, gui);
3184 action_set_sensitivity(
"Player_small_forward", sensitivity, gui);
3185 action_set_sensitivity(
"Player_small_backward", sensitivity, gui);
3186 action_set_sensitivity(
"Player_big_forward", sensitivity, gui);
3187 action_set_sensitivity(
"Player_big_backward", sensitivity, gui);
3188 action_set_sensitivity(
"Player_next_splitpoint", sensitivity, gui);
3189 action_set_sensitivity(
"Player_previous_splitpoint", sensitivity, gui);
3190 action_set_sensitivity(
"Add_splitpoint", sensitivity, gui);
3191 action_set_sensitivity(
"Delete_closest_splitpoint", sensitivity, gui);
3192 action_set_sensitivity(
"Zoom_in", sensitivity, gui);
3193 action_set_sensitivity(
"Zoom_out", sensitivity, gui);
3203 if (get_process_in_progress_safe(ui))
3209 set_process_in_progress_safe(TRUE, ui);
3229 gtk_widget_set_sensitive(gui->silence_wave_check_button, FALSE);
3231 clear_data_player(gui);
3232 status->playing = FALSE;
3235 set_process_in_progress_safe(FALSE, ui);
3239 gtk_widget_set_sensitive(gui->silence_wave_check_button, TRUE);
3241 if (status->playing)
3247 print_all_song_infos(ui);
3248 print_song_time_elapsed(ui);
3249 gtk_widget_set_sensitive(GTK_WIDGET(gui->progress_bar), TRUE);
3255 if (!status->stream)
3257 change_progress_bar(ui);
3261 if (status->preview_start_splitpoint != -1)
3265 if (status->preview_start_splitpoint + 1 < infos->splitnumber)
3267 set_quick_preview_end_splitpoint_safe(status->preview_start_splitpoint + 1, ui);
3271 if (status->preview_start_splitpoint + 1 == infos->splitnumber)
3273 set_quick_preview_end_splitpoint_safe(-1, ui);
3279 if (status->quick_preview)
3281 gint stop_splitpoint =
get_splitpoint_time(get_quick_preview_end_splitpoint_safe(ui), ui);
3283 if ((stop_splitpoint < (gint)infos->current_time)
3284 && (get_quick_preview_end_splitpoint_safe(ui) != -1))
3286 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(gui->pause_button), TRUE);
3292 gtk_widget_set_sensitive(GTK_WIDGET(gui->volume_button), TRUE);
3296 status->playing = FALSE;
3297 reset_label_time(gui);
3302 status->only_press_pause = TRUE;
3303 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(gui->pause_button), TRUE);
3304 status->only_press_pause = FALSE;
3308 status->only_press_pause = TRUE;
3309 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(gui->pause_button), FALSE);
3310 status->only_press_pause = FALSE;
3315 if ((infos->player_minutes != 0) || (infos->player_seconds != 0))
3317 infos->player_minutes = 0;
3318 infos->player_seconds = 0;
3321 print_player_filename(ui);
3322 reset_song_infos(gui);
3323 reset_label_time(gui);
3324 reset_inactive_progress_bar(gui);
3325 gtk_widget_set_sensitive(gui->player_add_button, FALSE);
3329 if ((ui->status->change_volume)&& (!ui->status->on_the_volume_button))
3331 change_volume_button(ui);
3335 if (status->playing)
3337 gtk_widget_set_sensitive(gui->player_add_button, TRUE);
3338 gtk_widget_set_sensitive(gui->stop_button, TRUE);
3339 wh_set_image_on_button(GTK_BUTTON(gui->stop_button), g_object_ref(gui->StopButton_active));
3341 gtk_widget_set_sensitive(gui->pause_button, TRUE);
3342 wh_set_image_on_button(GTK_BUTTON(gui->pause_button), g_object_ref(gui->PauseButton_active));
3344 player_key_actions_set_sensitivity(TRUE, gui);
3348 gtk_widget_set_sensitive(gui->stop_button, FALSE);
3349 wh_set_image_on_button(GTK_BUTTON(gui->stop_button), g_object_ref(gui->StopButton_inactive));
3351 gtk_widget_set_sensitive(gui->pause_button, FALSE);
3352 wh_set_image_on_button(GTK_BUTTON(gui->pause_button), g_object_ref(gui->PauseButton_inactive));
3354 player_key_actions_set_sensitivity(FALSE, gui);
3357 set_process_in_progress_safe(FALSE, ui);
3363 void file_chooser_ok_event(gchar *fname,
ui_state *ui)
3366 gtk_widget_set_sensitive(ui->gui->play_button, TRUE);
3367 wh_set_image_on_button(GTK_BUTTON(ui->gui->play_button), g_object_ref(ui->gui->PlayButton_active));
3369 ui->status->file_browsed = TRUE;
3371 if (ui->status->timer_active)
3373 GList *song_list = NULL;
3374 song_list = g_list_append(song_list, fname);
3380 else if (ui->status->playing)