📄 uif_sftree.c
字号:
item->map.bank, item->map.psetnum, s2, item->src.bank, item->src.psetnum, s3, s4); g_free (s2); g_free (s3); node = sftree_insert_node (s, NULL, NULL, nodes->maproot, NULL); sftree_set_node_ref (node, NODE_VBNK_MAP, lmap, item->itemid); g_free (s); item->itemid = SFTREE_NODE_REF (node)->itemid; return (node);}GtkCTreeNode *sftree_add_vbank_map_sorted (GSList *lmap, VBnkNodes *nodes){ UIVBank *uivb; GtkCTreeNode *pos; GSList *p; uivb = SFTREE_SFNODE_UIVB (nodes->vbank); p = g_slist_next (lmap); if (p) pos = gtk_ctree_find_by_row_data_custom (sftree_widg, nodes->maproot, p, (GCompareFunc) sftree_sftreeref_data_compare); else p = NULL; return (sftree_add_vbank_map (lmap, pos, nodes));}voidsftree_remove_vbank (UIVBank *uivb){ gtk_ctree_remove_node (sftree_widg, uivb->nodes->vbank); g_free (uivb->nodes); uivb->nodes = NULL;}GtkWidget *sftree_create (void){ GtkWidget *sfont_win; if (!sftreeref_initchunk) { /* initialize reference chunk */ chunk_sftreeref = g_mem_chunk_create (SFTreeRef, SFTREEREF_CHUNK_OPTIMUM_AREA, G_ALLOC_AND_FREE); sftreeref_initchunk = TRUE; } /* create scrolled window to attach to */ sfont_win = gtk_scrolled_window_new (NULL, NULL); gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sfont_win), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); sftree_widg = GTK_CTREE (gtk_ctree_new (2, 1)); gtk_clist_set_selection_mode (GTK_CLIST (sftree_widg), GTK_SELECTION_EXTENDED); gtk_ctree_set_indent (sftree_widg, 10); gtk_ctree_set_spacing (sftree_widg, 4); /* set the width of the auxiliary pixmap column */ gtk_clist_set_column_width (GTK_CLIST (sftree_widg), 0, 12); /* remove this to cause all sorts of weired ctree shit!! */ gtk_clist_set_column_auto_resize (GTK_CLIST (sftree_widg), 1, TRUE); /* attach row selection routine */ gtk_signal_connect_after (GTK_OBJECT (sftree_widg), "tree-select-row", GTK_SIGNAL_FUNC (sftree_cb_select_row), NULL); /* for right click menus */ gtk_signal_connect (GTK_OBJECT (sftree_widg), "button-press-event", GTK_SIGNAL_FUNC (sftree_cb_button_press), NULL); gtk_widget_show (GTK_WIDGET (sftree_widg)); gtk_container_add (GTK_CONTAINER (sfont_win), GTK_WIDGET (sftree_widg)); gtk_widget_show (sfont_win); return (sfont_win);}/* updates label associated with the sound font root node */voidsftree_update_sfont_node_label (UISFont * uisf){ gchar *s; s = g_strdup_printf ("%s (%s)", sfont_get_info (uisf->sf, INAM_ID), uisf->sf->fname); sftree_set_tree_node_label (uisf->nodes->sfont, s); g_free (s);}voidsftree_update_vbank_node_label (UIVBank * uivb){ gchar *s; s = g_basename (uivb->vbnk->fname); /* Does not need to be freed */ s = g_strdup_printf (_("<VBANK> %s (%s)"), s, uivb->vbnk->fname); sftree_set_tree_node_label (uivb->nodes->vbank, s); g_free (s);}/* set the text of a ctree node */voidsftree_set_tree_node_label (GtkCTreeNode * node, gchar * text){ guint8 spacing; GdkPixmap *pixmap_closed, *pixmap_opened; GdkBitmap *mask_closed, *mask_opened; gboolean is_leaf, expanded; gtk_ctree_get_node_info (sftree_widg, node, NULL, &spacing, &pixmap_closed, &mask_closed, &pixmap_opened, &mask_opened, &is_leaf, &expanded); gtk_ctree_set_node_info (sftree_widg, node, text, spacing, pixmap_closed, mask_closed, pixmap_opened, mask_opened, is_leaf, expanded);}/* get sfont tree selection, returns GList of sfitem IDs */GList *sftree_get_selection (void){ GList *selection = NULL, *p; p = GTK_CLIST (sftree_widg)->selection; while (p) { selection = g_list_append (selection, GINT_TO_POINTER (SFTREE_NODE_REF (GTK_CTREE_NODE (p->data))-> itemid)); p = g_list_next (p); } return (selection);}SFItemIDsftree_get_selection_single (void){ SFItemID itemid; GtkCTreeNode *node; if (sftree_override_selection) { if (!sftree_override_list) return (SFITEMID_NONE); itemid = (SFItemID)(GPOINTER_TO_INT (sftree_override_list->data)); if (sftree_override_list->next || !(node = SFTREE_LOOKUP_ITEMID (itemid))) return (SFITEMID_NONE); return (itemid); } if (sftree_rclicked_itemid != SFITEMID_NONE) { if (!(node = SFTREE_LOOKUP_ITEMID (sftree_rclicked_itemid)) || (sftree_is_node_selected (node) && !SFTREE_SELECTION_IS_SINGLE ())) return (SFITEMID_NONE); return (sftree_rclicked_itemid); } if (SFTREE_SELECTION_IS_SINGLE ()) return (SFTREE_NODE_REF (GTK_CTREE_NODE (SFTREE_SELECTION ()->data)) ->itemid); return (SFITEMID_NONE);}GList *sftree_get_selection_multi (void){ GtkCTreeNode *node; GList *sel = NULL; if (sftree_override_selection) sel = g_list_copy (sftree_override_list); if (sftree_rclicked_itemid != SFITEMID_NONE && (node = SFTREE_LOOKUP_ITEMID (sftree_rclicked_itemid)) && !sftree_is_node_selected (node)) sel = g_list_append (sel, GINT_TO_POINTER (sftree_rclicked_itemid)); else sel = sftree_get_selection (); return (sel);}voidsftree_set_selection (GList *sel){ if (sftree_override_selection) sftree_unset_selection (); sftree_override_selection = TRUE; sftree_override_list = g_list_copy (sel);}voidsftree_set_selection_single (SFItemID itemid){ if (sftree_override_selection) sftree_unset_selection (); sftree_override_selection = TRUE; sftree_override_list = g_list_append (sftree_override_list, GINT_TO_POINTER (itemid));}voidsftree_unset_selection (void){ if (!sftree_override_selection) return; g_list_free (sftree_override_list); sftree_override_selection = FALSE;}gbooleansftree_is_node_selected (GtkCTreeNode *node){ return (g_list_find (SFTREE_SELECTION (), node) != NULL);}/* erase tree selection (unselect all items) */voidsftree_clear_selection (void){ GList *p, *copy; copy = g_list_copy (SFTREE_SELECTION ()); p = copy; while (p) { gtk_ctree_unselect (sftree_widg, GTK_CTREE_NODE (p->data)); p = g_list_next (p); } g_list_free (copy);}/* recurses up the tree from "node" looking for a node of type "type" (including node) */GtkCTreeNode *sftree_find_parent_by_type (GtkCTreeNode * node, SFNodeType type){ GtkCTreeNode *n; n = node; while (n && SFTREE_NODE_REF (n)->type != type) n = GTK_CTREE_ROW (n)->parent; return (n);}/* the same as the above function, except returns the found nodes dptr */void *sftree_find_parent_data_by_type (GtkCTreeNode * node, SFNodeType type){ GtkCTreeNode *n; n = sftree_find_parent_by_type (node, type); if (!n) return (NULL); else return (SFTREE_NODE_REF (n)->dptr);}/* find all nodes under 'under' whose ref->dptr matches dptr and ref->type matches type (dptr = NULL or type = NODE_UNKNOWN for wildcard)*/GList *sftree_find_nodes (gint type, gpointer dptr, GtkCTreeNode * under){ SFTreeRef ref; /* the matching criteria */ ref.type = type; ref.dptr = dptr; return (gtk_ctree_find_all_by_row_data_custom (sftree_widg, under, &ref, (GCompareFunc) sftree_find_nodes_compare));}/* comparison function for sftree_ref_list */static gintsftree_find_nodes_compare (SFTreeRef * node, SFTreeRef * match){ if ((match->type != NODE_NONE && match->type != node->type) || (match->dptr && match->dptr != node->dptr)) return (1); return (0);}/* recursively expand all nodes up the tree from node and move view to position node in the center of the view */voidsftree_spotlight_node (GtkCTreeNode * node){ GtkCTreeNode *n; n = GTK_CTREE_ROW (node)->parent; while (n) { /* expand up the tree */ gtk_ctree_expand (sftree_widg, n); n = GTK_CTREE_ROW (n)->parent; } gtk_ctree_select (sftree_widg, node); gtk_ctree_node_moveto (sftree_widg, node, 1, 0.5, 0.0);}static gbooleansftree_cb_button_press (GtkWidget * widg, GdkEventButton * event){ gint row, col; gint x, y; GtkCTreeNode *node; if (event->button == 3) { /* right-click? */ x = event->x; /* x and y coordinates are of type double */ y = event->y; /* convert to integer */ /* ?clicked on a valid ctree row? */ if (!gtk_clist_get_selection_info (GTK_CLIST (sftree_widg), x, y, &row, &col)) return (FALSE); /* ?: No, return */ /* fetch the ctree node that belongs to clicked row */ if (!(node = gtk_ctree_node_nth (sftree_widg, row))) return (FALSE); sftree_rclicked_itemid = SFTREE_NODE_REF (node)->itemid; /* stop button press event propagation */ gtk_signal_emit_stop_by_name (GTK_OBJECT (widg), "button-press-event"); sftree_set_highlight (node, GTK_STATE_PRELIGHT); treemenu_popup (event->button, event->time); return (FALSE); } return (TRUE);}voidsftree_set_highlight (GtkCTreeNode *node, GtkStateType state){ if (sftree_is_node_selected (node)) return; gtk_ctree_node_set_background(GTK_CTREE(sftree_widg), node, >K_WIDGET (sftree_widg)->style->bg[state]); gtk_ctree_node_set_foreground(GTK_CTREE(sftree_widg), node, >K_WIDGET (sftree_widg)->style->fg[state]);}voidsftree_unset_highlight (GtkCTreeNode *node){ if (sftree_is_node_selected (node)) return; gtk_ctree_node_set_background(GTK_CTREE(sftree_widg), node, NULL); gtk_ctree_node_set_foreground(GTK_CTREE(sftree_widg), node, NULL);}static gbooleansftree_cb_select_row (GtkWidget * widg, GtkCTreeNode * node, gint col){ SFTreeRef *ref; GSList *p; GList *p2; ref = SFTREE_NODE_REF (node); p = ref->dptr; /* if multiple items selected, deactivate tree selection interface */ p2 = GTK_CLIST (sftree_widg)->selection; if (p2 && g_list_next (p2)) { uisf_deactivate_selection (); return (TRUE); } /* notify sfont user interface of item selection */ uisf_sfitem_selected (node); return (TRUE);}static GtkCTreeNode *sftree_insert_node (gchar *label, gchar **closed_xpm, gchar **opened_xpm, GtkCTreeNode *parent, GtkCTreeNode *sibling){ gchar *text[2] = {NULL, label}; GtkCTreeNode *node = NULL; GdkPixmap *closed_pixmap = NULL, *opened_pixmap = NULL; GdkBitmap *closed_mask = NULL, *opened_mask = NULL; if (closed_xpm) pixmap_get (closed_xpm, &closed_pixmap, &closed_mask); if (!opened_xpm) /* opened XPM NOT specified? */ { opened_pixmap = closed_pixmap; /* use closed pixmap and mask */ opened_mask = closed_mask; } /* get opened pixmap/mask from XPM */ else pixmap_get (opened_xpm, &opened_pixmap, &opened_mask); node = gtk_ctree_insert_node (sftree_widg, parent, sibling, text, 2, closed_pixmap, closed_mask, opened_pixmap, opened_mask, FALSE, FALSE); return (node);}/* set pixmap of non-tree (auxiliary) column */voidsftree_set_aux_pixmap (GtkCTreeNode *node, gchar **xpm){ GdkPixmap *pixi; GdkBitmap *maski; /* sure.. Using NULL as the pixmap argument would seem like an obvious way to clear it, but nooooooooo... We set to NULL text instead to clear */ if (xpm != NULL) { pixmap_get (xpm, &pixi, &maski); gtk_ctree_node_set_pixmap (sftree_widg, node, 0, pixi, maski); } else gtk_ctree_node_set_text (sftree_widg, node, 0, NULL);}/* create a node reference structure for the given node, if "id" is SFITEMID_NONE then assign a item id, otherwise use the given id */static voidsftree_set_node_ref (GtkCTreeNode *node, gint type, gpointer data, SFItemID id){ SFTreeRef *ref; ref = g_chunk_new (SFTreeRef, chunk_sftreeref); ref->type = type; ref->dptr = data; if (id == SFITEMID_NONE) ref->itemid = sfont_next_itemid (); else ref->itemid = id; /* register the item ID and associate it with GtkCTreeNode *node */ sfont_register_itemid (ref->itemid, node); /* assign reference to the node and a callback to destroy the ref */ gtk_ctree_node_set_row_data_full (sftree_widg, node, ref, (GtkDestroyNotify) sftree_destroy_node_ref);}static voidsftree_destroy_node_ref (SFTreeRef *ref){ sfont_remove_itemid (ref->itemid); g_mem_chunk_free (chunk_sftreeref, ref);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -