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