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 + -
显示快捷键?