uif_sfgen.c
字号:
/*================================================================== * uif_sfgen.c - User interface sound font generator routines * * Smurf Sound Font Editor * Copyright (C) 1999-2001 Josh Green * * 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 or point your web browser to http://www.gnu.org. * * To contact the author of this program: * Email: Josh Green <jgreen@users.sourceforge.net> * Smurf homepage: http://smurf.sourceforge.net *==================================================================*/#include <stdio.h>#include <gtk/gtk.h>#include "uiface.h"#include "uif_sfgen.h"#include "uif_sfont.h"#include "uif_sftree.h"#include "uif_menutbar.h"#include "uif_samview.h"#include "widgets/samview.h"#include "wavetable.h"#include "sfont.h"#include "util.h"#include "i18n.h"typedef struct _GenCtrl{ guint16 genid; GtkWidget *scale; GtkWidget *entry; GtkWidget *units;}GenCtrl;enum{ CLIST_PITCH, CLIST_EFFECTS, CLIST_MODENV, CLIST_VOLENV, CLIST_MODLFO, CLIST_VIBLFO, CLIST_LAST};static void sfgen_set_ctrl_mode (gint mode);static void sfgen_ctrl_update (SFGenAmount * garr);static void sfgen_cb_gen_value_change (GtkAdjustment * adj, gint ctrlndx);static void sfgen_cb_gen_entry_activate (GtkWidget * entry, gint ctrlndx);static void sfgen_cb_gen_entry_focus_out (GtkWidget * entry, GdkEventFocus * event, gint ctrlndx);static GtkWidget *create_gen_control (guint16 genid);static void sfgen_set_view_mode (gint mode);static void sfgen_view_update (SFGenAmount * garr);static void sfgen_cb_gen_clist_button_pressed (GtkWidget * btn, gint page);static GtkWidget *create_gen_clist (gchar * title, gint page);static void add_gen_citem (guint16 genid, GtkWidget * list);static GtkWidget *sfgen_view_create (void);static gint sfgen_mode = GENMODE_INACTIVE; /* gen mode (INACTIVE/ABS/OFS) */static gint sfgen_actv_win; /* Active window SFGEN_VIEW/SFGEN_CTRL? */static GtkWidget *sfgen_ctrl; /* The generator control top level widget */static GtkWidget *sfgen_ctrl_notebook; /* notebook widget for ctrls */static GArray *sfgen_ctrl_array; /* Array of GenCtrls *//* prevent update of entries while updating gen controls */static gboolean sfgen_ctrl_noentry = FALSE;/* The generator view toplevel widget */static GtkWidget *sfgen_view;/* array of pointers to clist widgets */static GtkWidget *sfgen_clists[CLIST_LAST];/******** User interface functions ********//* sets the generator interface to one of inactive, absolute or offset */voidsfgen_set_mode (gint mode){ if (mode == sfgen_mode) return; /* mode change needed? */ sfgen_set_view_mode (mode); sfgen_set_ctrl_mode (mode); sfgen_mode = mode;}/* update gen view and ctrl windows with current gen values */voidsfgen_update (SFZone *zone){ SFGenAmount genarray[SFGen_Count]; if (sfgen_mode == GENMODE_INACTIVE) return; /* no updates when inactive */ if (sfgen_mode == GENMODE_ABS) gen_initdef (genarray); else gen_initofs (genarray); gen_process_zone (zone, genarray); sfgen_view_update (genarray); sfgen_ctrl_update (genarray);}static voidsfgen_set_ctrl_mode (gint mode){ /* set mode for gen ctrl */ GtkAdjustment *adj; gint i, x; GenCtrl *gctrl; sfgen_ctrl_noentry = TRUE; switch (mode) { case GENMODE_INACTIVE: for (i = 0; i < sfgen_ctrl_array->len; i++) { gctrl = &g_array_index (sfgen_ctrl_array, GenCtrl, i); gtk_entry_set_text (GTK_ENTRY (gctrl->entry), ""); /* clear unit labels */ gtk_label_set_text (GTK_LABEL (gctrl->units), ""); /* disable scales */ adj = gtk_range_get_adjustment (GTK_RANGE (gctrl->scale)); adj->value = 0.0; adj->lower = 0.0; adj->upper = 0.0; gtk_adjustment_changed (adj); gtk_adjustment_value_changed (adj); } break; case GENMODE_ABS: for (i = 0; i < sfgen_ctrl_array->len; i++) { gctrl = &g_array_index (sfgen_ctrl_array, GenCtrl, i); /* set unit labels to ABS (NOTE: genconv[].unittxt are constant strings so they must be translated here by gettext */ gtk_label_set_text (GTK_LABEL (gctrl->units), _(genconv[genparms[gctrl->genid].unit].unittxt)); adj = gtk_range_get_adjustment (GTK_RANGE (gctrl->scale)); adj->value = (gfloat) genparms[gctrl->genid].def; adj->lower = (gfloat) genparms[gctrl->genid].min; adj->upper = (gfloat) genparms[gctrl->genid].max; gtk_adjustment_changed (adj); gtk_adjustment_value_changed (adj); } break; case GENMODE_OFS: for (i = 0; i < sfgen_ctrl_array->len; i++) { gctrl = &g_array_index (sfgen_ctrl_array, GenCtrl, i); /* set unit labels to OFS, NOTE: genconv[].ofstxt are constant strings, so translate them via gettext */ gtk_label_set_text (GTK_LABEL (gctrl->units), _(genconv[genparms[gctrl->genid].unit].ofstxt)); x = genparms[gctrl->genid].max - genparms[gctrl->genid].min; adj = gtk_range_get_adjustment (GTK_RANGE (gctrl->scale)); adj->value = 0.0; adj->lower = (float) (-x); adj->upper = (float) x; gtk_adjustment_changed (adj); gtk_adjustment_value_changed (adj); } break; } sfgen_ctrl_noentry = FALSE;}static voidsfgen_ctrl_update (SFGenAmount * garr){ gint i; GenCtrl *gctrl; gchar vbuf[20]; gboolean absval; /* TRUE/FALSE = ABS/OFS gen mode */ absval = (sfgen_mode == GENMODE_ABS); sfgen_ctrl_noentry = TRUE; for (i = 0; i < sfgen_ctrl_array->len; i++) { gctrl = &g_array_index (sfgen_ctrl_array, GenCtrl, i); gtk_adjustment_set_value (gtk_range_get_adjustment (GTK_RANGE (gctrl-> scale)), (float) garr[gctrl->genid].sword); gen_sf2userstr (gctrl->genid, garr[gctrl->genid], vbuf, absval); gtk_entry_set_text (GTK_ENTRY (gctrl->entry), vbuf); } sfgen_ctrl_noentry = FALSE;}static voidsfgen_cb_gen_value_change (GtkAdjustment * adj, gint ctrlndx){ GenCtrl *gctrl; SFGenAmount amt; gchar vbuf[20]; gboolean absval; if (sfgen_ctrl_noentry || (sfgen_mode == GENMODE_INACTIVE) || !uisf_selected_zone) return; absval = (sfgen_mode == GENMODE_ABS); gctrl = &g_array_index (sfgen_ctrl_array, GenCtrl, ctrlndx); amt.sword = (gint16) (GTK_ADJUSTMENT (adj)->value); gen_sf2userstr (gctrl->genid, amt, vbuf, absval); gtk_entry_set_text (GTK_ENTRY (gctrl->entry), vbuf); /* notify wavetable of change */ if (uisf_selected_elem_type == NODE_PRESET) { wtbl_sfitem_changed (((SFPreset *)uisf_selected_elem)->itemid, WTBL_ITEM_CHANGE); } else { wtbl_sfitem_changed (((SFInst *)uisf_selected_elem)->itemid, WTBL_ITEM_CHANGE); } sfont_gen_set (uisf_selected_uisfont->sf, uisf_selected_zone, gctrl->genid, amt, (uisf_selected_elem_type == NODE_PRESET));}static voidsfgen_cb_gen_entry_activate (GtkWidget * entry, gint ctrlndx){ GenCtrl *gctrl; gchar *etxt; gboolean err; SFGenAmount amt; gchar vbuf[20]; gboolean absval; if (sfgen_mode == GENMODE_INACTIVE || !uisf_selected_zone) return; gctrl = &g_array_index (sfgen_ctrl_array, GenCtrl, ctrlndx); absval = (sfgen_mode == GENMODE_ABS); /* fetch the entry text and try to convert it to sfont units */ etxt = gtk_entry_get_text (GTK_ENTRY (entry)); amt.sword = gen_userstr2sf (gctrl->genid, etxt, absval, &err); /* if error occured with ascii to float conv, get current gen value */ if (err) amt.sword = (gint16) (GTK_ADJUSTMENT (gtk_range_get_adjustment (GTK_RANGE (gctrl-> scale)))->value); /* convert back to possibly corrected user units and place it in the entry */ gen_sf2userstr (gctrl->genid, amt, vbuf, absval); gtk_entry_set_text (GTK_ENTRY (gctrl->entry), vbuf); if (!err) { /* this only happens if the user is good */ /* notify wavetable of change */ if (uisf_selected_elem_type == NODE_PRESET) { wtbl_sfitem_changed (((SFPreset *)uisf_selected_elem)->itemid, WTBL_ITEM_CHANGE); } else { wtbl_sfitem_changed (((SFInst *)uisf_selected_elem)->itemid, WTBL_ITEM_CHANGE); } sfgen_ctrl_noentry = TRUE; gtk_adjustment_set_value (gtk_range_get_adjustment (GTK_RANGE (gctrl-> scale)), (float) amt.sword); sfgen_ctrl_noentry = FALSE; sfont_gen_set (uisf_selected_uisfont->sf, uisf_selected_zone, gctrl->genid, amt, (uisf_selected_elem_type == NODE_PRESET)); }}/* if the entry focus leaves, set entry text to current gen value */static voidsfgen_cb_gen_entry_focus_out (GtkWidget * entry, GdkEventFocus * event, gint ctrlndx){ GenCtrl *gctrl; SFGenAmount amt; gchar vbuf[20]; if (sfgen_mode == GENMODE_INACTIVE || !uisf_selected_zone) return; gctrl = &g_array_index (sfgen_ctrl_array, GenCtrl, ctrlndx); amt.sword = (gint16) (GTK_ADJUSTMENT (gtk_range_get_adjustment (GTK_RANGE (gctrl->scale)))->value); gen_sf2userstr (gctrl->genid, amt, vbuf, (sfgen_mode == GENMODE_ABS)); gtk_entry_set_text (GTK_ENTRY (gctrl->entry), vbuf);}static GtkWidget *create_gen_control (guint16 genid){ GenCtrl gctrl; gint ndx; GtkWidget *vbox, *hbox; GtkWidget *scale; GtkWidget *entry; GtkWidget *title; GtkObject *adj; gctrl.genid = genid; vbox = gtk_vbox_new (FALSE, 0); /* vbox for title,entry,units & scale */ gtk_widget_show (vbox); adj = gtk_adjustment_new (0.0, 0.0, 0.0, 1.0, 5.0, 0.0); gctrl.scale = scale = gtk_hscale_new (GTK_ADJUSTMENT (adj)); /* don't draw current scale value (we use an entry instead) */ gtk_scale_set_draw_value (GTK_SCALE (scale), FALSE); gtk_widget_show (scale); /* text entry for scale value */ gctrl.entry = entry = gtk_entry_new_with_max_length (10); gtk_widget_set_usize (entry, 60, 0); gtk_widget_show (entry); /* title label (NOTE: genparms[].label are constant strings, so they must be translated everytime they are used) */ title = gtk_label_new (_(genparms[genid].label)); gtk_widget_show (title); /* units label */ gctrl.units = gtk_label_new (""); gtk_widget_show (gctrl.units); hbox = gtk_hbox_new (FALSE, 0); /* hbox for title, entry and units */ gtk_widget_show (hbox); gtk_box_pack_start (GTK_BOX (vbox), hbox, TRUE, TRUE, 0); gtk_box_pack_start (GTK_BOX (hbox), title, FALSE, FALSE, 0); gtk_box_pack_end (GTK_BOX (hbox), entry, FALSE, FALSE, 0); gtk_box_pack_end (GTK_BOX (hbox), gctrl.units, FALSE, FALSE, 2); gtk_box_pack_start (GTK_BOX (vbox), scale, TRUE, TRUE, 2); g_array_append_val (sfgen_ctrl_array, gctrl); ndx = sfgen_ctrl_array->len - 1; /* hook adjustment value_changed signal */ gtk_signal_connect (adj, "value_changed", GTK_SIGNAL_FUNC (sfgen_cb_gen_value_change), GINT_TO_POINTER (ndx)); /* hook entry activate signal (when user presses enter on entry value) */ gtk_signal_connect (GTK_OBJECT (entry), "activate", GTK_SIGNAL_FUNC (sfgen_cb_gen_entry_activate), GINT_TO_POINTER (ndx)); gtk_signal_connect (GTK_OBJECT (entry), "focus-out-event", GTK_SIGNAL_FUNC (sfgen_cb_gen_entry_focus_out), GINT_TO_POINTER (ndx)); return (vbox);}GtkWidget *sfgen_ctrl_create (void){ GtkWidget *scroll_win; GtkWidget *notebook; GtkWidget *label; GtkWidget *ctrl; GtkWidget *frame; GtkWidget *box, *box1, *box2; sfgen_ctrl_array = g_array_new (FALSE, FALSE, sizeof (GenCtrl)); scroll_win = gtk_scrolled_window_new (NULL, NULL); gtk_container_border_width (GTK_CONTAINER (scroll_win), 0); gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll_win), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); gtk_widget_show (scroll_win); /* create notebook */ notebook = gtk_notebook_new (); gtk_widget_show (notebook); gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (scroll_win), notebook); /* create vbox for first page */ box = gtk_vbox_new (FALSE, 0); gtk_widget_show (box); /* Pitch frame */ frame = gtk_frame_new (_("Pitch")); gtk_widget_show (frame); gtk_box_pack_start (GTK_BOX (box), frame, TRUE, TRUE, 2); box1 = gtk_hbox_new (TRUE, 0); gtk_widget_show (box1); gtk_container_add (GTK_CONTAINER (frame), box1); ctrl = create_gen_control (Gen_CoarseTune); gtk_box_pack_start (GTK_BOX (box1), ctrl, TRUE, TRUE, 2); ctrl = create_gen_control (Gen_FineTune); gtk_box_pack_start (GTK_BOX (box1), ctrl, TRUE, TRUE, 2); ctrl = create_gen_control (Gen_ScaleTune); gtk_box_pack_start (GTK_BOX (box1), ctrl, TRUE, TRUE, 2); /* Filter frame */ frame = gtk_frame_new (_("Filter")); gtk_widget_show (frame); gtk_box_pack_start (GTK_BOX (box), frame, TRUE, TRUE, 2); box1 = gtk_hbox_new (TRUE, 0); gtk_widget_show (box1); gtk_container_add (GTK_CONTAINER (frame), box1); ctrl = create_gen_control (Gen_FilterQ); gtk_box_pack_start (GTK_BOX (box1), ctrl, TRUE, TRUE, 2); ctrl = create_gen_control (Gen_FilterFc); gtk_box_pack_start (GTK_BOX (box1), ctrl, TRUE, TRUE, 2); /* Effects frame */ frame = gtk_frame_new (_("Effects")); gtk_widget_show (frame); gtk_box_pack_start (GTK_BOX (box), frame, TRUE, TRUE, 2); box1 = gtk_hbox_new (TRUE, 0); gtk_widget_show (box1); gtk_container_add (GTK_CONTAINER (frame), box1); ctrl = create_gen_control (Gen_ReverbSend); gtk_box_pack_start (GTK_BOX (box1), ctrl, TRUE, TRUE, 2); ctrl = create_gen_control (Gen_ChorusSend); gtk_box_pack_start (GTK_BOX (box1), ctrl, TRUE, TRUE, 2); ctrl = create_gen_control (Gen_Pan); gtk_box_pack_start (GTK_BOX (box1), ctrl, TRUE, TRUE, 2); /* add the box to the notebook with label */ label = gtk_label_new (_("Pitch/Effects")); gtk_widget_show (label);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -