samview.c

来自「A GTK sound font editor. Sound font file」· C语言 代码 · 共 1,307 行 · 第 1/3 页

C
1,307
字号
	}      /* calculate the x position (in pixels) of the marker */      VIEW_SAM2XPOS (x, mark->pos, samview);      mark->xpos = x;      if (!mark->gc)	{			/* create graphics context if needed */	  cmap = gdk_window_get_colormap (widget->window);	  mark->gc = gdk_gc_new (widget->window);	  gdk_colormap_alloc_color (cmap, &mark->color, FALSE, TRUE);	  gdk_gc_set_foreground (mark->gc, &mark->color);	}      /* if marker is selected, draw it highlighted, else use its own color */      if (mark != samview->sel_marker)	gc = mark->gc;      else	gc = samview->selmark_gc;      /* draw marker */      gdk_draw_line (samview->samview_pm, gc, x, 0, x, vheight - 1);    }  /* mid point in pixels from top */  vmid = vheight / 2;  /* draw center line */  gdk_draw_line (samview->samview_pm, samview->cline_gc,    0, vmid, vwidth - 1, vmid);  /* calc samples per pixel ratio */  xmul = (float) (samview->size - 1) / (vwidth - 1);  ymul = (float) (vheight - 1) / 65535;	/* pixels per amplitude ratio */  for (x = 0; x < vwidth; x++)    {      i = samview->start + (int) (x * xmul);	/* this sample index */      if (i >= samview->length)	break;			/* index beyond sample data? */      /* convert sample to unsigned (^ 0x8000) and calc pixel amplitude */      y =	vheight - 1 -	(int) (((guint16) (samview->samdata[i]) ^ 0x8000) * ymul);      if (x > 0)	{			/* first sample point doesn't draw line */	  gdk_draw_line (samview->samview_pm, samview->sam_gc,	    x - 1, lasty, x, y);	}      lasty = y;    }  /* if there is a selection and it should be drawn.. */  if (samview->select_start != -1)    {      gint s, e, sx, ex;      /* calculate virtual x positions of start and end of selection */      VIEW_SAM2XPOS (sx, samview->select_start, samview);      VIEW_SAM2XPOS (ex, samview->select_end, samview);      /* determine area of selection within view */      s = MAX (0, sx);      e = MIN (vwidth - 1, ex);      /* s > e if selection is entirely outside of view */      if (s <= e)	{			/* draw selection if not outside of view */	  gdk_draw_rectangle (samview->samview_pm, samview->select_gc, TRUE,	    s, 0, e - s + 1, vheight);	}    }}static gintsamview_button_press (GtkWidget * widget, GdkEventButton * event){  SamView *samview;  gint s, e;  gboolean ctrl;  g_return_val_if_fail (widget != NULL, FALSE);  g_return_val_if_fail (IS_SAMVIEW (widget), FALSE);  g_return_val_if_fail (event != NULL, FALSE);  samview = SAMVIEW (widget);  /* if a zoom is in progress, return */  if (samview->zoom_btn != 0)    return (FALSE);  if (event->button != 1 && event->button != 3)    return (FALSE);  ctrl = (event->state & GDK_CONTROL_MASK) != 0;  /* zoom if SHIFT is held down on keyboard */  if (event->state & GDK_SHIFT_MASK)    {      samview->zoom_btn = event->button;      samview->zoom_pos = event->x;      VIEW_X2SAMPOS (samview->zoom_sampos, event->x, samview);      samview->zoom_ofs = 0;      samview->zoom_dir = 2;      samview->zoom_toactv = FALSE;      gtk_grab_add (widget);	/* grab all mouse events */      samview_redraw (SAMVIEW (widget));    }  else if ((event->button == 1 && !ctrl)    || (ctrl && samview->select_start == -1))    {				/* selection operation? */      /* store selection start sample position */      VIEW_X2SAMPOS (samview->select_actvbegin, event->x, samview);      /* invalidate previous selection (if any) */      if (samview->select_start != -1)	{	  samview->select_start = samview->select_end = -1;	  samview_redraw (SAMVIEW (widget));	  gtk_signal_emit (GTK_OBJECT (samview),	    samview_signals[SELECTION_CHANGE]);	}      gtk_grab_add (widget);	/* grab all mouse events */    }  else if (ctrl)    {				/* add to selection? */      if (event->button == 1)	s = samview->select_end;      else	s = samview->select_start;      samview->select_actvbegin = s;      VIEW_X2SAMPOS (e, event->x, samview);      CMPSWAP (s, e);      samview->select_start = s;      samview->select_end = e;      samview_redraw (SAMVIEW (widget));      gtk_signal_emit (GTK_OBJECT (samview),	samview_signals[SELECTION_CHANGE]);      gtk_grab_add (widget);	/* grab all mouse events */    }  return (FALSE);}static gintsamview_button_release (GtkWidget * widget, GdkEventButton * event){  SamView *samview;  g_return_val_if_fail (widget != NULL, FALSE);  g_return_val_if_fail (IS_SAMVIEW (widget), FALSE);  g_return_val_if_fail (event != NULL, FALSE);  samview = SAMVIEW (widget);  /* zoom is done? */  if (event->button == samview->zoom_btn)    {      samview->zoom_btn = 0;      if (samview->zoom_toactv)	{			/* disable any active timeout */	  g_source_remove (samview->zoom_toid);	  samview->zoom_toactv = FALSE;	}      gtk_grab_remove (widget);	/* no more mouse event grabbing */      samview_redraw (SAMVIEW (widget));	/* redraw sample view */    }  /* selection done? */  if (samview->select_actvbegin != -1)    {      samview->select_actvbegin = -1;	/* selection no longer active */      gtk_grab_remove (widget);	/* no more mouse event grabbing */      if (samview->select_scroll)	{	  samview->select_scroll = 0;	  g_source_remove (samview->select_toid);	}    }  return (FALSE);}static gintsamview_motion_notify (GtkWidget * widget, GdkEventMotion * event){  SamView *samview;  gint x, y;  gint s;  gint t, d, a;  float plus, minus;  GdkModifierType mods;  g_return_val_if_fail (widget != NULL, FALSE);  g_return_val_if_fail (IS_SAMVIEW (widget), FALSE);  g_return_val_if_fail (event != NULL, FALSE);  samview = SAMVIEW (widget);  x = event->x;  y = event->y;  if (event->is_hint || (event->window != widget->window))    gdk_window_get_pointer (widget->window, &x, &y, &mods);  if (samview->zoom_btn == 0)    {				/* selection in progress? */      if (samview->select_actvbegin == -1)	return (FALSE);      /* scroll?? */      if ((x < 0 && samview->start != 0) || (x >= widget->allocation.width	  && samview->start + samview->size < samview->length - 1))	{	  if (samview->select_scroll)	    {			/* scroll in progress? */	      d = ABS (y - samview->select_scrolly);	      t = event->time - samview->select_scrolltime;	      minus = SCROLL_DSLOPE * t + SCROLL_DOFS;	      samview->select_scrollamt += minus;	      if (samview->select_scrollamt < 0.0)		samview->select_scrollamt = 0.0;	      plus = SCROLL_SLOPE * d / t + SCROLL_OFS;	      samview->select_scrollamt += plus;	      if (samview->select_scrollamt > SCROLL_MAX)		samview->select_scrollamt = SCROLL_MAX;	      a = (x < 0) ? 1 : 2;	/* direction of scroll 1,2 = left,right */	      /* probably won't happen, but just in case scroll direction	         switches without being disabled first */	      if (a != samview->select_scroll)		{		  samview->select_scroll = a;	/* change direction */		  samview->select_scrollamt = 0.0;	/* reset counters */		  samview->select_scrollaccum = 0;		}	      a = (float) samview->select_scrollamt		/ (widget->allocation.width - 1) * (samview->size - 1);	      samview->select_scrollaccum += a;//	      printf ("%d %2.2f %2.2f %2.2f\n", event->time,//		samview->select_scrollamt, plus, minus);	    }	  else	    {			/* ?: scroll not in progress, so initiate it */	      samview->select_scroll = (x < 0) ? 1 : 2;	      samview->select_scrollamt = 0.0;	      samview->select_scrollaccum = 0;	      samview->select_toid = g_timeout_add_full (SCROLL_PRIORITY,		SCROLL_TINTERVAL, samview_scroll_timeout,		(gpointer) samview, NULL);	    }	  samview->select_scrolltime = event->time;	  samview->select_scrolly = y;	}      else	samview->select_scroll = 0;	/* ?: no scroll */      x = CLAMP (x, 0, widget->allocation.width - 1);	/* clamp x to view */      /* calculate new start point of selection in samples */      samview->select_start = CLAMP (samview->select_actvbegin, 0,	samview->length - 1);      /* calculate new end point of selection in samples */      VIEW_X2SAMPOS (s, x, samview);      samview->select_end = CLAMP (s, 0, samview->length - 1);      /* swap start/end if in reverse */      CMPSWAP (samview->select_start, samview->select_end);      samview_redraw (SAMVIEW (widget));      gtk_signal_emit (GTK_OBJECT (samview),	samview_signals[SELECTION_CHANGE]);      return (FALSE);    }  if (samview->zoom_dir == 2)    {				/* un/zoom not determined yet? */      if (x > samview->zoom_pos + ZOOM_SAFEZONE)	{	  samview->zoom_dir = 0;	}      else if (x < samview->zoom_pos - ZOOM_SAFEZONE)	{	  samview->zoom_dir = 1;	}      else	return (FALSE);      if (samview->zoom_btn == 3)	samview->zoom_dir ^= 1;    }  samview->zoom_ofs = x - samview->zoom_pos;  if (abs (samview->zoom_ofs) > ZOOM_SAFEZONE)    {				/* safe zone? */      /* calculate zoom/unzoom interval timeout (in milliseconds) */      samview->zoom_totime = (float) (abs (samview->zoom_ofs) - ZOOM_SAFEZONE)	* ZOOM_TIME_SLOPE + ZOOM_TIME_OFS;      /* make sure interval isn't too fast */      if (samview->zoom_totime < ZOOM_TIME_MIN)	samview->zoom_totime = ZOOM_TIME_MIN;      /* calculate ZOOM amount */      samview->zoom_amount = (float) (abs (samview->zoom_ofs) - ZOOM_SAFEZONE)	* ZOOM_AMT_SLOPE + ZOOM_AMT_OFS;      /* make sure un/zoom amount isn't too much */      if (samview->zoom_amount < ZOOM_AMT_MIN)	samview->zoom_amount = ZOOM_AMT_MIN;      /* If UNZOOM, UNZOOM = 1 / ZOOM */      if ((samview->zoom_dir == 0 && samview->zoom_ofs < 0)	|| (samview->zoom_dir == 1 && samview->zoom_ofs > 0))	samview->zoom_amount = 1.0 / samview->zoom_amount;      if (!samview->zoom_toactv)	{			/* start timeout, if not actv */	  samview->zoom_toid = g_timeout_add_full (ZOOM_PRIORITY,	    samview->zoom_totime, samview_zoom_timeout,	    (gpointer) samview, NULL);	  samview->zoom_toactv = TRUE;	}    }  else if (samview->zoom_toactv)    {				/* ?: Yes, safe ZONE */      g_source_remove (samview->zoom_toid);	/* disable timeout function */      samview->zoom_toactv = FALSE;    }  return (FALSE);}static gbooleansamview_scroll_timeout (gpointer data){  SamView *samview;  gint a;  samview = SAMVIEW (data);  a = samview->select_scrollaccum;  if (!a || !samview->select_scroll)    return (TRUE);  if (samview->select_scroll == 1)    {      a = samview->start - a;      if (a < 0)	a = 0;    }  else    {      a = samview->start + a;      if (a + samview->size >= samview->length)	a = samview->length - samview->size - 1;    }  samview->select_scrollaccum = 0;  if (samview->start == a)    return (TRUE);  samview_freeze (samview);  samview_set_position (samview, a);  samview_thaw (samview);  return (TRUE);}static gbooleansamview_zoom_timeout (gpointer data){  SamView *samview;  gint vwidth;  gint newsize;  gint newstart;  samview = SAMVIEW (data);  vwidth = GTK_WIDGET (samview)->allocation.width;  /* calculate new view size (in samples) i.e. zoom in or out */  newsize = samview->size * samview->zoom_amount;  /* make sure newsize is within bounds */  if (newsize > samview->length)    newsize = samview->length;  if (newsize < vwidth)    newsize = vwidth;		/* at least 1 sample per pixel */  /* calculate new start position, keeping zoom point stationary */  newstart = (int) ((float) samview->zoom_pos / (vwidth - 1) * newsize);  newstart = samview->zoom_sampos - newstart;  /* make sure newstart is within bounds */  if (newstart < 0)    newstart = 0;  else if (newstart + newsize > samview->length)    newstart = samview->length - newsize;  if (newstart != samview->start || newsize != samview->size)    samview_set_view (samview, newstart, newsize);  samview->zoom_toid = g_timeout_add (samview->zoom_totime,    samview_zoom_timeout, (gpointer) samview);  samview->zoom_toactv = TRUE;  return (FALSE);		/* don't destroy timeout */}

⌨️ 快捷键说明

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