📄 uif_sftree.c
字号:
/*================================================================== * uif_sftree.c - GTK sound font tree 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 "uif_sftree.h"#include "uif_sfont.h"#include "uif_sfgen.h"#include "uif_treemenu.h"#include "uif_pianospan.h"#include "pixmap.h"#include "sfont.h"#include "vbank.h"#include "widgets/popdog.h"#include "i18n.h"#define SFTREEREF_CHUNK_OPTIMUM_AREA 256/*** Local Prototypes ***/static gint sftree_sftreeref_data_compare (SFTreeRef * ref, GSList * match);static gint sftree_find_nodes_compare (SFTreeRef * node, SFTreeRef * match);static gboolean sftree_cb_button_press (GtkWidget * widg, GdkEventButton * event);static gboolean sftree_cb_select_row (GtkWidget * widg, GtkCTreeNode * node, gint col);static GtkCTreeNode *sftree_insert_node (gchar *label, gchar **closed_xpm, gchar **opened_xpm, GtkCTreeNode *parent, GtkCTreeNode *sibling);static void sftree_set_node_ref (GtkCTreeNode * node, gint type, gpointer data, SFItemID id);static void sftree_destroy_node_ref (SFTreeRef * ref);/*** Global Data ***/static gboolean sftreeref_initchunk = FALSE;static GMemChunk *chunk_sftreeref = NULL;/* Sound font ctree widget and pointers to major sub nodes */GtkCTree *sftree_widg;/* current right clicked SFItemID node */SFItemID sftree_rclicked_itemid = 0;/* selection override (sftree_set_selection_*) */static gboolean sftree_override_selection = FALSE;static GList *sftree_override_list = NULL;/* add a sound font to the tree */GtkCTreeNode *sftree_add_sfont (UISFont * uisf){ GSList *p; SFData *sf; SFTreeNodes *sfnodes; gchar *s; sf = uisf->sf; sfnodes = g_malloc (sizeof (SFTreeNodes)); uisf->nodes = sfnodes; gtk_clist_freeze (GTK_CLIST (sftree_widg)); s = g_strdup_printf ("%s (%s)", sfont_get_info (sf, INAM_ID), sf->fname); sfnodes->sfont = sftree_insert_node (s, folder_xpm, folder_open_xpm, NULL, NULL); g_free (s); sftree_set_node_ref (sfnodes->sfont, NODE_SFONT, uisf, sf->itemid); /* store assigned item id into SFData structure */ sf->itemid = SFTREE_NODE_REF (sfnodes->sfont)->itemid; sfnodes->preset = sftree_insert_node(_("Presets"), folder_xpm, folder_open_xpm, sfnodes->sfont, NULL); sftree_set_node_ref (sfnodes->preset, NODE_PRESETROOT, sf->preset, SFITEMID_NONE); sfnodes->melodic = sftree_insert_node (_("Melodic"), folder_xpm, folder_open_xpm, sfnodes->preset, NULL); sftree_set_node_ref (sfnodes->melodic, NODE_MELODIC, sf->preset, SFITEMID_NONE); sfnodes->percuss = sftree_insert_node (_("Percussion"), folder_xpm, folder_open_xpm, sfnodes->preset, NULL); sftree_set_node_ref (sfnodes->percuss, NODE_PERCUSS, sf->preset, SFITEMID_NONE); sfnodes->inst = sftree_insert_node (_("Instruments"), folder_xpm, folder_open_xpm, sfnodes->sfont, NULL); sftree_set_node_ref (sfnodes->inst, NODE_INSTROOT, sf->inst, SFITEMID_NONE); sfnodes->sample = sftree_insert_node(_("Samples"), folder_xpm, folder_open_xpm, sfnodes->sfont, NULL); sftree_set_node_ref (sfnodes->sample, NODE_SAMPLEROOT, sf->sample, SFITEMID_NONE); sfnodes->loaded = sftree_insert_node (_("User"), folder_xpm, folder_open_xpm, sfnodes->sample, NULL); sftree_set_node_ref (sfnodes->loaded, NODE_USER, sf->sample, SFITEMID_NONE); sfnodes->rom = sftree_insert_node (_("ROM"), folder_xpm, folder_open_xpm, sfnodes->sample, NULL); sftree_set_node_ref (sfnodes->rom, NODE_ROM, sf->sample, SFITEMID_NONE); p = sf->preset; while (p) { sftree_add_preset (p, NULL, sfnodes); p = g_slist_next (p); } p = sf->inst; while (p) { sftree_add_inst (p, sfnodes, SFTREE_NODE_APPEND); p = g_slist_next (p); } p = sf->sample; while (p) { sftree_add_sample (p, sfnodes, SFTREE_NODE_APPEND); p = g_slist_next (p); } gtk_clist_thaw (GTK_CLIST (sftree_widg)); return (sfnodes->sfont);}/* remove a sound font from the tree */voidsftree_remove_sfont (UISFont * uisf){ gtk_ctree_remove_node (sftree_widg, uisf->nodes->sfont); g_free (uisf->nodes); uisf->nodes = NULL;}/* add a preset to tree just before the node specified by "pos" */GtkCTreeNode *sftree_add_preset (GSList * preset, GtkCTreeNode * pos, SFTreeNodes * sfnodes){ GtkCTreeNode *parent; GtkCTreeNode *node; SFPreset *pr; GSList *p; gchar *s; pr = (SFPreset *) (preset->data); if (pr->bank != 128) parent = sfnodes->melodic; else parent = sfnodes->percuss; s = g_strdup_printf ("%03d-%03d %s", pr->bank, pr->prenum, pr->name); node = sftree_insert_node (s, preset_xpm, NULL, parent, pos); g_free (s); sftree_set_node_ref (node, NODE_PRESET, preset, pr->itemid); /* store assigned item id into SFPreset structure */ pr->itemid = SFTREE_NODE_REF (node)->itemid; p = pr->zone; while (p) { sftree_add_pzone (p, node, SFTREE_NODE_APPEND); p = g_slist_next (p); } return (node);}/* add a preset sorted */GtkCTreeNode *sftree_add_preset_sorted (GSList * pnode, SFTreeNodes * sfnodes){ GtkCTreeNode *pos, *parent; GSList *p; SFPreset *preset; preset = (SFPreset *) (pnode->data); /* find position to insert into (ordered by bank - preset #) */ p = g_slist_next (pnode); if (preset->bank != 128) { parent = sfnodes->melodic; /* in case node is last non-percussion preset */ if (p && ((SFPreset *) (p->data))->bank == 128) p = NULL; } else parent = sfnodes->percuss; /* find the tree node */ if (p) pos = gtk_ctree_find_by_row_data_custom (sftree_widg, parent, p, (GCompareFunc) sftree_sftreeref_data_compare); else pos = NULL; return (sftree_add_preset (pnode, pos, sfnodes));}/* function returns 0 if ref->dptr matches match */static gintsftree_sftreeref_data_compare (SFTreeRef * ref, GSList * match){ return (ref->dptr != match);}/* add preset zone to tree */GtkCTreeNode *sftree_add_pzone (GSList * lzone, GtkCTreeNode * parent, gint pos){ SFZone *zone; GSList *p; GtkCTreeNode *node, *sibling; gchar *s; gchar **xpm = NULL; zone = (SFZone *) (lzone->data); if (!(p = zone->instsamp)) { s = _("Global Zone"); pos = 0; xpm = gzone_xpm; } else { s = ((SFInst *)(p->data))->name; xpm = inst_xpm; } if (pos >= 0) /* Position specified? */ { sibling = GTK_CTREE_ROW (parent)->children; while (sibling && pos > 0) /* Locate the node at pos */ { sibling = GTK_CTREE_ROW (sibling)->sibling; /* Next sibling */ pos--; } } else sibling = NULL; /* No, append to zones */ node = sftree_insert_node (s, xpm, NULL, parent, sibling); sftree_set_node_ref (node, NODE_PZONE, lzone, zone->itemid); /* store assigned item id into SFZone structure */ zone->itemid = SFTREE_NODE_REF (node)->itemid; return (node);}/* add instrument to tree */GtkCTreeNode *sftree_add_inst (GSList * linst, SFTreeNodes * sfnodes, gint pos){ SFInst *inst; GSList *p; GtkCTreeNode *node, *sibling; inst = (SFInst *) (linst->data); if (pos >= 0) /* Position specified? */ { sibling = GTK_CTREE_ROW (sfnodes->inst)->children; while (sibling && pos > 0) /* Locate the node at pos */ { sibling = GTK_CTREE_ROW (sibling)->sibling; /* Next sibling */ pos--; } } else sibling = NULL; /* ?: No, append to instruments */ node = sftree_insert_node (inst->name, inst_xpm, NULL, sfnodes->inst,sibling); sftree_set_node_ref (node, NODE_INST, linst, inst->itemid); /* store assigned item id into SFInst structure */ inst->itemid = SFTREE_NODE_REF (node)->itemid; p = inst->zone; while (p) { sftree_add_izone (p, node, SFTREE_NODE_APPEND); p = g_slist_next (p); } return (node);}/* add an instrument zone to the tree */GtkCTreeNode *sftree_add_izone (GSList * lzone, GtkCTreeNode * parent, gint pos){ SFZone *zone; GSList *p; GtkCTreeNode *node, *sibling; gchar *s; gchar **xpm = NULL; zone = (SFZone *) (lzone->data); if (!(p = zone->instsamp)) /* Global zone? */ { s = _("Global Zone"); pos = 0; /* Global zones are first in zone list */ xpm = gzone_xpm; } else { SFSample *sam = (SFSample *)(p->data); s = sam->name; if (!(sam->sampletype & SF_SAMPLETYPE_ROM)) xpm = sample_xpm; else xpm = rom_xpm; } if (pos >= 0) /* Position specified? */ { sibling = GTK_CTREE_ROW (parent)->children; while (sibling && pos > 0) /* Locate the node at pos */ { sibling = GTK_CTREE_ROW (sibling)->sibling; /* Next sibling */ pos--; } } else sibling = NULL; /* No, append to zones */ node = sftree_insert_node (s, xpm, NULL, parent, sibling); sftree_set_node_ref (node, NODE_IZONE, lzone, zone->itemid); /* store assigned item id into SFZone structure */ zone->itemid = SFTREE_NODE_REF (node)->itemid; return (node);}/* add a sample to the tree */GtkCTreeNode *sftree_add_sample (GSList * lsample, SFTreeNodes * sfnodes, gint pos){ GtkCTreeNode *parent; SFSample *sam; GtkCTreeNode *node, *sibling; gchar **xpm; sam = (SFSample *) (lsample->data); if (!(sam->sampletype & SF_SAMPLETYPE_ROM)) { parent = sfnodes->loaded; xpm = sample_xpm; } else { parent = sfnodes->rom; xpm = rom_xpm; } if (pos >= 0) /* Position specified? */ { sibling = GTK_CTREE_ROW (parent)->children; while (sibling && pos > 0) { sibling = GTK_CTREE_ROW (sibling)->sibling; pos--; } } else sibling = NULL; /* ?: No, append to samples */ node = sftree_insert_node (sam->name, xpm, NULL, parent, sibling); sftree_set_node_ref (node, NODE_SAMPLE, lsample, sam->itemid); /* store assigned item id into SFSample structure */ sam->itemid = SFTREE_NODE_REF (node)->itemid; return (node);}GtkCTreeNode *sftree_add_vbank (UIVBank * uivb){ VBnkData *vbnk; VBnkNodes *vbnodes; GSList *p; gchar *s, *s2; vbnk = uivb->vbnk; vbnodes = g_malloc (sizeof (VBnkNodes)); uivb->nodes = vbnodes; SFTREE_FREEZE (); s2 = g_basename (vbnk->fname); /* Does not need to be freed */ s = g_strdup_printf (_("<VBANK> %s (%s)"), s2, vbnk->fname); vbnodes->vbank = sftree_insert_node (s, NULL, NULL, NULL, NULL); sftree_set_node_ref (vbnodes->vbank, NODE_VBANK, uivb, SFITEMID_NONE); g_free (s); s2 = (vbnk->defname != NULL && *vbnk->defname != '\0') ? vbnk->defname : _("<none>"); s = g_strdup_printf (_("<DEFAULT> %s"), s2); vbnodes->defbank = sftree_insert_node (s, NULL, NULL, vbnodes->vbank, NULL); sftree_set_node_ref (vbnodes->defbank, NODE_VBNK_DEFBANK, NULL, SFITEMID_NONE); g_free (s); vbnodes->maproot = sftree_insert_node (_("Mappings"), NULL, NULL, vbnodes->vbank, NULL); sftree_set_node_ref (vbnodes->maproot, NODE_VBNK_MAPROOT, NULL,vbnk->itemid); vbnk->itemid = SFTREE_NODE_REF (vbnodes->maproot)->itemid; p = vbnk->items; while (p) { sftree_add_vbank_map (p, NULL, vbnodes); p = g_slist_next (p); } SFTREE_THAW (); return (vbnodes->vbank);}GtkCTreeNode *sftree_add_vbank_map (GSList *lmap, GtkCTreeNode *pos, VBnkNodes *nodes){ VBnkItem *item; GtkCTreeNode *node; gchar *s, *s2, *s3, *s4; item = (VBnkItem *)(lmap->data); s2 = (item->map.keynote != -1) ? g_strdup_printf ("(%03d)", item->map.keynote) : g_strdup (""); s3 = (item->src.keynote != -1) ? g_strdup_printf ("(%03d)", item->src.keynote) : g_strdup (""); if (item->sfname) s4 = item->sfname; else s4 = ""; s = g_strdup_printf ("%03d-%03d%s > %03d-%03d%s %s",
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -