⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 piano.c

📁 A GTK sound font editor. Sound font files are used to synthesize instruments from audio samples for
💻 C
📖 第 1 页 / 共 2 页
字号:
/*================================================================== * piano.c - piano 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 <gtk/gtkmain.h>#include <gtk/gtksignal.h>#include "piano.h"/* Forward declarations */static void piano_class_init (PianoClass * klass);static void piano_init (Piano * piano);static void piano_destroy (GtkObject * object);static void piano_realize (GtkWidget * widget);static void piano_size_request (GtkWidget * widget,  GtkRequisition * requisition);static void piano_size_allocate (GtkWidget * widget,  GtkAllocation * allocation);static gint piano_expose (GtkWidget * widget, GdkEventExpose * event);static gint piano_button_press (GtkWidget * widget, GdkEventButton * event);static gint piano_button_release (GtkWidget * widget, GdkEventButton * event);static gint piano_motion_notify (GtkWidget * widget, GdkEventMotion * event);static void piano_update_mouse (Piano * piano, gint x, gint y);#define POFSY 0static struct{  guint8 selx;  guint8 dispx;  gboolean white;		/* white key or black key? */}keyinfo[12] = { {6, 2, TRUE}, {11, 7, FALSE}, {15, 11, TRUE}, {20, 16, FALSE},  {26, 20, TRUE}, {33, 29, TRUE}, {38, 34, FALSE}, {42, 38, TRUE},  {47, 43, FALSE}, {51, 47, TRUE}, {56, 52, FALSE}, {62, 56, TRUE}};static GtkWidgetClass *parent_class = NULL;guintpiano_get_type (void){  static guint piano_type = 0;  if (!piano_type)    {      GtkTypeInfo piano_info = {	"Piano",	sizeof (Piano),	sizeof (PianoClass),	(GtkClassInitFunc) piano_class_init,	(GtkObjectInitFunc) piano_init,	(GtkArgSetFunc) NULL,	(GtkArgGetFunc) NULL,      };      piano_type = gtk_type_unique (gtk_widget_get_type (), &piano_info);    }  return piano_type;}enum{  NOTE_ON,  NOTE_OFF,  DUMMY_SIGNAL			/* used to count signals */};static gint piano_signals[DUMMY_SIGNAL] = { 0 };static voidpiano_class_init (PianoClass * klass){  GtkObjectClass *object_class;  GtkWidgetClass *widget_class;  object_class = (GtkObjectClass *) klass;  widget_class = (GtkWidgetClass *) klass;  parent_class = gtk_type_class (gtk_widget_get_type ());  piano_signals[NOTE_ON] = gtk_signal_new ("note-on",    GTK_RUN_FIRST, object_class->type,    GTK_SIGNAL_OFFSET (PianoClass, note_on),    gtk_marshal_NONE__UINT, GTK_TYPE_NONE, 1, GTK_TYPE_UINT);  piano_signals[NOTE_OFF] = gtk_signal_new ("note-off",    GTK_RUN_FIRST, object_class->type,    GTK_SIGNAL_OFFSET (PianoClass, note_off),    gtk_marshal_NONE__UINT, GTK_TYPE_NONE, 1, GTK_TYPE_UINT);  gtk_object_class_add_signals (object_class, piano_signals, DUMMY_SIGNAL);  klass->note_on = NULL;  klass->note_off = NULL;  object_class->destroy = piano_destroy;  widget_class->realize = piano_realize;  widget_class->expose_event = piano_expose;  widget_class->size_request = piano_size_request;  widget_class->size_allocate = piano_size_allocate;  widget_class->button_press_event = piano_button_press;  widget_class->button_release_event = piano_button_release;  widget_class->motion_notify_event = piano_motion_notify;}/* ----------------------------------------------- initialize piano widget Draws piano pixmap and black/white (un)selected state pixmaps Sets variables to default states----------------------------------------------- */static voidpiano_init (Piano * piano){  piano->key_mouse = 255;	/* no key selected with mouse */  piano->key_lospan = 255;	/* no lo span indicator */  piano->key_hispan = 255;	/* no high span indicator */  piano->key_root = 255;	/* no root key indicator */}GtkWidget *piano_new (gboolean * selkeys){  Piano *piano;  piano = gtk_type_new (piano_get_type ());  piano->selkeys = selkeys;  return GTK_WIDGET (piano);}/* draws specified key in its "on" state */voidpiano_note_on (Piano * piano, guint8 keynum){  gint xval, mod;  GdkRectangle uparea;		/* update area rectangle */  g_return_if_fail (piano != NULL);  g_return_if_fail (IS_PIANO (piano));  g_return_if_fail (keynum < 128);  if (piano->selkeys[keynum])    return;			/* already selected? */  piano->selkeys[keynum] = TRUE;  mod = keynum % 12;  xval = keynum / 12 * 63 + keyinfo[mod].dispx;  if (keyinfo[mod].white)    {      gdk_draw_pixmap (piano->keyb_pm,	piano->widget.style->fg_gc[GTK_WIDGET_STATE (&piano->widget)],	piano->selw_pm, 0, 0, xval - 1, 39 + POFSY, 8, 8);      uparea.x = xval - 1;      uparea.y = 39 + POFSY;      uparea.width = 8;    }  else    {      gdk_draw_pixmap (piano->keyb_pm,	piano->widget.style->fg_gc[GTK_WIDGET_STATE (&piano->widget)],	piano->selb_pm, 0, 0, xval, 20 + POFSY, 5, 8);      uparea.x = xval;      uparea.y = 20 + POFSY;      uparea.width = 5;    }  uparea.height = 8;  gtk_widget_draw (&piano->widget, &uparea);}/* draws specified key in its "released" state */voidpiano_note_off (Piano * piano, guint8 keynum){  gint xval, mod;  GdkRectangle uparea;		/* update area */  g_return_if_fail (piano != NULL);  g_return_if_fail (IS_PIANO (piano));  g_return_if_fail (keynum < 128);  if (!piano->selkeys[keynum])    return;			/* already unselected? */  piano->selkeys[keynum] = FALSE;  mod = keynum % 12;  xval = keynum / 12 * 63 + keyinfo[mod].dispx;  if (keyinfo[mod].white)    {      gdk_draw_pixmap (piano->keyb_pm,	piano->widget.style->fg_gc[GTK_WIDGET_STATE (&piano->widget)],	piano->unsw_pm, 0, 0, xval - 1, 39 + POFSY, 8, 8);      uparea.x = xval - 1;      uparea.y = 39 + POFSY;      uparea.width = 8;    }  else    {      gdk_draw_pixmap (piano->keyb_pm,	piano->widget.style->fg_gc[GTK_WIDGET_STATE (&piano->widget)],	piano->unsb_pm, 0, 0, xval, 20 + POFSY, 5, 8);      uparea.x = xval;      uparea.y = 20 + POFSY;      uparea.width = 5;    }  uparea.height = 8;  gtk_widget_draw (&piano->widget, &uparea);}/* converts a key number to x position in pixels to center of key */gintpiano_key_to_xpos (guint8 keynum){  gint mod, xval;  if (keynum > 127)    keynum = 127;  mod = keynum % 12;  xval = keynum / 12 * 63 + keyinfo[mod].dispx;  if (keyinfo[mod].white)    xval += 2;  else    xval += 2;  /* slight adjustments for adjacent white keys, looks like center */  if (mod == 4 || mod == 11)    xval++;  else if (mod == 5 || mod == 0)    xval--;  return (xval);}/* converts a pixel x position to key number */guint8piano_xpos_to_key (gint xpos){  gint xval, i;  guint8 keynum;  xval = xpos % 63;		/* pixel offset into keyboard octave */  for (i = 0; i < 12; i++)	/* loop through key selection offsets */    if (xval <= keyinfo[i].selx)      break;			/* is offset within key select */  keynum = xpos / 63 * 12 + i;	/* calc key number */  if (keynum > 127)    keynum = 127;  return (keynum);}static voidpiano_destroy (GtkObject * object){  Piano *piano;  g_return_if_fail (object != NULL);  g_return_if_fail (IS_PIANO (object));  piano = PIANO (object);  gdk_pixmap_unref (piano->keyb_pm);  gdk_pixmap_unref (piano->selw_pm);  gdk_pixmap_unref (piano->unsw_pm);  gdk_pixmap_unref (piano->selb_pm);  gdk_pixmap_unref (piano->unsb_pm);  gdk_gc_unref (piano->shadowgc);  gdk_color_free (&piano->shadclr);  if (GTK_OBJECT_CLASS (parent_class)->destroy)    (*GTK_OBJECT_CLASS (parent_class)->destroy) (object);}static voidpiano_realize (GtkWidget * widget){

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -