📄 uif_pianospan.c
字号:
/*================================================================== * uif_pianospan.c - User interface piano and key/velocity span 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_pianospan.h"#include "uif_piano.h"#include "uif_sfont.h"#include "uif_sftree.h"#include "sfont.h"#include "widgets/piano.h"#include "widgets/keyspan.h"#include "widgets/ptrstrip.h"#include "wavetable.h"#include "smurfcfg.h"static void pianospan_cb_span_changed (KeySpan * keyspan, GSList * zone);static void pianospan_cb_span_state_changed (KeySpan * keyspan, GtkStateType state, GSList * p);static gint pianospan_find_zone_compare (SFTreeRef * nref, GSList * pzone);static void pianospan_cb_scrollbar_automatic (GtkAdjustment * adj, GtkWidget * scrollbar);static void pianospan_cb_piano_vel_range_hadj (GtkAdjustment * padj, GtkAdjustment * radj);static void pianospan_cb_ptrstrip_change (GtkWidget * ptrstrip, guint ptrndx);gint pianospan_mode = PIANOSPAN_PIANO;GtkWidget *pianospan_ptrstrip = NULL; /* root key pointer strip widget */GtkWidget *pianospan_velbar = NULL; /* velocity bar widget */GtkWidget *pianospan_velbar_box = NULL; /* velbar's box to keep left justified */GtkWidget *pianospan_view_box; /* the box widget for piano/velocity */GtkWidget *pianospan_keyrange_box; /* Key range box (to pack the spans into) */GPtrArray *pianospan_spans; /* Ptr array of active spans */guchar velbar_scolor[3] = { 0, 0, 0x40 }; /* velbar start color */guchar velbar_ecolor[3] = { 0, 0, 0xFF }; /* velbar end color *//* variables to disable entry into callbacks */static gboolean pianospan_no_entry = FALSE;static guchar *velbar_linebuf; /* buffer for one line of velocity bar */voidpianospan_set_mode (gint mode){ if (mode == pianospan_mode) return; pianospan_clear (); if (mode == PIANOSPAN_PIANO) { gtk_widget_ref (pianospan_velbar_box); gtk_container_remove (GTK_CONTAINER (pianospan_view_box), pianospan_velbar_box); gtk_box_pack_start (GTK_BOX (pianospan_view_box), uipiano_widg, FALSE, FALSE, 0); gtk_widget_unref (uipiano_widg); } else { gtk_widget_ref (uipiano_widg); gtk_container_remove (GTK_CONTAINER (pianospan_view_box), uipiano_widg); gtk_box_pack_start (GTK_BOX (pianospan_view_box), pianospan_velbar_box, FALSE, FALSE, 0); gtk_widget_unref (pianospan_velbar_box); } pianospan_mode = mode;}/* range of a span changed */static voidpianospan_cb_span_changed (KeySpan * keyspan, GSList * zone){ SFGenAmount amt; amt.range.lo = keyspan->lokey; amt.range.hi = keyspan->hikey; if (pianospan_mode == PIANOSPAN_PIANO) sfont_gen_set (uisf_selected_uisfont->sf, (SFZone *) (zone->data), Gen_KeyRange, amt, FALSE); else sfont_gen_set (uisf_selected_uisfont->sf, (SFZone *) (zone->data), Gen_VelRange, amt, FALSE); 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); }}/* active state of a span changed */static voidpianospan_cb_span_state_changed (KeySpan * keyspan, GtkStateType state, GSList * p){ GtkCTreeNode *node; KeySpan *span; gint i; /* 'state' callback parameter is probably the old state?? */ if (GTK_WIDGET_STATE (GTK_WIDGET (keyspan)) != GTK_STATE_SELECTED || pianospan_no_entry) return; /* locate the corresponding zone for this span and activate it */ if (uisf_selected_elem_type == NODE_PRESET) { node = gtk_ctree_find_by_row_data_custom (sftree_widg, uisf_selected_uisfont->nodes->preset, p, (GCompareFunc) pianospan_find_zone_compare); } else if (uisf_selected_elem_type == NODE_INST) { node = gtk_ctree_find_by_row_data_custom (sftree_widg, uisf_selected_uisfont->nodes->inst, p, (GCompareFunc) pianospan_find_zone_compare); } /* clear all other spans (except for this selected one) */ i = pianospan_spans->len; while (i--) { span = g_ptr_array_index (pianospan_spans, i); if (span != keyspan) gtk_widget_set_state (GTK_WIDGET (span), GTK_STATE_NORMAL); } if (node) { sftree_clear_selection (); gtk_ctree_select (sftree_widg, node); }}/* find a particular zone in the sound font tree */static gintpianospan_find_zone_compare (SFTreeRef * nref, GSList * pzone){ if ((nref->type == NODE_PZONE || nref->type == NODE_IZONE) && nref->dptr == pzone) return (0); return (1);}/* update key/velocity spans for active element */voidpianospan_update (void){ GSList *zone = NULL; GSList *p, *p2; SFGen *gen; GtkWidget *keyspan; gint8 lo, hi; pianospan_clear (); if (uisf_selected_elem_type == NODE_PRESET) zone = ((SFPreset *) uisf_selected_elem)->zone; else if (uisf_selected_elem_type == NODE_INST) zone = ((SFInst *) uisf_selected_elem)->zone; if (!zone) return; /* if there aren't any zones, return */ p = zone; if (!((SFZone *) (p->data))->instsamp) /* global zone? */ p = g_slist_next (p); /* yes: skip */ while (p) { lo = 0; /* default range is all keys */ hi = 127; if ((p2 = ((SFZone *) (p->data))->gen)) { /* if gen.count > 0 */ gen = (SFGen *) (p2->data); if (pianospan_mode == PIANOSPAN_PIANO) { /* piano mode? */ if (gen->id == Gen_KeyRange) { lo = gen->amount.range.lo; hi = gen->amount.range.hi; } } else { /* velocity mode */ if (gen->id == Gen_KeyRange) { /* only KeyRange preceeds VelRange */ p2 = g_slist_next (p2); /* advance to next gen */ if (p2) gen = (SFGen *) (p2->data); else gen = NULL; } if (gen && gen->id == Gen_VelRange) { /* gen is velocity range? */ lo = gen->amount.range.lo; hi = gen->amount.range.hi; } } } keyspan = keyspan_new (); keyspan_set_span (KEYSPAN (keyspan), lo, hi); if (pianospan_mode == PIANOSPAN_PIANO) keyspan_set_mode (KEYSPAN (keyspan), KEYSPAN_KEYMODE); else keyspan_set_mode (KEYSPAN (keyspan), KEYSPAN_VELMODE); gtk_signal_connect (GTK_OBJECT (keyspan), "span_change", GTK_SIGNAL_FUNC (pianospan_cb_span_changed), (gpointer) p); gtk_signal_connect (GTK_OBJECT (keyspan), "state-changed", GTK_SIGNAL_FUNC (pianospan_cb_span_state_changed), (gpointer) p); gtk_widget_show (GTK_WIDGET (keyspan)); gtk_box_pack_start (GTK_BOX (pianospan_keyrange_box), keyspan, FALSE, FALSE, 0); /* add keyspan ptr to keyspan ptr array */ g_ptr_array_add (pianospan_spans, (gpointer) keyspan); if (p->data == uisf_selected_zone) { /* this span is active? */ pianospan_no_entry = TRUE; /* ?: yes, set its state to active */ gtk_widget_set_state (GTK_WIDGET (keyspan), GTK_STATE_SELECTED); pianospan_no_entry = FALSE; } p = g_slist_next (p); }}voidpianospan_clear (void){ /* clear span window */ gint i; i = pianospan_spans->len; while (i--) { gtk_widget_destroy (GTK_WIDGET (g_ptr_array_index (pianospan_spans, 0))); g_ptr_array_remove_index_fast (pianospan_spans, 0); }}voidpianospan_select_span (gint spannum){ KeySpan *span; span = g_ptr_array_index (pianospan_spans, spannum); pianospan_no_entry = TRUE; gtk_widget_set_state (GTK_WIDGET (span), GTK_STATE_SELECTED); pianospan_no_entry = FALSE;}voidpianospan_clear_selection (void){ /* unselects all spans */ KeySpan *span; gint i; i = pianospan_spans->len; while (i--) { span = g_ptr_array_index (pianospan_spans, i); gtk_widget_set_state (GTK_WIDGET (span), GTK_STATE_NORMAL); }}voidpianospan_clear_rootkey_ptrstrip (void){ gtk_signal_handler_block_by_func (GTK_OBJECT (pianospan_ptrstrip), (GtkSignalFunc) pianospan_cb_ptrstrip_change, NULL);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -