samview.c
来自「A GTK sound font editor. Sound font file」· C语言 代码 · 共 1,307 行 · 第 1/3 页
C
1,307 行
/*================================================================== * samview.c - sample view widget * * 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 <stdlib.h>#include <string.h>#include <gtk/gtkmain.h>#include <gtk/gtksignal.h>#include "samview.h"#define SAMVIEW_DEFAULT_SIZEX 100#define SAMVIEW_DEFAULT_SIZEY 40#define ZOOM_PRIORITY -1 /* priority of glib timeout (g_timeout_add_full) */#define ZOOM_SAFEZONE 2 /* # of pixels no-zoom on each side of zoom point *//* The following constants define the zoom curve, which consists of two slopes.One in the time domain (amount of time between each zoom update) and the otheris the amount of zoom per time interval, each slope is calculated using the #of pixels from the safe zoneupdate_time_interval_in_ms = ZOOM_TIME_SLOPE * x + ZOOM_TIME_OFSzoom_amount_per_time_interval = ZOOM_AMT_SLOPE * x + ZOOM_AMT_OFSwhere x is the # of pixels from the safe zone (i.e. further = faster updatesand more zoom per update, resulting in faster zoom) */#define ZOOM_TIME_OFS 160 /* longest zoom time, 1st pixel out of safezone */#define ZOOM_TIME_SLOPE -20.0 /* # of ms to add to OFS per pixel */#define ZOOM_TIME_MIN 40 /* minimum timout in milliseconds */#define ZOOM_AMT_OFS 1.0 /* initial amount of zoom per update = 1X */#define ZOOM_AMT_SLOPE -0.001 /* amt added to zoom amt per pixel */#define ZOOM_AMT_MIN 0.05 /* max zoom amount 1/AMT (multiplier) *//* scrolling during a selection uses these defines. The amount of pixels to scroll in view is kept in a variable, this variable is added to by the increase equation, which relies on the rate of movement of the mouse in the y axis. The decrease equation is related to time only, and is a steady linear decrease which works against the increase function. D = vertical distance of mouse cursor since last event T = time in milliseconds since last event scroll amount increase in pixels = SCROLL_SLOPE * D / T + SCROLL_OFS*/#define SCROLL_OFS 1.0 /* scroll amount increase offset */#define SCROLL_SLOPE 4.0 /* scroll amount increase multiplier */#define SCROLL_MAX 400.0 /* max scroll amount (in pixels) *//* scroll amount decrease in pixels = SCROLL_DSLOPE * T + SCROLL_DOFS */#define SCROLL_DOFS 0.0 /* scroll amount decrease offset */#define SCROLL_DSLOPE (-30.0/200.0) /* scroll amount decrease devisor */#define SCROLL_PRIORITY -1 /* priority of scroll timeout (g_timeout_add_full) */#define SCROLL_TINTERVAL 120 /* timer interval in milliseconds *//* converts x pixel position within view to sample position or -1 if outside sample */#define VIEW_X2SAMPOS(sampos, x, sv) G_STMT_START { \ sampos = (int)((float)x / (((GtkWidget *)sv)->allocation.width - 1) \ * (sv->size - 1)) + sv->start; \} G_STMT_END/* converts a sample position to view xpos or -1 if not in view */#define VIEW_SAM2XPOS(x, sampos, sv) G_STMT_START { \ x = (int)((float)(sampos - sv->start) / (sv->size - 1) \ * (((GtkWidget *)sv)->allocation.width - 1)); \} G_STMT_END/* compares two integers and swaps them if the second is less than the first */#define CMPSWAP(f, s) G_STMT_START { \ gint _temp; \ if (s < f) { \ _temp = f; \ f = s; \ s = _temp; \ } \} G_STMT_END/* Forward declarations */static void samview_class_init (SamViewClass * klass);static void samview_init (SamView * samview);static void samview_destroy (GtkObject * object);static void samview_size_request (GtkWidget * widget, GtkRequisition * requisition);static void samview_size_allocate (GtkWidget * widget, GtkAllocation * allocation);static void samview_realize (GtkWidget * widget);static gint samview_expose (GtkWidget * widget, GdkEventExpose * event);static void samview_adjustment_changed (GtkAdjustment * adj, SamView * samview);static void samview_adjustment_value_changed (GtkAdjustment * adj, SamView * samview);static void samview_redraw (SamView * samview);static void samview_draw (GtkWidget * widget);static gint samview_button_press (GtkWidget * widget, GdkEventButton * event);static gint samview_button_release (GtkWidget * widget, GdkEventButton * event);static gint samview_motion_notify (GtkWidget * widget, GdkEventMotion * event);static gboolean samview_scroll_timeout (gpointer data);static gboolean samview_zoom_timeout (gpointer data);/* data */static GtkWidgetClass *parent_class = NULL;enum{ VIEW_CHANGE, SELECTION_CHANGE, DUMMY_SIGNAL};static gint samview_signals[DUMMY_SIGNAL] = { 0 };/* functions */guintsamview_get_type (void){ static guint samview_type = 0; if (!samview_type) { GtkTypeInfo samview_info = { "SamView", sizeof (SamView), sizeof (SamViewClass), (GtkClassInitFunc) samview_class_init, (GtkObjectInitFunc) samview_init, (GtkArgSetFunc) NULL, (GtkArgGetFunc) NULL, }; samview_type = gtk_type_unique (gtk_widget_get_type (), &samview_info); } return samview_type;}static voidsamview_class_init (SamViewClass * klass){ GtkObjectClass *object_class; GtkWidgetClass *widget_class; object_class = (GtkObjectClass *) klass; widget_class = (GtkWidgetClass *) klass; parent_class = gtk_type_class (gtk_widget_get_type ()); samview_signals[VIEW_CHANGE] = gtk_signal_new ("view_change", GTK_RUN_FIRST, object_class->type, GTK_SIGNAL_OFFSET (SamViewClass, view_change), gtk_marshal_NONE__NONE, GTK_TYPE_NONE, 0); samview_signals[SELECTION_CHANGE] = gtk_signal_new ("selection_change", GTK_RUN_FIRST, object_class->type, GTK_SIGNAL_OFFSET (SamViewClass, selection_change), gtk_marshal_NONE__NONE, GTK_TYPE_NONE, 0); gtk_object_class_add_signals (object_class, samview_signals, DUMMY_SIGNAL); klass->view_change = NULL; klass->selection_change = NULL; object_class->destroy = samview_destroy; widget_class->size_request = samview_size_request; widget_class->size_allocate = samview_size_allocate; widget_class->realize = samview_realize; widget_class->expose_event = samview_expose; widget_class->button_press_event = samview_button_press; widget_class->button_release_event = samview_button_release; widget_class->motion_notify_event = samview_motion_notify;}static voidsamview_init (SamView * samview){ samview->samdata = NULL; samview->length = 0; samview->start = 0; samview->size = 0; samview->select_start = -1; samview->select_actvbegin = -1; samview->select_scroll = 0; samview->markers = NULL; samview->sel_marker = NULL; samview->adj = NULL; samview->zoom_btn = 0; samview->samview_pm = NULL; samview->freeze_count = 0; samview->bg_gc = NULL; samview->sam_gc = NULL; samview->cline_gc = NULL; samview->realpos_gc = NULL; samview->selmark_gc = NULL; samview->select_gc = NULL; samview->bg_clr.red = 0; samview->bg_clr.green = 0; samview->bg_clr.blue = 0; samview->sam_clr.red = 0; samview->sam_clr.green = 65535; samview->sam_clr.blue = 65535; samview->cline_clr.red = 65535; samview->cline_clr.green = 65535; samview->cline_clr.blue = 65535; samview->realpos_clr.red = 32768; samview->realpos_clr.green = 32768; samview->realpos_clr.blue = 32768; samview->selmark_clr.red = 65535; samview->selmark_clr.green = 65535; samview->selmark_clr.blue = 65535; samview->select_clr.red = 65535; samview->select_clr.green = 65535; samview->select_clr.blue = 65535;}GtkWidget *samview_new (void){ SamView *samview; samview = gtk_type_new (samview_get_type ()); samview->adj = (GtkAdjustment *) gtk_adjustment_new (0.0, 0.0, 0.0, 0.0, 0.0, 0.0); gtk_object_ref (GTK_OBJECT (samview->adj)); gtk_signal_connect (GTK_OBJECT (samview->adj), "changed", (GtkSignalFunc) samview_adjustment_changed, samview); gtk_signal_connect (GTK_OBJECT (samview->adj), "value_changed", (GtkSignalFunc) samview_adjustment_value_changed, samview); return GTK_WIDGET (samview);}voidsamview_freeze (SamView * samview){ g_return_if_fail (samview != NULL); g_return_if_fail (IS_SAMVIEW (samview)); samview->freeze_count++;}voidsamview_thaw (SamView * samview){ g_return_if_fail (samview != NULL); g_return_if_fail (IS_SAMVIEW (samview)); g_return_if_fail (samview->freeze_count > 0); samview->freeze_count--;}voidsamview_set_data (SamView * samview, gint16 * data, gint length){ gint w; g_return_if_fail (samview != NULL); g_return_if_fail (IS_SAMVIEW (samview)); samview->samdata = data; samview->length = length; samview->select_start = -1; samview->select_end = -1; w = GTK_WIDGET (samview)->allocation.width; if (length > w) w = length; samview->adj->lower = 0.0; samview->adj->upper = (float) (w); samview->adj->value = 0.0; samview->adj->step_increment = (float) w / 30.0; samview->adj->page_increment = (float) w / 10.0; samview->adj->page_size = (float) w; gtk_adjustment_changed (samview->adj); gtk_adjustment_value_changed (samview->adj); gtk_signal_emit (GTK_OBJECT (samview), samview_signals[VIEW_CHANGE]);}voidsamview_set_view (SamView * samview, gint start, gint size){ g_return_if_fail (samview != NULL); g_return_if_fail (IS_SAMVIEW (samview)); samview->adj->value = (float) start; samview->adj->step_increment = (float) size / 30.0; samview->adj->page_increment = (float) size / 10.0; samview->adj->page_size = (float) size; gtk_adjustment_changed (samview->adj); gtk_adjustment_value_changed (samview->adj); gtk_signal_emit (GTK_OBJECT (samview), samview_signals[VIEW_CHANGE]);}voidsamview_set_position (SamView * samview, gint start){ g_return_if_fail (samview != NULL); g_return_if_fail (IS_SAMVIEW (samview)); samview->adj->value = (float) start; gtk_adjustment_value_changed (samview->adj); gtk_signal_emit (GTK_OBJECT (samview), samview_signals[VIEW_CHANGE]);}/* calculates the sample offset given an x pixel position */gintsamview_calc_sample_pos (SamView * samview, gint xpos){ gint pos; g_return_val_if_fail (samview != NULL, -1); g_return_val_if_fail (IS_SAMVIEW (samview), -1); VIEW_X2SAMPOS (pos, xpos, samview); return (CLAMP (pos, 0, samview->length - 1));}gintsamview_calc_xpos (SamView * samview, gint pos){ gint xpos; g_return_val_if_fail (samview != NULL, -1); g_return_val_if_fail (IS_SAMVIEW (samview), -1); if (samview->size <= 1 || pos < 0) return (-1); VIEW_SAM2XPOS (xpos, pos, samview); if (xpos < 0 || xpos > ((GtkWidget *) samview)->allocation.width - 1) return (-1); return (xpos);}voidsamview_new_marker (SamView * samview, GdkColor * color){ GtkSVMark *marker; g_return_if_fail (samview != NULL); g_return_if_fail (IS_SAMVIEW (samview)); marker = g_new (GtkSVMark, 1); marker->pos = -1; marker->xpos = -1; memcpy (&marker->color, color, sizeof (GdkColor)); marker->gc = NULL; samview->markers = g_slist_append (samview->markers, marker);}voidsamview_set_marker (SamView * samview, guint marknum, gint loc){ GtkSVMark *marker; g_return_if_fail (samview != NULL); g_return_if_fail (IS_SAMVIEW (samview)); marker = g_slist_nth_data (samview->markers, marknum); if (!marker) return; marker->pos = loc; samview_redraw (samview);}GtkSVMark *samview_get_nth_mark (SamView * samview, guint marknum){ g_return_val_if_fail (samview != NULL, NULL); g_return_val_if_fail (IS_SAMVIEW (samview), NULL); return (g_slist_nth_data (samview->markers, marknum));}gintsamview_get_mark_index (SamView * samview, GtkSVMark * mark){ g_return_val_if_fail (samview != NULL, 0); g_return_val_if_fail (IS_SAMVIEW (samview), 0); return (g_slist_index (samview->markers, mark));}voidsamview_select_marker (SamView * samview, guint marknum){
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?