/* * Copyright (C) 2004-2005 Vadim Berezniker * http://www.kryptolus.com * * 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, 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 GNU Make; see the file COPYING. If not, write to * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. * http://www.gnu.org/copyleft/gpl.html * */ #include "stdafx.h" #include "common.h" #include "gui_main_style.h" #include "gui_main_script.h" #include "sabbu.h" #include "sound.h" extern struct sabbu app; void gui_options_pref_advanced_waveform_ui_cb(gboolean val, gpointer data) { app.prefs->SetInt("AdvancedWaveformInterface", val); gui_main_advanced_waveform_ui_switch(val); } void gui_options_pref_text_editor_top_cb(gboolean val, gpointer data) { if(app.opts.text_editor_top != val) { GtkPaned *from, *to; app.opts.text_editor_top = val; if(!val) { from = app.ui.paned_notebook; to = app.ui.paned_list; } else { from = app.ui.paned_list; to = app.ui.paned_notebook; } int pos = gtk_paned_get_position(from); GtkWidget *widget = gtk_paned_get_child1(from); gtk_container_remove(GTK_CONTAINER(from), widget); gtk_paned_add1(to, GTK_WIDGET(app.ui.vbox_event_edit)); if(pos != 0) gtk_paned_set_position(to, pos); } app.prefs->SetInt("TextEditorTop", app.opts.text_editor_top); } void gui_options_pref_event_list_text_edit_cb(gboolean val, gpointer data) { app.prefs->SetInt("EventListTextEdit", val); g_object_set(app.ui.renderer_text, "editable", val, NULL); } void gui_options_pref_collision_cb(gboolean enable, gpointer data) { gboolean disable = !enable; if(disable != app.opts.disable_collisions) { app.opts.disable_collisions = disable; if(enable) app.script->EnableCollisions(); else app.script->DisableCollisions(); } app.prefs->SetInt("EnableCollisions", !app.opts.disable_collisions); } void gui_options_pref_show_only_first_cb(gboolean val, gpointer data) { app.opts.show_only_first_channel = val; app.prefs->SetInt("ShowOnlyFirstChannel", app.opts.show_only_first_channel); } void gui_options_pref_drag_selection_cb(gboolean val, gpointer data) { app.opts.enable_drag_selection = val; app.prefs->SetInt("DragSelection", app.opts.enable_drag_selection); kry_waveform_group_set_drag_selection(app.ui.waveform_group, val); } void gui_options_pref_allow_marker_dragging_cb(gboolean val, gpointer data) { app.opts.enable_marker_dragging = val; app.prefs->SetInt("EnableMarkerDragging", app.opts.enable_marker_dragging); kry_waveform_group_set_marker_dragging(app.ui.waveform_group, val); } void gui_options_pref_play_selection_stop_cb(gboolean val, gpointer data) { app.opts.play_selection_stop = val; app.prefs->SetInt("PlaySelectionStop", app.opts.play_selection_stop); } void gui_options_pref_logging_cb(gboolean val, gpointer data) { app.opts.enable_logging = val; app.prefs->SetInt("DebugLogging", app.opts.enable_logging); } void gui_options_pref_two_button_controls_cb(gboolean val, gpointer data) { app.opts.two_button_mode = val; if(val) { app.prefs->SetInt("TwoButtonMode", 1); gtk_widget_hide(GTK_WIDGET(app.ui.hbox_start_1)); gtk_widget_hide(GTK_WIDGET(app.ui.hbox_end_1)); } else { app.prefs->SetInt("TwoButtonMode", 0); gtk_widget_show(GTK_WIDGET(app.ui.hbox_start_1)); gtk_widget_show(GTK_WIDGET(app.ui.hbox_end_1)); } } void gui_options_pref_utf16_cb(gboolean val, gpointer data) { app.opts.save_utf16 = val; app.prefs->SetInt("SaveUTF16", val); } void gui_options_pref_join_2spaces_cb (gboolean val, gpointer data) { app.opts.join_2spaces = val; app.prefs->SetInt("Join2Spaces", app.opts.join_2spaces); } void gui_options_pref_format_script_cb(gboolean value, gpointer data) { app.opts.format_script = value; app.prefs->SetInt("FormatScript", app.opts.format_script); } void gui_options_pref_peak_files_cb(gboolean value, gpointer data) { app.opts.peak_files = value; app.prefs->SetInt("PeakFiles", value); } void gui_options_set_toolbar_location_custom(enum toolbar_pos pos_wave, enum toolbar_pos pos_list) { if(app.ui.toolbar_location == TOOLBAR_LEFT || app.ui.toolbar_location == TOOLBAR_RIGHT) { if((pos_wave != app.ui.toolbar_location || !app.ui.toolbar_wave) && app.ui.toolbar_wave) { gtk_container_remove(GTK_CONTAINER(app.ui.hbox_wave), GTK_WIDGET(app.ui.toolbar_wave)); app.ui.toolbar_wave = NULL; } if(pos_list != app.ui.toolbar_location && app.ui.toolbar_list) { gtk_container_remove(GTK_CONTAINER(app.ui.hbox_list), GTK_WIDGET(app.ui.toolbar_list)); app.ui.toolbar_list = NULL; } } else if(app.ui.toolbar_location == TOOLBAR_TOP || app.ui.toolbar_location == TOOLBAR_BOTTOM) { if((pos_wave != app.ui.toolbar_location || !app.ui.toolbar_wave) && app.ui.toolbar_wave) { gtk_container_remove(GTK_CONTAINER(app.ui.vbox_sub_wave), GTK_WIDGET(app.ui.toolbar_wave)); app.ui.toolbar_wave = NULL; } if(pos_list != app.ui.toolbar_location && app.ui.toolbar_list) { gtk_container_remove(GTK_CONTAINER(app.ui.vbox_sub_list), GTK_WIDGET(app.ui.toolbar_list)); app.ui.toolbar_list = NULL; } } if(pos_wave != TOOLBAR_NONE && app.opts.controls_as_toolbar && (pos_wave != app.ui.toolbar_location || !app.ui.toolbar_wave)) { if(pos_wave == TOOLBAR_LEFT || pos_wave == TOOLBAR_RIGHT) { app.ui.toolbar_wave = gui_main_create_control_toolbar(CONTROLS_VBOX); gtk_box_pack_start(GTK_BOX(app.ui.hbox_wave), GTK_WIDGET(app.ui.toolbar_wave), FALSE, TRUE, 0); if(pos_wave == TOOLBAR_RIGHT) gtk_box_reorder_child(GTK_BOX(app.ui.hbox_wave), GTK_WIDGET(app.ui.toolbar_wave), -1); else if(pos_wave == TOOLBAR_LEFT) gtk_box_reorder_child(GTK_BOX(app.ui.hbox_wave), GTK_WIDGET(app.ui.toolbar_wave), 0); gtk_widget_show_all(GTK_WIDGET(app.ui.toolbar_wave)); } else { app.ui.toolbar_wave = gui_main_create_control_toolbar(CONTROLS_HBOX); gtk_box_pack_start(GTK_BOX(app.ui.vbox_sub_wave), GTK_WIDGET(app.ui.toolbar_wave), FALSE, TRUE, 0); if(pos_wave == TOOLBAR_TOP) gtk_box_reorder_child(GTK_BOX(app.ui.vbox_sub_wave), GTK_WIDGET(app.ui.toolbar_wave), 0); else if(pos_wave == TOOLBAR_BOTTOM) gtk_box_reorder_child(GTK_BOX(app.ui.vbox_sub_wave), GTK_WIDGET(app.ui.toolbar_wave), -1); gtk_widget_show_all(GTK_WIDGET(app.ui.toolbar_wave)); } } if(pos_list != TOOLBAR_NONE && pos_list != app.ui.toolbar_location) { if(pos_list == TOOLBAR_LEFT || pos_list == TOOLBAR_RIGHT) { app.ui.toolbar_list = gui_main_create_list_toolbar(FALSE); gtk_box_pack_start(GTK_BOX(app.ui.hbox_list), GTK_WIDGET(app.ui.toolbar_list), FALSE, TRUE, 0); if(pos_list == TOOLBAR_RIGHT) gtk_box_reorder_child(GTK_BOX(app.ui.hbox_list), GTK_WIDGET(app.ui.toolbar_list), 1); else if(pos_list == TOOLBAR_LEFT) gtk_box_reorder_child(GTK_BOX(app.ui.hbox_list), GTK_WIDGET(app.ui.toolbar_list), 0); gtk_widget_show_all(GTK_WIDGET(app.ui.toolbar_list)); } else { app.ui.toolbar_list = gui_main_create_list_toolbar(TRUE); gtk_box_pack_start(GTK_BOX(app.ui.vbox_sub_list), GTK_WIDGET(app.ui.toolbar_list), FALSE, TRUE, 0); if(pos_list == TOOLBAR_TOP) gtk_box_reorder_child(GTK_BOX(app.ui.vbox_sub_list), GTK_WIDGET(app.ui.toolbar_list), 0); else if(pos_list == TOOLBAR_BOTTOM) gtk_box_reorder_child(GTK_BOX(app.ui.vbox_sub_list), GTK_WIDGET(app.ui.toolbar_list), -1); gtk_widget_show_all(GTK_WIDGET(app.ui.toolbar_list)); } } } void gui_options_set_toolbar_location(enum toolbar_pos pos) { if(app.ui.toolbar_location == pos) return; app.prefs->SetInt("ToolbarLocation", pos); gui_options_set_toolbar_location_custom(pos, pos); app.ui.toolbar_location = pos; } void gui_options_pref_audio_controls_as_toolbar_cb(gboolean val, gpointer data) { app.prefs->SetInt("AudioControlsToolbar", val); app.opts.controls_as_toolbar = val; enum toolbar_pos pos = (enum toolbar_pos) app.prefs->GetInt("ToolbarLocation", 0); if(val) { gui_options_set_toolbar_location_custom(pos, pos); gtk_widget_hide(GTK_WIDGET(app.ui.frame_controls)); } else { gui_options_set_toolbar_location_custom(TOOLBAR_NONE, pos); gtk_widget_show(GTK_WIDGET(app.ui.frame_controls)); } app.ui.toolbar_location = pos; } void gui_options_pref_toolbar_cb(GtkWidget *widget, enum toolbar_pos pos) { gui_options_set_toolbar_location(pos); } void gui_options_pref_default_zoom_cb(GtkWidget *widget, gpointer data) { app.prefs->SetInt("DefaultZoomMili", (int) (gtk_spin_button_get_value_as_float(GTK_SPIN_BUTTON(widget)) * 1000)); } void gui_options_pref_time_advance_cb(GtkWidget *widget, gpointer data) { app.prefs->SetInt("TimeAdvanceMili", (int) (gtk_spin_button_get_value_as_float(GTK_SPIN_BUTTON(widget)) * 1000)); app.opts.time_advance = (int) (gtk_spin_button_get_value_as_float(GTK_SPIN_BUTTON(widget)) * 1000); } void gui_options_pref_leadin_cb(GtkWidget *widget, gpointer data) { app.prefs->SetInt("LeadInMili", (int) (gtk_spin_button_get_value_as_float(GTK_SPIN_BUTTON(widget)))); app.opts.leadin = (int) (gtk_spin_button_get_value_as_float(GTK_SPIN_BUTTON(widget))); } void gui_options_pref_leadout_cb(GtkWidget *widget, gpointer data) { app.prefs->SetInt("LeadOutMili", (int) (gtk_spin_button_get_value_as_float(GTK_SPIN_BUTTON(widget)))); app.opts.leadout = (int) (gtk_spin_button_get_value_as_float(GTK_SPIN_BUTTON(widget))); } GtkTextView *gui_options_create_desc(char *text) { GtkTextView *view = GTK_TEXT_VIEW(gtk_text_view_new()); GtkTextBuffer *buffer = gtk_text_view_get_buffer(view); gtk_text_buffer_set_text(buffer, _(text), -1); gtk_text_view_set_wrap_mode(view, GTK_WRAP_WORD); gtk_text_view_set_editable(view, FALSE); gtk_widget_modify_base(GTK_WIDGET(view), GTK_STATE_NORMAL, &app.ui.color_bg); return view; } void gui_options_create_ui_system(GtkVBox *vbox) { #ifdef _WINDOWS // setup register associations GtkLabel *label_assoc = GTK_LABEL(gtk_label_new(_("Make Sabbu the default application for opening the following file formats:"))); GtkLabel *label_spacer = GTK_LABEL(gtk_label_new(NULL)); gtk_widget_set_size_request(GTK_WIDGET(label_spacer), 22, -1); GtkHBox *hbox_label = GTK_HBOX(gtk_hbox_new(FALSE, 0)); gtk_box_pack_start(GTK_BOX(hbox_label), GTK_WIDGET(label_spacer), FALSE, TRUE, 0); gtk_box_pack_start(GTK_BOX(hbox_label), GTK_WIDGET(label_assoc), FALSE, TRUE, 0); GtkVBox *vbox_assoc = GTK_VBOX(gtk_vbox_new(FALSE, 0)); GtkHBox *hbox_assoc = GTK_HBOX(gtk_hbox_new(FALSE, 0)); //GtkTextView *view = GTK_TEXT_VIEW(gtk_text_view_new()); //gtk_text_buffer_set_text(gtk_text_view_get_buffer(view), _(" Make Sabbu the default application for opening the following file formats: "), -1); //gtk_box_pack_start(GTK_BOX(hbox_assoc), GTK_WIDGET(view), FALSE, TRUE, 0); GtkButton *button_all = GTK_BUTTON(gtk_button_new_with_label(_("All"))); GtkButton *button_ssa = GTK_BUTTON(gtk_button_new_with_label(_(".ssa (Script)"))); GtkButton *button_ass = GTK_BUTTON(gtk_button_new_with_label(_(".ass (Script)"))); GtkButton *button_srt = GTK_BUTTON(gtk_button_new_with_label(_(".srt (Script)"))); GtkButton *button_sabbu = GTK_BUTTON(gtk_button_new_with_label(_(".sabbu (Workspace)"))); g_signal_connect(button_all, "clicked", G_CALLBACK(gui_main_register_extensions), (gpointer) 0); g_signal_connect(button_ssa, "clicked", G_CALLBACK(gui_main_register_extensions), (gpointer) 1); g_signal_connect(button_ass, "clicked", G_CALLBACK(gui_main_register_extensions), (gpointer) 2); g_signal_connect(button_sabbu, "clicked", G_CALLBACK(gui_main_register_extensions), (gpointer) 3); g_signal_connect(button_srt, "clicked", G_CALLBACK(gui_main_register_extensions), (gpointer) 4); label_spacer = GTK_LABEL(gtk_label_new(NULL)); gtk_widget_set_size_request(GTK_WIDGET(label_spacer), 22, -1); gtk_box_pack_start(GTK_BOX(hbox_assoc), GTK_WIDGET(label_spacer), FALSE, TRUE, 2); gtk_box_pack_start(GTK_BOX(hbox_assoc), GTK_WIDGET(button_all), FALSE, TRUE, 2); gtk_box_pack_start(GTK_BOX(hbox_assoc), GTK_WIDGET(button_ssa), FALSE, TRUE, 2); gtk_box_pack_start(GTK_BOX(hbox_assoc), GTK_WIDGET(button_ass), FALSE, TRUE, 2); gtk_box_pack_start(GTK_BOX(hbox_assoc), GTK_WIDGET(button_srt), FALSE, TRUE, 2); gtk_box_pack_start(GTK_BOX(hbox_assoc), GTK_WIDGET(button_sabbu), FALSE, TRUE, 2); gtk_box_pack_start(GTK_BOX(vbox_assoc), GTK_WIDGET(hbox_label), FALSE, TRUE, 4); gtk_box_pack_start(GTK_BOX(vbox_assoc), GTK_WIDGET(hbox_assoc), FALSE, TRUE, 4); gtk_box_pack_start(GTK_BOX(vbox), GTK_WIDGET(vbox_assoc), FALSE, TRUE, 0); gtk_widget_show_all(GTK_WIDGET(vbox)); #endif } void gui_options_create_ui_interface_general(GtkVBox *vbox) { GtkLabel *label_toolbar = GTK_LABEL(gtk_label_new(_("Toolbar Location: "))); GtkLabel *label_spacer = GTK_LABEL(gtk_label_new(NULL)); gtk_widget_set_size_request(GTK_WIDGET(label_spacer), 22, -1); GtkHBox *hbox_toolbar = GTK_HBOX(gtk_hbox_new(FALSE, 0)); int loc = app.ui.toolbar_location; GtkButton *button_left = GTK_BUTTON(gtk_radio_button_new_with_label(NULL, _("Left"))); GtkButton *button_top = GTK_BUTTON(gtk_radio_button_new_with_label(gtk_radio_button_get_group(GTK_RADIO_BUTTON(button_left)), _("Top"))); GtkButton *button_right = GTK_BUTTON(gtk_radio_button_new_with_label(gtk_radio_button_get_group(GTK_RADIO_BUTTON(button_left)), _("Right"))); GtkButton *button_bottom = GTK_BUTTON(gtk_radio_button_new_with_label(gtk_radio_button_get_group(GTK_RADIO_BUTTON(button_left)), _("Bottom"))); g_signal_connect(button_left, "toggled", G_CALLBACK(gui_options_pref_toolbar_cb), (gpointer) TOOLBAR_LEFT); g_signal_connect(button_top, "toggled", G_CALLBACK(gui_options_pref_toolbar_cb), (gpointer) TOOLBAR_TOP); g_signal_connect(button_right, "toggled", G_CALLBACK(gui_options_pref_toolbar_cb), (gpointer) TOOLBAR_RIGHT); g_signal_connect(button_bottom, "toggled", G_CALLBACK(gui_options_pref_toolbar_cb), (gpointer) TOOLBAR_BOTTOM); if(loc == TOOLBAR_LEFT) gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button_left), TRUE); else if(loc == TOOLBAR_TOP) gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button_top), TRUE); else if(loc == TOOLBAR_RIGHT) gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button_right), TRUE); else if(loc == TOOLBAR_BOTTOM) gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button_bottom), TRUE); gtk_box_pack_start(GTK_BOX(hbox_toolbar), GTK_WIDGET(label_spacer), FALSE, TRUE, 0); gtk_box_pack_start(GTK_BOX(hbox_toolbar), GTK_WIDGET(label_toolbar), FALSE, TRUE, 0); gtk_box_pack_start(GTK_BOX(hbox_toolbar), GTK_WIDGET(button_left), FALSE, TRUE, 2); gtk_box_pack_start(GTK_BOX(hbox_toolbar), GTK_WIDGET(button_top), FALSE, TRUE, 2); gtk_box_pack_start(GTK_BOX(hbox_toolbar), GTK_WIDGET(button_right), FALSE, TRUE, 2); gtk_box_pack_start(GTK_BOX(hbox_toolbar), GTK_WIDGET(button_bottom), FALSE, TRUE, 2); gtk_box_pack_start(GTK_BOX(vbox), GTK_WIDGET(hbox_toolbar), FALSE, TRUE, 0); } void gui_options_create_ui_interface_waveform(GtkVBox *vbox) { GtkTable *table = GTK_TABLE(gtk_table_new(7, 3, FALSE)); GtkHBox *hbox_toolbar_and_zoom = GTK_HBOX(gtk_hbox_new(FALSE, 0)); GtkLabel *label_spacer = GTK_LABEL(gtk_label_new(NULL)); gtk_widget_set_size_request(GTK_WIDGET(label_spacer), 22, -1); gtk_box_pack_start(GTK_BOX(hbox_toolbar_and_zoom), GTK_WIDGET(label_spacer), FALSE, TRUE, 0); // zoom { GtkLabel *label_zoom GTK_LABEL(gtk_label_new(_("Default Zoom: "))); GtkSpinButton *spin = GTK_SPIN_BUTTON(gtk_spin_button_new_with_range(1, 3600, 1)); gtk_spin_button_set_value(spin, app.prefs->GetInt("DefaultZoomMili", 3000) / 1000.0); gtk_spin_button_set_digits(spin, 2); g_signal_connect(spin, "value-changed", G_CALLBACK(gui_options_pref_default_zoom_cb), NULL); gtk_misc_set_alignment(GTK_MISC(label_zoom), 0.0, 0.5); gtk_table_attach(table, GTK_WIDGET(label_zoom), 0, 1, 0, 1, GTK_FILL, GTK_FILL, 0, 0); gtk_table_attach(table, GTK_WIDGET(spin), 1, 2, 0, 1, GTK_FILL, GTK_FILL, 0, 0); label_spacer = GTK_LABEL(gtk_label_new(NULL)); gtk_table_attach(table, GTK_WIDGET(label_spacer), 2, 3, 0, 1, (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), GTK_FILL, 0, 0); GtkHBox *hbox_view = GTK_HBOX(gtk_hbox_new(FALSE, 0)); GtkTextView *view = gui_options_create_desc("Number of seconds displayed per page on a newly opened waveform."); label_spacer = GTK_LABEL(gtk_label_new(NULL)); gtk_widget_set_size_request(GTK_WIDGET(label_spacer), 22, -1); gtk_box_pack_start(GTK_BOX(hbox_view), GTK_WIDGET(label_spacer), FALSE, TRUE, 0); gtk_box_pack_start(GTK_BOX(hbox_view), GTK_WIDGET(view), TRUE, TRUE, 0); gtk_table_attach_defaults(table, GTK_WIDGET(hbox_view), 0, 3, 1, 2); gtk_table_attach_defaults(table, GTK_WIDGET(gtk_label_new(NULL)), 0, 3, 2, 3); } gtk_box_pack_start(GTK_BOX(hbox_toolbar_and_zoom), GTK_WIDGET(table), TRUE, TRUE, 0); gtk_box_pack_start(GTK_BOX(vbox), GTK_WIDGET(hbox_toolbar_and_zoom), FALSE, TRUE, 0); } void gui_options_default_script_type_cb(GtkWidget *widget, gpointer data) { char *val = KRY_TS(gtk_combo_box_get_active_text(GTK_COMBO_BOX(widget))); app.prefs->SetString("DefaultScriptType", val); kry_free(val); } void gui_options_create_ui_option(GtkTable *table, int *row, char *text, char *description, GtkWidget *widget) { GtkLabel *label_spacer; GtkLabel *label = GTK_LABEL(gtk_label_new(text)); gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5); gtk_table_attach(table, GTK_WIDGET(label), 0, 1, *row, *row + 1, GTK_FILL, GTK_FILL, 0, 0); gtk_table_attach(table, GTK_WIDGET(widget), 1, 2, *row, *row + 1, GTK_FILL, GTK_FILL, 0, 0); label_spacer = GTK_LABEL(gtk_label_new(NULL)); gtk_table_attach(table, GTK_WIDGET(label_spacer), 2, 3, *row, *row + 1, (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), GTK_FILL, 0, 0); GtkHBox *hbox_description = GTK_HBOX(gtk_hbox_new(FALSE, 0)); GtkTextView *view = gui_options_create_desc(description); label_spacer = GTK_LABEL(gtk_label_new(NULL)); gtk_widget_set_size_request(GTK_WIDGET(label_spacer), 22, -1); gtk_box_pack_start(GTK_BOX(hbox_description), GTK_WIDGET(label_spacer), FALSE, TRUE, 0); gtk_box_pack_start(GTK_BOX(hbox_description), GTK_WIDGET(view), TRUE, TRUE, 0); gtk_table_attach_defaults(table, GTK_WIDGET(hbox_description), 0, 3, *row + 1, *row + 2); gtk_table_attach_defaults(table, GTK_WIDGET(gtk_label_new(NULL)), 0, 3, *row + 2, *row + 3); *row += 3; } void gui_options_create_ui_general(GtkVBox *vbox) { int row = 0; GtkTable *table = GTK_TABLE(gtk_table_new(7, 3, FALSE)); GtkHBox *hbox_spacer = GTK_HBOX(gtk_hbox_new(FALSE, 0)); GtkLabel *label_spacer = GTK_LABEL(gtk_label_new(NULL)); gtk_widget_set_size_request(GTK_WIDGET(label_spacer), 22, -1); gtk_box_pack_start(GTK_BOX(hbox_spacer), GTK_WIDGET(label_spacer), FALSE, TRUE, 0); // default script type { GtkComboBox *combo = GTK_COMBO_BOX(gtk_combo_box_new_text()); gtk_combo_box_append_text(combo, "SSA"); gtk_combo_box_append_text(combo, "ASS"); gtk_combo_box_append_text(combo, "SRT"); char *type = app.prefs->GetString("DefaultScriptType"); if(!type) type = "ASS"; gui_combo_box_set_text(combo, type); g_signal_connect(combo, "changed", G_CALLBACK(gui_options_default_script_type_cb), NULL); gui_options_create_ui_option(table, &row, _("Default Script Type: "), _("The default type for new scripts."), GTK_WIDGET(combo)); } // time advance { GtkSpinButton *spin = GTK_SPIN_BUTTON(gtk_spin_button_new_with_range(0, 10, 1)); g_signal_connect(spin, "value-changed", G_CALLBACK(gui_options_pref_time_advance_cb), NULL); gtk_spin_button_set_value(spin, app.prefs->GetInt("TimeAdvanceMili", 2000) / 1000.0); gtk_spin_button_set_digits(spin, 2); gui_options_create_ui_option(table, &row, _("Time Advance: "), _("Number of seconds the start/end times are advanced when grabbing times."), GTK_WIDGET(spin)); } // lead in { GtkSpinButton *spin = GTK_SPIN_BUTTON(gtk_spin_button_new_with_range(0, 1000, 10)); g_signal_connect(spin, "value-changed", G_CALLBACK(gui_options_pref_leadin_cb), NULL); gtk_spin_button_set_value(spin, app.prefs->GetInt("LeadInMili", 150)); gui_options_create_ui_option(table, &row, _("Lead In: "), _("Number of miliseconds the start marker is moved when the 'Add Lead-In' button is used."), GTK_WIDGET(spin)); } // lead out { GtkSpinButton *spin = GTK_SPIN_BUTTON(gtk_spin_button_new_with_range(0, 1000, 10)); g_signal_connect(spin, "value-changed", G_CALLBACK(gui_options_pref_leadout_cb), NULL); gtk_spin_button_set_value(spin, app.prefs->GetInt("LeadOutMili", 450)); gui_options_create_ui_option(table, &row, _("Lead Out: "), _("Number of miliseconds the end marker is moved when the 'Add Lead-Out' button is used."), GTK_WIDGET(spin)); } gtk_box_pack_start(GTK_BOX(hbox_spacer), GTK_WIDGET(table), TRUE, TRUE, 0); gtk_box_pack_start(GTK_BOX(vbox), GTK_WIDGET(hbox_spacer), FALSE, TRUE, 0); } struct option { char *name; char *descr; char *opt_name; int defval; void (*cb)(gboolean val, gpointer data); GtkCheckButton *button; }; struct option options_general[] = { { _("AutoSave"), _("Creates a backup copy of the opened script every " "5 minutes and places it in a 'SabbuAutoSave' directory in the same directory as the script. " "Up to 5 backup files are created. After that, new backup copies replace older backup copies. "), "AutoSave", 1, gui_main_menu_script_autosave }, { _("Create new scripts in Unicode (UTF16) encoding"), NULL, "SaveUTF16", 0, gui_options_pref_utf16_cb }, { NULL, NULL, NULL, 0, NULL } }; struct option options_events[] = { { _("Join Lines with 2 Spaces"), _("When using the join lines command this option adds two spaces, instead of one, at every point where lines join. " "The only exception is after a comma, where only one space is used."), "Join2Spaces", 1, gui_options_pref_join_2spaces_cb }, { _("Collision Detection [EXPERIMENTAL]"), _("Highlights lines that overlap with other lines."), "EnableCollisions", 0, gui_options_pref_collision_cb }, { _("Allow editing event text directly within the event list."), _("Allows editing event text directly within the event list by clicking on the event text in the text column."), "EventListTextEdit", 1, gui_options_pref_event_list_text_edit_cb }, { NULL, NULL, NULL, 0, NULL } }; struct option options_audio[] = { { _("Use Peak Files"), _("A peak file contains a summary of an audio file. When this option is on, opening the same audio file multiple times is significantly faster. " "The peak file is placed in the same directory as the wave file and has the same name except the extension is 'sabbu_pk'." ), "PeakFiles", 1, gui_options_pref_peak_files_cb }, { _("Using 'Play Selection' while sound is playing stops playback"), _("If sound is already playing, pressing 'Play Selection' will stop playback. "), "PlaySelectionStop", 0, gui_options_pref_play_selection_stop_cb }, { NULL, NULL, NULL, 0, NULL } }; struct option options_interface_general[] = { { _("Two Button Controls"), _("Displays only two buttons for moving the start and end markers instead of four. " "By holding down Control when clicking on the button, you can move the marker in increments of 10ms."), "TwoButtonMode", 0, gui_options_pref_two_button_controls_cb }, { _("Place Text Editor on Top"), _("Places the text editor above the waves in the 'classic' manner."), "TextEditorTop", 0, gui_options_pref_text_editor_top_cb }, { _("Show Audio Controls as a Separate Toolbar"), "Shows the audio controls as a separate toolbar instead of on the event editor panel", "AudioControlsToolbar", 0, gui_options_pref_audio_controls_as_toolbar_cb }, { NULL, NULL, NULL, 0, NULL } }; struct option options_interface_waveform[] = { { _("Enable Dragging Markers"), _("Allows the markers on the waveform to be dragged."), "EnableMarkerDragging", 1, gui_options_pref_allow_marker_dragging_cb }, { _("Wave Drag Selection"), _("Allows selecting an area of the wave by dragging from a start point to an end point. When this feature is disabled, dragging on the wave will place the respective marker at the mouse position."), "DragSelection", 1, gui_options_pref_drag_selection_cb }, { _("Only show the first channel when opening audio"), _("When an audio file is opened, all but the first channel will be hidden."), "ShowOnlyFirstChannel", 0, gui_options_pref_show_only_first_cb }, { _("Advanced Waveform Interface"), NULL, "AdvancedWaveformInterface", 0, gui_options_pref_advanced_waveform_ui_cb }, { NULL, NULL, NULL, 0, NULL } }; struct option options_scripts_ssa[] = { { _("Align Columns Inside Script"), _("Adds extra spaces between columns inside the script so that the data inside the columns lines up."), "FormatScript", 0, gui_options_pref_format_script_cb }, { NULL, NULL, NULL, 0, NULL } }; struct option options_misc[] = { { _("Logging"), _("Creates a file 'debug.log' which contains data which might assist the author with troubleshooting certain problems should they arise. "), "DebugLogging", 0, gui_options_pref_logging_cb }, { NULL, NULL, NULL, 0, NULL } }; enum option_list_entry_type { OPTION_NODE, OPTION_CHECKBOXES, OPTION_CUSTOMUI, OPTION_END }; struct option_list_entry { enum option_list_entry_type type; char *name; void *data; void (*custom_ui_func)(GtkVBox *vbox); }; struct option_list_entry options_list_entries_interface[] = { { OPTION_CUSTOMUI, _("General"), options_interface_general, gui_options_create_ui_interface_general }, { OPTION_CUSTOMUI, _("Waveform"), options_interface_waveform, gui_options_create_ui_interface_waveform }, { OPTION_END, NULL, NULL, NULL } }; struct option_list_entry options_list_entries_scripts[] = { { OPTION_CHECKBOXES, _("SSA/ASS"), options_scripts_ssa, NULL }, { OPTION_END, NULL, NULL, NULL } }; struct option_list_entry options_list_entries_main[] = { { OPTION_CUSTOMUI, _("General"), options_general, gui_options_create_ui_general }, { OPTION_NODE, _("Interface"), options_list_entries_interface, NULL }, { OPTION_CHECKBOXES, _("Events"), options_events, NULL }, { OPTION_CHECKBOXES, _("Audio"), options_audio, NULL }, { OPTION_NODE, _("Scripts"), options_list_entries_scripts, NULL }, { OPTION_CUSTOMUI, _("System"), NULL, gui_options_create_ui_system }, { OPTION_CHECKBOXES, _("Miscellaneous"), options_misc, NULL }, { OPTION_END, NULL, NULL, NULL } }; void gui_main_tab_options_toggle(GtkWidget *widget, struct option *option) { option->cb(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)), NULL); } enum { COLUMN_SECTION, COLUMN_PTR, COLUMN_COUNT }; void gui_options_fill_list_recur(GtkTreeStore *store, GtkTreeIter *parent, struct option_list_entry *entries) { for(int i = 0;; i++) { struct option_list_entry *entry = &entries[i]; if(entry->type == OPTION_END) { break; } GtkTreeIter iter; gtk_tree_store_append(store, &iter, parent); gtk_tree_store_set(store, &iter, COLUMN_SECTION, entry->name, COLUMN_PTR, entry, -1); if(entry->type == OPTION_NODE) { gui_options_fill_list_recur(store, &iter, (option_list_entry *) entry->data); continue; } } } void gui_options_selection_changed_cb(GtkTreeSelection *selection, GtkVBox *options_box) { GtkTreeModel *model; GList *rows = gtk_tree_selection_get_selected_rows(selection, &model); if(!rows) return; GtkTreePath *path = (GtkTreePath *) rows->data; GtkTreeIter iter; struct option_list_entry *entry; gtk_tree_model_get_iter(model, &iter, path); gtk_tree_model_get(model, &iter, COLUMN_PTR, &entry, -1); GList *children = gtk_container_get_children(GTK_CONTAINER(options_box)); for(GList *ptr = children; ptr; ptr = ptr->next) gtk_container_remove(GTK_CONTAINER(options_box), GTK_WIDGET(ptr->data)); if(entry->type == OPTION_NODE) { GtkLabel *label = GTK_LABEL(gtk_label_new(_("Please select a sub-category in the list on the left"))); gtk_box_pack_start(GTK_BOX(options_box), GTK_WIDGET(label), TRUE, TRUE, 0); } if(entry->type != OPTION_NODE && entry->data) { GtkVBox *vbox_page_options = GTK_VBOX(gtk_vbox_new(FALSE, 0)); struct option *options = (struct option *) entry->data; for(int i = 0; ; i++) { struct option *option = &options[i]; if(!option->name) break; GtkCheckButton *button = GTK_CHECK_BUTTON(gtk_check_button_new_with_label(option->name)); g_signal_connect(G_OBJECT(button), "toggled", G_CALLBACK(gui_main_tab_options_toggle), option); if(app.prefs->GetInt(option->opt_name, option->defval)) gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), TRUE); gtk_box_pack_start(GTK_BOX(vbox_page_options), GTK_WIDGET(button), FALSE, TRUE, 0); if(option->descr) { GtkHBox *hbox_view = GTK_HBOX(gtk_hbox_new(FALSE, 0)); GtkLabel *label_spacer = GTK_LABEL(gtk_label_new(NULL)); gtk_widget_set_size_request(GTK_WIDGET(label_spacer), 17, -1); gtk_box_pack_start(GTK_BOX(hbox_view), GTK_WIDGET(label_spacer), FALSE, TRUE, 0); GtkTextView *view = gui_options_create_desc(option->descr); gtk_box_pack_start(GTK_BOX(hbox_view), GTK_WIDGET(view), TRUE, TRUE, 5); gtk_box_pack_start(GTK_BOX(vbox_page_options), GTK_WIDGET(hbox_view), FALSE, TRUE, 0); } gtk_box_pack_start(GTK_BOX(vbox_page_options), gtk_label_new(NULL), FALSE, TRUE, 0); } GtkHBox *hbox_checkbox_options = GTK_HBOX(gtk_hbox_new(FALSE, 0)); GtkLabel *spacer = GTK_LABEL(gtk_label_new(NULL)); gtk_widget_set_size_request(GTK_WIDGET(spacer), 22, -1); gtk_box_pack_start(GTK_BOX(hbox_checkbox_options), GTK_WIDGET(spacer), FALSE, TRUE, 0); gtk_box_pack_start(GTK_BOX(hbox_checkbox_options), GTK_WIDGET(vbox_page_options), TRUE, TRUE, 0); gtk_box_pack_start(GTK_BOX(options_box), GTK_WIDGET(hbox_checkbox_options), FALSE, TRUE, 0); } if(entry->type == OPTION_CUSTOMUI && entry->custom_ui_func) entry->custom_ui_func(options_box); gtk_widget_show_all(GTK_WIDGET(options_box)); g_list_foreach(rows, (GFunc) (gtk_tree_path_free), NULL); g_list_free(rows); } gboolean gui_options_delete_cb(GtkWidget *widget, gpointer data) { gui_main_enable(); gui_main_focus(); return FALSE; } void gui_options_close_cb(GtkWidget *widget, GtkWidget *window) { gui_main_enable(); gui_main_focus(); gtk_widget_destroy(window); } void gui_options_show() { GtkWindow *window = GTK_WINDOW(gtk_window_new(GTK_WINDOW_TOPLEVEL)); GtkHBox *hbox_main = GTK_HBOX(gtk_hbox_new(FALSE, 0)); GtkFrame *frame_categories; GtkVBox *vbox_options_real; GtkVBox *vbox_options_main; // options { GtkFrame *notice = GTK_FRAME(gtk_frame_new(NULL)); vbox_options_main = GTK_VBOX(gtk_vbox_new(FALSE, 0)); vbox_options_real = GTK_VBOX(gtk_vbox_new(FALSE, 0)); gtk_container_set_border_width(GTK_CONTAINER(notice), 5); gtk_container_add(GTK_CONTAINER(notice), GTK_WIDGET(gtk_label_new(_("All changes take effect instantly")))); gtk_box_pack_start(GTK_BOX(vbox_options_main), GTK_WIDGET(notice), FALSE, TRUE, 0); gtk_box_pack_start(GTK_BOX(vbox_options_main), GTK_WIDGET(vbox_options_real), TRUE, TRUE, 0); } // section tree view { GtkTreeStore *store = gtk_tree_store_new(COLUMN_COUNT, G_TYPE_STRING, G_TYPE_POINTER); GtkCellRendererText *renderer = GTK_CELL_RENDERER_TEXT(gtk_cell_renderer_text_new()); GtkTreeViewColumn *column_section = gtk_tree_view_column_new_with_attributes("Section", GTK_CELL_RENDERER(renderer), "text", COLUMN_SECTION, NULL); GtkTreeSelection *selection; GtkTreeView *view; frame_categories = GTK_FRAME(gtk_frame_new(NULL)); view = GTK_TREE_VIEW(gtk_tree_view_new_with_model(GTK_TREE_MODEL(store))); gui_options_fill_list_recur(store, NULL, options_list_entries_main); gtk_tree_view_append_column(view, column_section); gtk_tree_view_set_headers_visible(view, FALSE); gtk_tree_view_expand_all(view); selection = gtk_tree_view_get_selection(view); g_signal_connect(G_OBJECT(selection), "changed", G_CALLBACK(gui_options_selection_changed_cb), vbox_options_real); gtk_tree_selection_set_mode(selection, GTK_SELECTION_BROWSE); gtk_container_add(GTK_CONTAINER(frame_categories), GTK_WIDGET(view)); } GtkHButtonBox *bbox = GTK_HBUTTON_BOX(gtk_hbutton_box_new()); GtkButton *button_close = GTK_BUTTON(gtk_button_new_from_stock("gtk-close")); GtkHBox *hbox_button = GTK_HBOX(gtk_hbox_new(FALSE, 0)); gtk_box_pack_start(GTK_BOX(bbox), GTK_WIDGET(button_close), FALSE, TRUE, 0); gtk_button_box_set_layout(GTK_BUTTON_BOX(bbox), GTK_BUTTONBOX_END); gtk_box_pack_start(GTK_BOX(hbox_button), GTK_WIDGET(bbox), TRUE, TRUE, 10); g_signal_connect(G_OBJECT(button_close), "clicked", G_CALLBACK(gui_options_close_cb), window); g_signal_connect(G_OBJECT(window), "delete-event", G_CALLBACK(gui_options_delete_cb), NULL); gtk_box_pack_start(GTK_BOX(vbox_options_main), GTK_WIDGET(hbox_button), FALSE, TRUE, 5); gtk_box_pack_start(GTK_BOX(hbox_main), GTK_WIDGET(frame_categories), FALSE, TRUE, 0); gtk_box_pack_start(GTK_BOX(hbox_main), GTK_WIDGET(vbox_options_main), TRUE, TRUE, 0); gtk_window_set_title(window, "Options"); gtk_container_add(GTK_CONTAINER(window), GTK_WIDGET(hbox_main)); gtk_window_set_transient_for(window, app.ui.window); gtk_window_set_position(window, GTK_WIN_POS_CENTER_ON_PARENT); gui_main_disable(); gtk_widget_set_size_request(GTK_WIDGET(window), 600, 550); gtk_widget_show_all(GTK_WIDGET(window)); } void gui_options_load_options(struct option *options) { for(int i = 0;;i++) { struct option *option = &options[i]; if(!option->name) break; if(app.prefs->GetInt(option->opt_name, option->defval)) option->cb(TRUE, NULL); else option->cb(FALSE, NULL); } } void gui_options_load_recur(struct option_list_entry *entries) { for(int i = 0;; i++) { struct option_list_entry *entry = &entries[i]; if(entry->type == OPTION_END) { break; } else if(entry->type == OPTION_NODE) { gui_options_load_recur((option_list_entry *) entry->data); continue; } if(entry->data) gui_options_load_options((struct option *) entry->data); } } void gui_options_load() { app.ui.toolbar_location = TOOLBAR_NONE; gui_options_load_recur(options_list_entries_main); int loc = app.prefs->GetInt("ToolbarLocation", 0); if(loc < 0 || loc > 3) loc = 0; gui_options_set_toolbar_location((enum toolbar_pos) loc); app.opts.default_zoom = (app.prefs->GetInt("DefaultZoomMili", 3000) / 1000.0); app.opts.time_advance = (app.prefs->GetInt("TimeAdvanceMili", 2000)); app.opts.leadin = (app.prefs->GetInt("LeadInMili", 150)); app.opts.leadout = (app.prefs->GetInt("LeadOutMili", 450)); }