/* * Sweep, a sound wave editor. * * Copyright (C) 2000 Conrad Parker * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifdef HAVE_CONFIG_H # include #endif #include #include #include #include #include "callbacks.h" #include #include #include #include #include #include "sample.h" #include "interface.h" #include "edit.h" #include "head.h" #include "sample-display.h" #include "play.h" #include "driver.h" #include "undo_dialog.h" #include "paste_dialogs.h" #include "print.h" #include "record.h" #include "file_dialogs.h" /* * Default zooming parameters. * * DEFAULT_ZOOM sets the ratio for zooming. Each time zoom_in is * called, the view is adjusted to be 1/DEFAULT_ZOOM its current * length. Each time zoom_out is called, the view is adjusted to * DEFAULT_ZOOM times its current length. * * If you alter this, make sure * (DEFAULT_ZOOM - 1) * DEFAULT_MIN_ZOOM > 1 * * where DEFAULT_MIN_ZOOM is defined in view.c */ #define DEFAULT_ZOOM 2.0 #define ZOOM_FRAMERATE 10 /* Sample creation */ void sample_new_empty_cb (GtkWidget * widget, gpointer data) { sw_view * view = (sw_view *)data; if (view == NULL) { create_sample_new_dialog_defaults (NULL); } else { create_sample_new_dialog_like (view->sample); } } void sample_new_copy_cb (GtkWidget * widget, gpointer data) { sw_sample * ns; SampleDisplay * sd = SAMPLE_DISPLAY(data); sw_sample * s; sw_view * v; s = sd->view->sample; if(!s) return; ns = sample_new_copy(s); while (ns->color == s->color) { ns->color = (random()) % VIEW_COLOR_MAX; } v = view_new_all (ns, 1.0); sample_add_view (ns, v); sample_bank_add(ns); } /* Generic repeater */ static void view_init_repeater (sw_view * view, GtkFunction function, gpointer data) { function (data); if (view->repeater_tag <= 0) { view->repeater_tag = g_timeout_add ((guint32)1000/ZOOM_FRAMERATE, (GSourceFunc) function, data); } } void repeater_released_cb (GtkWidget * widget, gpointer data) { sw_view * view = (sw_view *)data; if (view->repeater_tag > 0) { g_source_remove(view->repeater_tag); view->repeater_tag = 0; } } /* View */ void view_new_all_cb (GtkWidget * widget, gpointer data) { SampleDisplay * sd = SAMPLE_DISPLAY(data); sw_sample * s; sw_view * v; s = sd->view->sample; v = view_new_all(s, 1.0); sample_add_view (s, v); } void view_new_cb (GtkWidget * widget, gpointer data) { SampleDisplay * sd = SAMPLE_DISPLAY(data); sw_sample * s; sw_view * view, * v; v = sd->view; s = v->sample; view = view_new (s, v->start, v->end, s->play_head->gain); sample_add_view (s, view); } void view_close_cb (GtkWidget * widget, gpointer data) { SampleDisplay * sd = SAMPLE_DISPLAY(data); sw_view * v; v = sd->view; view_close(v); } void exit_cb (GtkWidget * widget, gpointer data) { sweep_quit (); } /* Tools */ void set_tool_cb (GtkWidget * widget, gpointer data) { g_print ("NOOOOOOOOOOOOOO global current_tool\n"); } void view_set_tool_cb (GtkWidget * widget, gpointer data) { sw_view * view = (sw_view *)data; sw_tool_t tool; tool = (sw_tool_t) GPOINTER_TO_INT(g_object_get_data (G_OBJECT(widget), "default")); view->current_tool = tool; view_refresh_tool_buttons (view); } /* Zooming */ static gboolean zoom_in_step (gpointer data) { sw_view * view = (sw_view *)data; view_zoom_in (view, DEFAULT_ZOOM); return TRUE; } void zoom_in_cb (GtkWidget * widget, gpointer data) { sw_view * view = (sw_view *)data; view_zoom_in (view, DEFAULT_ZOOM); } static gboolean zoom_out_step (gpointer data) { sw_view * view = (sw_view *)data; view_zoom_out (view, DEFAULT_ZOOM); return TRUE; } void zoom_out_cb (GtkWidget * widget, gpointer data) { sw_view * view = (sw_view *)data; view_zoom_out (view, DEFAULT_ZOOM); } void zoom_in_pressed_cb (GtkWidget * widget, gpointer data) { sw_view * view = (sw_view *)data; view_zoom_in (view, DEFAULT_ZOOM); view_init_repeater (view, (GtkFunction)zoom_in_step, data); } void zoom_out_pressed_cb (GtkWidget * widget, gpointer data) { sw_view * view = (sw_view *)data; view_zoom_out (view, DEFAULT_ZOOM); view_init_repeater (view, (GtkFunction)zoom_out_step, data); } void zoom_to_sel_cb (GtkWidget * widget, gpointer data) { SampleDisplay * sd = SAMPLE_DISPLAY(data); sw_view * v = sd->view; view_zoom_to_sel (v); } void zoom_left_cb (GtkWidget * widget, gpointer data) { SampleDisplay * sd = SAMPLE_DISPLAY(data); sw_view * v = sd->view; view_zoom_left (v); } void zoom_right_cb (GtkWidget * widget, gpointer data) { SampleDisplay * sd = SAMPLE_DISPLAY(data); sw_view * v = sd->view; view_zoom_right (v); } void zoom_all_cb (GtkWidget * widget, gpointer data) { sw_view * v = (sw_view *)data; view_zoom_all (v); } /* XXX: dump this ?? */ void zoom_2_1_cb (GtkWidget * widget, gpointer data) { SampleDisplay * sd = SAMPLE_DISPLAY(data); sw_sample * s; s = sd->view->sample; view_set_ends(sd->view, s->sounddata->nr_frames / 4, 3 * s->sounddata->nr_frames / 4); } void zoom_norm_cb (GtkWidget * widget, gpointer data) { SampleDisplay * sd = SAMPLE_DISPLAY(data); sw_view * view = sd->view; view_zoom_normal (view); } void zoom_1to1_cb (GtkWidget * widget, gpointer data) { SampleDisplay * sd = SAMPLE_DISPLAY(data); view_zoom_length (sd->view, sd->width); view_center_on (sd->view, sd->view->sample->user_offset); } void zoom_center_cb (GtkWidget * widget, gpointer data) { SampleDisplay * sd = SAMPLE_DISPLAY(data); view_center_on (sd->view, sd->view->sample->user_offset); } void zoom_combo_changed_cb (GtkWidget * widget, gpointer data) { sw_view * view = (sw_view *)data; gchar * text; sw_time_t zoom_time; sw_framecount_t zoom_length; text = (gchar *) gtk_entry_get_text (GTK_ENTRY(widget)); if (!strcmp (text, "All")) { view_zoom_all (view); } else { zoom_time = (sw_time_t)strtime_to_seconds (text); if (zoom_time != -1.0) { zoom_length = time_to_frames (view->sample->sounddata->format, zoom_time); view_zoom_length (view, zoom_length); /* Work around a bug, probably in gtkcombo, whereby all the other * widgets sometimes lost input after choosing a zoom */ gtk_widget_grab_focus (view->display); } } } /* Device config */ void device_config_cb (GtkWidget * widget, gpointer data) { device_config (); } /* Sample */ void sample_set_color_cb (GtkWidget * widget, gpointer data) { sw_view * view = (sw_view *) data; gint color; color = GPOINTER_TO_INT(g_object_get_data (G_OBJECT(widget), "default")); sample_set_color (view->sample, color); } /* Playback */ void follow_toggled_cb (GtkWidget * widget, gpointer data) { sw_view * view = (sw_view *) data; gboolean active; active = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(widget)); view_set_following (view, active); } void follow_toggle_cb (GtkWidget * widget, gpointer data) { sw_view * view = (sw_view *)data; view_set_following (view, !view->following); } void loop_toggled_cb (GtkWidget * widget, gpointer data) { sw_view * view = (sw_view *) data; gboolean active; active = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(widget)); sample_set_looping (view->sample, active); } void loop_toggle_cb (GtkWidget * widget, gpointer data) { sw_view * view = (sw_view *)data; sample_set_looping (view->sample, !view->sample->play_head->looping); } void playrev_toggled_cb (GtkWidget * widget, gpointer data) { sw_view * view = (sw_view *) data; gboolean active; active = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(widget)); sample_set_playrev (view->sample, active); } void playrev_toggle_cb (GtkWidget * widget, gpointer data) { sw_view * view = (sw_view *)data; sample_set_playrev (view->sample, !view->sample->play_head->reverse); } void mute_toggled_cb (GtkWidget * widget, gpointer data) { sw_view * view = (sw_view *) data; gboolean active; active = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(widget)); sample_set_mute (view->sample, active); } void mute_toggle_cb (GtkWidget * widget, gpointer data) { sw_view * view = (sw_view *)data; sample_set_mute (view->sample, !view->sample->play_head->mute); } void monitor_toggled_cb (GtkWidget * widget, gpointer data) { sw_view * view = (sw_view *) data; gboolean active; active = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(widget)); sample_set_monitor (view->sample, active); } void monitor_toggle_cb (GtkWidget * widget, gpointer data) { sw_view * view = (sw_view *)data; sample_set_monitor (view->sample, !view->sample->play_head->monitor); } void play_view_button_cb (GtkWidget * widget, gpointer data) { sw_view * view = (sw_view *) data; sw_head * head = view->sample->play_head; gboolean was_restricted = head->restricted; head_set_rate (head, 1.0); /* head_set_restricted (head, FALSE);*/ if (head->going && (head->scrubbing || !was_restricted)) { pause_playback_cb (widget, data); } else { play_view_all (view); } } void play_view_cb (GtkWidget * widget, gpointer data) { sw_view * view = (sw_view *) data; sw_head * head = view->sample->play_head; head_set_rate (head, 1.0); /* head_set_restricted (head, FALSE);*/ if (head->going) { pause_playback_cb (widget, data); } else { play_view_all (view); } } void play_view_sel_button_cb (GtkWidget * widget, gpointer data) { sw_view * view = (sw_view *) data; sw_head * head = view->sample->play_head; gboolean was_restricted = head->restricted; if (view->sample->sounddata->sels == NULL) { play_view_cb (widget, data); return; } head_set_rate (head, 1.0); /* head_set_restricted (head, TRUE);*/ if (head->going && (head->scrubbing || was_restricted)) { pause_playback_cb (widget, data); } else { play_view_sel (view); } } void play_view_sel_cb (GtkWidget * widget, gpointer data) { sw_view * view = (sw_view *) data; sw_head * head = view->sample->play_head; if (view->sample->sounddata->sels == NULL) { play_view_cb (widget, data); return; } head_set_rate (head, 1.0); /* head_set_restricted (head, TRUE);*/ if (head->going) { pause_playback_cb (widget, data); } else { play_view_sel (view); } } void pause_playback_cb (GtkWidget * widget, gpointer data) { sw_view * view = (sw_view *)data; pause_playback (view->sample); } void stop_playback_cb (GtkWidget * widget, gpointer data) { sw_view * view = (sw_view *)data; stop_playback (view->sample); } void preview_cut_cb (GtkWidget * widget, gpointer data) { sw_view * view = (sw_view *) data; sample_refresh_playmode (view->sample); if (view->sample->sounddata->sels != NULL) { play_preview_cut (view); } else { play_preroll (view); } } void preroll_cb (GtkWidget * widget, gpointer data) { sw_view * view = (sw_view *) data; sample_refresh_playmode (view->sample); play_preroll (view); } /* Record */ void show_rec_dialog_cb (GtkWidget * widget, gpointer data) { sw_view * view = (sw_view *)data; rec_dialog_create (view->sample); } /* Transport */ static gboolean rewind_step (gpointer data) { sw_sample * sample = (sw_sample *)data; gint step; step = sample->sounddata->format->rate; /* 1 second */ sample_set_playmarker (sample, sample->user_offset - step, TRUE); return TRUE; } static gboolean ffwd_step (gpointer data) { sw_sample * sample = (sw_sample *)data; gint step; step = sample->sounddata->format->rate; /* 1 second */ sample_set_playmarker (sample, sample->user_offset + step, TRUE); return TRUE; } void page_back_cb (GtkWidget * widget, gpointer data) { sw_view * view = (sw_view *)data; sw_sample * sample = view->sample; gint step; step = MIN(sample->sounddata->format->rate, (view->end - view->start)); sample_set_playmarker (sample, sample->user_offset - step, TRUE); } void page_fwd_cb (GtkWidget * widget, gpointer data) { sw_view * view = (sw_view *)data; sw_sample * sample = view->sample; gint step; step = MIN(sample->sounddata->format->rate, (view->end - view->start)); sample_set_playmarker (sample, sample->user_offset + step, TRUE); } void rewind_pressed_cb (GtkWidget * widget, gpointer data) { sw_view * view = (sw_view *)data; sw_sample * sample = view->sample; view_init_repeater (view, (GtkFunction)rewind_step, sample); } void ffwd_pressed_cb (GtkWidget * widget, gpointer data) { sw_view * view = (sw_view *)data; sw_sample * sample = view->sample; view_init_repeater (view, (GtkFunction)ffwd_step, sample); } void goto_start_cb (GtkWidget * widget, gpointer data) { sw_view * view = (sw_view *)data; sw_sample * sample = view->sample; sample_set_scrubbing (sample, FALSE); sample_set_playmarker (sample, 0, TRUE); } void goto_start_of_view_cb (GtkWidget * widget, gpointer data) { sw_view * view = (sw_view *)data; sw_sample * sample = view->sample; sample_set_scrubbing (sample, FALSE); sample_set_playmarker (sample, view->start, TRUE); } void goto_end_of_view_cb (GtkWidget * widget, gpointer data) { sw_view * view = (sw_view *)data; sw_sample * sample = view->sample; sample_set_scrubbing (sample, FALSE); sample_set_playmarker (sample, view->end, TRUE); } void goto_end_cb (GtkWidget * widget, gpointer data) { sw_view * view = (sw_view *)data; sw_sample * sample = view->sample; sample_set_scrubbing (sample, FALSE); sample_set_playmarker (sample, sample->sounddata->nr_frames, TRUE); } /* Interface elements: sample display, scrollbars etc. */ void sd_sel_changed_cb (GtkWidget * widget) { SampleDisplay * sd = SAMPLE_DISPLAY(widget); sample_refresh_views (sd->view->sample); } void sd_win_changed_cb (GtkWidget * widget) { SampleDisplay * sd = SAMPLE_DISPLAY(widget); sw_view * v = sd->view; g_signal_handlers_block_matched (GTK_OBJECT(v->adj), G_SIGNAL_MATCH_DATA, 0, 0, 0, 0, v); view_fix_adjustment (sd->view); g_signal_handlers_unblock_matched (GTK_OBJECT(v->adj), G_SIGNAL_MATCH_DATA, 0, 0, 0, 0, v); view_refresh_hruler (v); } void adj_changed_cb (GtkWidget * widget, gpointer data) { sw_view * v = (sw_view *)data; SampleDisplay * sd = SAMPLE_DISPLAY(v->display); GtkAdjustment * adj = GTK_ADJUSTMENT(v->adj); g_signal_handlers_block_matched (GTK_OBJECT(GTK_OBJECT(sd)), G_SIGNAL_MATCH_DATA, 0, 0, 0, 0, v); sample_display_set_window(sd, (gint)adj->value, (gint)(adj->value + adj->page_size)); g_signal_handlers_unblock_matched (GTK_OBJECT(GTK_OBJECT(sd)), G_SIGNAL_MATCH_DATA, 0, 0, 0, 0, v); view_refresh_hruler (v); } void adj_value_changed_cb (GtkWidget * widget, gpointer data) { sw_view * v = (sw_view *)data; SampleDisplay * sd = SAMPLE_DISPLAY(v->display); GtkAdjustment * adj = GTK_ADJUSTMENT(v->adj); if (!v->sample->play_head->going || !v->following) { g_signal_handlers_block_matched (GTK_OBJECT(GTK_OBJECT(sd)), G_SIGNAL_MATCH_DATA, 0, 0, 0, 0, v); sample_display_set_window(sd, (gint)adj->value, (gint)(adj->value + adj->page_size)); g_signal_handlers_unblock_matched (GTK_OBJECT(GTK_OBJECT(sd)), G_SIGNAL_MATCH_DATA, 0, 0, 0, 0, v); } if (v->following) { if (v->sample->user_offset < adj->value || v->sample->user_offset > adj->value + adj->page_size) sample_set_playmarker (v->sample, adj->value + adj->page_size/2, TRUE); } view_refresh_hruler (v); } /* Selection */ void select_invert_cb (GtkWidget * widget, gpointer data) { SampleDisplay * sd = SAMPLE_DISPLAY(data); sample_selection_invert (sd->view->sample); } void select_all_cb (GtkWidget * widget, gpointer data) { SampleDisplay * sd = SAMPLE_DISPLAY(data); sample_selection_select_all (sd->view->sample); } void select_none_cb (GtkWidget * widget, gpointer data) { SampleDisplay * sd = SAMPLE_DISPLAY(data); sample_selection_select_none (sd->view->sample); } void selection_halve_cb (GtkWidget * widget, gpointer data) { SampleDisplay * sd = SAMPLE_DISPLAY(data); sample_selection_halve (sd->view->sample); } void selection_double_cb (GtkWidget * widget, gpointer data) { SampleDisplay * sd = SAMPLE_DISPLAY(data); sample_selection_double (sd->view->sample); } void select_shift_left_cb (GtkWidget * widget, gpointer data) { SampleDisplay * sd = SAMPLE_DISPLAY(data); sample_selection_shift_left (sd->view->sample); } void select_shift_right_cb (GtkWidget * widget, gpointer data) { SampleDisplay * sd = SAMPLE_DISPLAY(data); sample_selection_shift_right (sd->view->sample); } /* Undo / Redo */ void show_undo_dialog_cb (GtkWidget * widget, gpointer data) { sw_view * view = (sw_view *)data; undo_dialog_create (view->sample); } void undo_cb (GtkWidget * widget, gpointer data) { sw_view * view = (sw_view *)data; undo_current (view->sample); } void redo_cb (GtkWidget * widget, gpointer data) { sw_view * view = (sw_view *)data; redo_current (view->sample); } void cancel_cb (GtkWidget * widget, gpointer data) { sw_view * view = (sw_view *)data; cancel_active_op (view->sample); } /* Edit */ void copy_cb (GtkWidget * widget, gpointer data) { sw_view * view = (sw_view *)data; sw_sample * s = view->sample; do_copy (s); } void cut_cb (GtkWidget * widget, gpointer data) { sw_view * view = (sw_view *)data; sw_sample * s = view->sample; do_cut (s); } void clear_cb (GtkWidget * widget, gpointer data) { sw_view * view = (sw_view *)data; sw_sample * s = view->sample; do_clear (s); } void delete_cb (GtkWidget * widget, gpointer data) { sw_view * view = (sw_view *)data; sw_sample * s = view->sample; do_delete (s); } void crop_cb (GtkWidget * widget, gpointer data) { sw_view * view = (sw_view *)data; sw_sample * s = view->sample; do_crop (s); } void paste_cb (GtkWidget * widget, gpointer data) { sw_view * view = (sw_view *)data; sw_sample * s = view->sample; do_paste_insert (s); } void paste_mix_cb (GtkWidget * widget, gpointer data) { sw_view * view = (sw_view *)data; sw_sample * s = view->sample; if (clipboard_width() > 0) { create_paste_mix_dialog (s); } else { sample_set_tmp_message (s, _("Clipboard empty")); } } void paste_xfade_cb (GtkWidget * widget, gpointer data) { sw_view * view = (sw_view *)data; sw_sample * s = view->sample; if (clipboard_width() > 0) { create_paste_xfade_dialog (s); } else { sample_set_tmp_message (s, _("Clipboard empty")); } } void paste_as_new_cb (GtkWidget * widget, gpointer data) { sw_sample * s; sw_view * v; s = do_paste_as_new (); if (s) { v = view_new_all (s, 1.0); sample_add_view (s, v); sample_bank_add (s); } } void show_info_dialog_cb (GtkWidget * widget, gpointer data) { sw_view * view = (sw_view *)data; sample_show_info_dialog (view->sample); } void hide_window_cb (GtkAccelGroup *accel_group, GObject *acceleratable, guint keyval, GdkModifierType modifier) { if (GTK_IS_WINDOW(acceleratable)) g_signal_emit_by_name(G_OBJECT(acceleratable), "hide"); } void close_window_cb (GtkAccelGroup *accel_group, GObject *acceleratable, guint keyval, GdkModifierType modifier) { if (GTK_IS_WINDOW(acceleratable)) g_signal_emit_by_name(G_OBJECT(acceleratable), "destroy"); } /* * Prime the label with the largest string then fetch the width. * now we can lock the width via gtk_widget_set_usize() to prevent * the wobble wobble caused by using a variable width font. * Just a hackish replacement for the belated gtk_label_set_width_chars() * don't try this at home kids, karma will get you. (oh well.. it works.) */ void hack_max_label_width_cb (GtkWidget *widget, GtkStyle *previous_style, gpointer user_data) { PangoRectangle logical_rect, ink_rect; const gchar *saved; if (!GTK_IS_LABEL(widget)) return; saved = strdup(gtk_label_get_text(GTK_LABEL(widget))); gtk_label_set_text(GTK_LABEL(widget), "00:00:00.0000"); pango_layout_get_extents (gtk_label_get_layout (GTK_LABEL(widget)), &ink_rect, &logical_rect); gtk_label_set_text(GTK_LABEL(widget), saved); if(saved != NULL) g_free((gpointer)saved); gtk_widget_set_usize(GTK_WIDGET(widget), PANGO_PIXELS (ink_rect.width), -1); } void hack_max_combo_width_cb (GtkWidget *widget, GtkStyle *previous_style, gpointer user_data) { PangoRectangle logical_rect, ink_rect; GtkWidget *tmp_entry; if (!GTK_IS_ENTRY(widget)) return; tmp_entry = gtk_entry_new(); gtk_widget_set_style(tmp_entry, gtk_style_copy(widget->style)); gtk_entry_set_text(GTK_ENTRY(tmp_entry), "00:00:00.0000."); pango_layout_get_extents (gtk_entry_get_layout (GTK_ENTRY(tmp_entry)), &ink_rect, &logical_rect); gtk_widget_destroy(tmp_entry); gtk_widget_set_usize(GTK_WIDGET(GTK_ENTRY(widget)), PANGO_PIXELS (ink_rect.width), -1); } #if GTK_CHECK_VERSION (2, 10, 0) void recent_chooser_menu_activated_cb(GtkRecentChooser *chooser, gpointer user_data) { gchar *uri = NULL; gchar *path = NULL; uri = gtk_recent_chooser_get_current_uri(chooser); path = g_filename_from_uri(uri, NULL, NULL); sample_load(path); g_free (path); } #endif