1 /*
2 * Copyright (C) 2002 2003 2004, Magnus Hjorth
3 *
4 * This file is part of mhWaveEdit.
5 *
6 * mhWaveEdit is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * mhWaveEdit is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with mhWaveEdit; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19 */
20
21
22 #include <config.h>
23
24 #include <math.h>
25
26 #include "main.h"
27 #include "vu_meter.h"
28
vu_meter_size_request(GtkWidget * widget,GtkRequisition * req)29 static void vu_meter_size_request(GtkWidget *widget, GtkRequisition *req)
30 {
31 req->width = 80;
32 req->height = 60;
33 }
34
draw_meter_line(VuMeter * v,GdkGC * gc)35 static void draw_meter_line(VuMeter *v, GdkGC *gc)
36 {
37 guint w,h;
38 gfloat ang = (0.75-0.5*v->value)*3.1415;
39 gfloat len;
40 w = GTK_WIDGET(v)->allocation.width;
41 h = GTK_WIDGET(v)->allocation.height;
42 len = ((gfloat)h)*0.8;
43 gdk_draw_line(GTK_WIDGET(v)->window,gc,w/2,h,
44 w/2+(gint)(len*cos(ang)),h-(gint)(len*sin(ang)));
45 }
46
draw_black_arc(VuMeter * v)47 static void draw_black_arc(VuMeter *v)
48 {
49 GtkWidget *widget = GTK_WIDGET(v);
50 gdk_draw_arc(widget->window,widget->style->black_gc,1,
51 widget->allocation.width/2-15,
52 widget->allocation.height-15,30,30,0,180*64);
53 }
54
vu_meter_expose(GtkWidget * widget,GdkEventExpose * event)55 static gint vu_meter_expose(GtkWidget *widget, GdkEventExpose *event)
56 {
57 VuMeter *vu = VU_METER(widget);
58 guint w,h;
59 gfloat len;
60 w = widget->allocation.width;
61 h = widget->allocation.height;
62 len = ((gfloat)h)*0.8;
63 gdk_draw_rectangle(widget->window,widget->style->black_gc,0,0,0,w,h);
64 gdk_draw_rectangle(widget->window,widget->style->black_gc,0,1,1,w-2,h-2);
65 gdk_draw_rectangle(widget->window,widget->style->black_gc,0,2,2,w-4,h-4);
66 /* gdk_draw_rectangle(widget->window,widget->style->bg_gc[0],1,3,3,w-6,h-6); */
67 gdk_draw_arc(widget->window,widget->style->white_gc,1,w/2-len,h-len,
68 len*2,len*2,45*64,90*64);
69 draw_black_arc(vu);
70 draw_meter_line(vu,widget->style->black_gc);
71 return TRUE;
72 }
73
vu_meter_class_init(GtkWidgetClass * klass)74 static void vu_meter_class_init(GtkWidgetClass *klass)
75 {
76 klass->size_request = vu_meter_size_request;
77 klass->expose_event = vu_meter_expose;
78 }
79
vu_meter_init(VuMeter * v)80 static void vu_meter_init(VuMeter *v)
81 {
82 v->value = 0.0;
83 v->goal = 0.0;
84 }
85
vu_meter_get_type(void)86 GtkType vu_meter_get_type(void)
87 {
88 static GtkType id = 0;
89 if (!id) {
90 GtkTypeInfo info = {
91 "VuMeter",
92 sizeof(VuMeter),
93 sizeof(VuMeterClass),
94 (GtkClassInitFunc) vu_meter_class_init,
95 (GtkObjectInitFunc) vu_meter_init
96 };
97 id = gtk_type_unique(gtk_drawing_area_get_type(),&info);
98 }
99 return id;
100 }
101
vu_meter_new(gfloat value)102 GtkWidget *vu_meter_new(gfloat value)
103 {
104 VuMeter *v;
105 v = gtk_type_new(vu_meter_get_type());
106 v->value = value;
107 v->goal = value;
108 g_get_current_time(&(v->valuetime));
109 return GTK_WIDGET(v);
110 }
111
vu_meter_update_value_real(VuMeter * v,GTimeVal * tv)112 static void vu_meter_update_value_real(VuMeter *v, GTimeVal *tv)
113 {
114 GTimeVal diff;
115 float f;
116 timeval_subtract(&diff,tv,&(v->valuetime));
117 f = ((float)diff.tv_usec) / 1000000.0 + ((float)diff.tv_sec);
118 v->value = v->value + (v->goal - v->value)*(1-exp(-f*10.0));
119 memcpy(&(v->valuetime),tv,sizeof(GTimeVal));
120 }
121
undraw_value(VuMeter * v)122 static void undraw_value(VuMeter *v)
123 {
124 draw_meter_line(v,GTK_WIDGET(v)->style->white_gc);
125 draw_black_arc(v);
126 }
127
draw_value(VuMeter * v)128 static void draw_value(VuMeter *v)
129 {
130 draw_meter_line(v,GTK_WIDGET(v)->style->black_gc);
131 }
132
vu_meter_update(VuMeter * v)133 void vu_meter_update(VuMeter *v)
134 {
135 GTimeVal tv;
136 undraw_value(v);
137 g_get_current_time(&tv);
138 vu_meter_update_value_real(v,&tv);
139 draw_value(v);
140 }
141
vu_meter_set_value(VuMeter * v,gfloat value)142 void vu_meter_set_value(VuMeter *v, gfloat value)
143 {
144 GTimeVal tv;
145 undraw_value(v);
146 g_get_current_time(&tv);
147 vu_meter_update_value_real(v,&tv);
148 v->goal = value;
149 if (value > v->value) v->value = value;
150 draw_value(v);
151 }
152
153