/*================================================================== * SwamiUIGenView.c - User interface generator view object * * Swami * Copyright (C) 1999-2003 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 * Swami homepage: http://swami.sourceforge.net *==================================================================*/ #include #include #include #include "SwamiUIGenView.h" #include "SwamiUIObject.h" #include "util.h" #include "i18n.h" enum { CLIST_PITCH, CLIST_EFFECTS, CLIST_MODENV, CLIST_VOLENV, CLIST_MODLFO, CLIST_VIBLFO, CLIST_LAST }; static void swamiui_genview_class_init (SwamiUIGenViewClass *klass); static void swamiui_genview_init (SwamiUIGenView *genview); static void swamiui_genview_cb_zone_gen_change (SwamiObject *swami, IPZone *zone, SwamiUIGenView *genview); static void swamiui_genview_cb_show (GtkWidget *widg, gpointer data); static GtkWidget *create_gen_clist (gchar *title, gint page); static void add_gen_citem (guint16 genid, GtkWidget *list); static void sfgen_cb_gen_clist_button_pressed (GtkWidget * btn, gint page); gboolean colors_initialized = FALSE; static GdkColor set_clr = { red : 0, green : 48000, blue : 0 }; static GdkColor global_clr = { red : 65535, green : 0, blue : 0 }; guint8 view_gens[] = { IPGEN_COARSE_TUNE, IPGEN_FINE_TUNE, IPGEN_SCALE_TUNE, IPGEN_FILTER_Q, IPGEN_FILTER_FC, IPGEN_REVERB_SEND, IPGEN_CHORUS_SEND, IPGEN_PAN, IPGEN_VOL_ENV_DELAY, IPGEN_VOL_ENV_ATTACK, IPGEN_VOL_ENV_HOLD, IPGEN_VOL_ENV_DECAY, IPGEN_VOL_ENV_SUSTAIN, IPGEN_VOL_ENV_RELEASE, IPGEN_ATTENUATION, IPGEN_KEY_TO_VOL_ENV_HOLD, IPGEN_KEY_TO_VOL_ENV_DECAY, IPGEN_MOD_ENV_DELAY, IPGEN_MOD_ENV_ATTACK, IPGEN_MOD_ENV_HOLD, IPGEN_MOD_ENV_DECAY, IPGEN_MOD_ENV_SUSTAIN, IPGEN_MOD_ENV_RELEASE, IPGEN_MOD_ENV_TO_PITCH, IPGEN_MOD_ENV_TO_FILTER_FC, IPGEN_KEY_TO_MOD_ENV_HOLD, IPGEN_KEY_TO_MOD_ENV_DECAY, IPGEN_MOD_LFO_DELAY, IPGEN_MOD_LFO_FREQ, IPGEN_MOD_LFO_TO_PITCH, IPGEN_MOD_LFO_TO_FILTER_FC, IPGEN_MOD_LFO_TO_VOL, IPGEN_VIB_LFO_DELAY, IPGEN_VIB_LFO_FREQ, IPGEN_VIB_LFO_TO_PITCH }; #define VIEW_GENS_COUNT (sizeof (view_gens) / sizeof (guint8)) guint swamiui_genview_get_type (void) { static guint obj_type = 0; if (!obj_type) { GtkTypeInfo obj_info = { "SwamiUIGenView", sizeof (SwamiUIGenView), sizeof (SwamiUIGenViewClass), (GtkClassInitFunc) swamiui_genview_class_init, (GtkObjectInitFunc) swamiui_genview_init, (GtkArgSetFunc) NULL, (GtkArgGetFunc) NULL, }; obj_type = gtk_type_unique (gtk_scrolled_window_get_type (), &obj_info); } return obj_type; } static void swamiui_genview_class_init (SwamiUIGenViewClass *klass) { } static void swamiui_genview_init (SwamiUIGenView *genview) { GtkWidget *box, *box2; GtkWidget *list; gint8 *genp; int i; genview->zone = NULL; genview->queue_update = FALSE; gtk_scrolled_window_set_hadjustment (GTK_SCROLLED_WINDOW (genview), NULL); gtk_scrolled_window_set_vadjustment (GTK_SCROLLED_WINDOW (genview), NULL); gtk_container_border_width (GTK_CONTAINER (genview), 0); gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (genview), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); box = gtk_hbox_new (TRUE, 0); gtk_widget_show (GTK_WIDGET (box)); gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (genview), box); box2 = gtk_vbox_new (FALSE, 0); gtk_widget_show (GTK_WIDGET (box2)); genp = view_gens; genview->clists[CLIST_PITCH] = list = create_gen_clist (_("Pitch"), 0); for (i=0; i < 3; i++, genp++) add_gen_citem (*genp, list); gtk_box_pack_start (GTK_BOX (box2), list, TRUE, TRUE, 0); genview->clists[CLIST_EFFECTS] = list = create_gen_clist (_("Effects"), 0); for (i=0; i < 5; i++, genp++) add_gen_citem (*genp, list); gtk_box_pack_start (GTK_BOX (box2), list, TRUE, TRUE, 0); gtk_box_pack_start (GTK_BOX (box), box2, TRUE, TRUE, 0); genview->clists[CLIST_VOLENV] =list= create_gen_clist (_("Vol Envelope"), 1); for (i=0; i < 9; i++, genp++) add_gen_citem (*genp, list); gtk_box_pack_start (GTK_BOX (box), list, TRUE, TRUE, 0); genview->clists[CLIST_MODENV] =list= create_gen_clist (_("Mod Envelope"), 2); for (i=0; i < 10; i++, genp++) add_gen_citem (*genp, list); gtk_box_pack_start (GTK_BOX (box), list, TRUE, TRUE, 0); box2 = gtk_vbox_new (FALSE, 0); gtk_widget_show (GTK_WIDGET (box2)); genview->clists[CLIST_MODLFO] = list = create_gen_clist (_("Mod LFO"), 3); for (i=0; i < 5; i++, genp++) add_gen_citem (*genp, list); gtk_box_pack_start (GTK_BOX (box2), list, TRUE, TRUE, 0); genview->clists[CLIST_VIBLFO] =list= create_gen_clist (_("Vibrato LFO"), 3); for (i=0; i < 3; i++, genp++) add_gen_citem (*genp, list); gtk_box_pack_start (GTK_BOX (box2), list, TRUE, TRUE, 0); gtk_box_pack_start (GTK_BOX (box), box2, TRUE, TRUE, 0); g_signal_connect (swami_object, "zone_gen_change", (GCallback)swamiui_genview_cb_zone_gen_change, genview); gtk_signal_connect (GTK_OBJECT (genview), "show", swamiui_genview_cb_show, NULL); } static void swamiui_genview_cb_zone_gen_change (SwamiObject *swami, IPZone *zone, SwamiUIGenView *genview) { if (zone != genview->zone) return; if (GTK_WIDGET_VISIBLE (GTK_WIDGET (genview))) swamiui_genview_update (genview); else genview->queue_update = TRUE; } static void swamiui_genview_cb_show (GtkWidget *widg, gpointer data) { SwamiUIGenView *genview = SWAMIUI_GENVIEW (widg); if (genview->queue_update) { swamiui_genview_update (genview); genview->queue_update = FALSE; } } /** * Create a new generator view object * Returns: new widget of type SwamiUIGenView */ GtkWidget * swamiui_genview_new (void) { return (GTK_WIDGET (gtk_type_new (swamiui_genview_get_type ()))); } static GtkWidget * create_gen_clist (gchar *title, gint page) { GtkWidget *list; gchar *titles[3]; titles[0] = title; titles[1] = _("unit"); titles[2] = _("value"); list = gtk_clist_new_with_titles (3, titles); gtk_widget_show (GTK_WIDGET (list)); gtk_clist_set_column_width (GTK_CLIST (list), 0, (gint) (85)); gtk_clist_set_column_width (GTK_CLIST (list), 1, (gint) (40)); gtk_clist_set_column_width (GTK_CLIST (list), 2, (gint) (60)); gtk_clist_set_column_justification (GTK_CLIST (list), 1, GTK_JUSTIFY_CENTER); gtk_clist_set_column_justification (GTK_CLIST (list), 2, GTK_JUSTIFY_RIGHT); gtk_clist_set_selection_mode (GTK_CLIST (list), GTK_SELECTION_EXTENDED); gtk_clist_column_titles_passive (GTK_CLIST (list)); gtk_clist_column_title_active (GTK_CLIST (list), 0); gtk_signal_connect (GTK_OBJECT (GTK_CLIST (list)->column[0].button), "clicked", GTK_SIGNAL_FUNC (sfgen_cb_gen_clist_button_pressed), GINT_TO_POINTER (page)); return (list); } static void add_gen_citem (guint16 genid, GtkWidget *list) { gint row; gchar *data[] = { NULL, "--", "--" }; /* genparms[].label are constant strings, must be translated by gettext */ data[0] = _(instp_gen_info[genid].label); row = gtk_clist_append (GTK_CLIST (list), data); gtk_clist_set_row_data (GTK_CLIST (list), row, GINT_TO_POINTER ((gint) genid)); } /** * Set patch item to view generators of * @genview Generator View object * @item Patch item to sync to (only IPZone items used) or NULL to * de-activate view. Invalid item types are considered NULL. */ void swamiui_genview_set_item (SwamiUIGenView *genview, IPItem *item) { IPZone *zone = NULL; GtkWidget *list; static gchar blank[] = "--"; guint16 genid; gint i, i2; g_return_if_fail (genview != NULL); g_return_if_fail (SWAMIUI_IS_GENVIEW (genview)); if (!colors_initialized) /* FIXME: Is this proper color allocation? */ { GdkColormap *cmap; cmap = gdk_window_get_colormap (GTK_WIDGET (genview->clists[0])->window); gdk_colormap_alloc_color (cmap, &set_clr, FALSE, TRUE); gdk_colormap_alloc_color (cmap, &global_clr, FALSE, TRUE); colors_initialized = TRUE; } if (item && !INSTP_IS_ZONE (item)) item = NULL; if (item) zone = INSTP_ZONE (item); genview->zone = zone; if (zone) { IPItem *parent = instp_item_parent (INSTP_ITEM (zone)); g_assert (parent != NULL); for (i = 0; i < CLIST_LAST; i++) { list = genview->clists[i]; for (i2 = 0; i2 < GTK_CLIST (list)->rows; i2++) { genid = GPOINTER_TO_INT(gtk_clist_get_row_data (GTK_CLIST (list), i2)); /* translate and set unit label */ if (parent->type == IPITEM_INST) /* instrument zone? */ gtk_clist_set_text (GTK_CLIST (list), i2, 1, _(instp_gen_conv [instp_gen_info[genid].unit].unit_text)); else /* preset zone */ gtk_clist_set_text (GTK_CLIST (list), i2, 1, _(instp_gen_conv [instp_gen_info[genid].unit].ofs_text)); } } swamiui_genview_update (genview); } else /* zone is NULL, blank out labels */ for (i = 0; i < CLIST_LAST; i++) { list = genview->clists[i]; for (i2 = 0; i2 < GTK_CLIST (list)->rows; i2++) { gtk_clist_set_text (GTK_CLIST (list), i2, 1, blank); gtk_clist_set_text (GTK_CLIST (list), i2, 2, blank); /* reset cell style to use default widget style */ gtk_clist_set_cell_style (GTK_CLIST (list), i2, 2, NULL); } } } /** * Update entire generator view to sound font zone * @genview Generator view object to update */ void swamiui_genview_update (SwamiUIGenView *genview) { GtkWidget *list; IPItem *parent; IPZone *gzone; IPGenAmount amt; gboolean ispreset; gint i, i2, genid; gboolean set; GdkColor *fg; char *s; g_return_if_fail (genview != NULL); g_return_if_fail (SWAMIUI_IS_GENVIEW (genview)); if (!genview->zone) return; /* no update needed if inactive */ parent = instp_item_parent (INSTP_ITEM (genview->zone)); g_assert (parent != NULL); ispreset = (parent->type == IPITEM_PRESET); /* get global zone */ if (ispreset) gzone = instp_preset_first_zone (INSTP_PRESET (parent)); else gzone = instp_inst_first_zone (INSTP_INST (parent)); if (gzone && gzone->refitem) gzone = NULL; /* make sure is a global zone */ for (i = 0; i < CLIST_LAST; i++) { list = genview->clists[i]; gtk_clist_freeze (GTK_CLIST (list)); for (i2 = 0; i2 < GTK_CLIST (list)->rows; i2++) { GtkStyle *style = gtk_style_copy (gtk_widget_get_style (list)); genid = GPOINTER_TO_INT (gtk_clist_get_row_data (GTK_CLIST (list), i2)); set = instp_zone_get_gen (genview->zone, genid, &amt); /* set foreground depending on if gen is set, global or unset */ if (set) fg = &set_clr; else { IPGenAmount amt2; /* if there is a global zone and it is set for genid.. */ if (gzone && instp_zone_get_gen (gzone, genid, &amt2)) { fg = &global_clr; amt = amt2; } else fg = &list->style->fg[GTK_STATE_NORMAL]; } style->fg[GTK_STATE_NORMAL] = *fg; style->fg[GTK_STATE_PRELIGHT] = *fg; gtk_clist_set_cell_style (GTK_CLIST (list), i2, 2, style); gtk_style_unref (style); /* convert the generator value to user units */ instp_units_sfont_to_user_str (genid, amt, NULL, &s, ispreset); gtk_clist_set_text (GTK_CLIST (list), i2, 2, s); g_free (s); } gtk_clist_thaw (GTK_CLIST (list)); } } /** * swamiui_genview_get_genids: * @genids: Location to store a pointer to the genid array of all the * generators displayed in generator view objects. The array is used * internally and should not be messed with. * * Gets an array of genid values used in constructing #SwamiUIGenView * objects. * * Returns: Count of generator IDs in array */ int swamiui_genview_get_genids (guint8 **genids) { g_return_val_if_fail (genids != NULL, 0); *genids = view_gens; return (VIEW_GENS_COUNT); } static void sfgen_cb_gen_clist_button_pressed (GtkWidget * btn, gint page) { }