root/foundation-apps/grosview-maxx/fieldmeterdecay.cc

Revision 2, 7.2 KB (checked in by emasson, 3 years ago)

initial import for the community edition

Line 
1//
2//  The original FieldMeter class is Copyright (c) 1994, 2006 by Mike Romberg
3//    ( mike.romberg@noaa.gov )
4//  Modifications from FieldMeter class done in Oct. 1995
5//    by Brian Grayson ( bgrayson@netbsd.org )
6//
7//  This file was written by Brian Grayson for the NetBSD and xosview
8//    projects.
9//  This file may be distributed under terms of the GPL or of the BSD
10//    license, whichever you choose.  The full license notices are
11//    contained in the files COPYING.GPL and COPYING.BSD, which you
12//    should have received.  If not, contact one of the xosview
13//    authors for a copy.
14//
15// $Id: fieldmeterdecay.cc,v 1.1.1.1 2008/05/04 15:53:48 emasson Exp $
16//
17
18// In order to use the FieldMeterDecay class in place of a FieldMeter class in
19// a meter file (say, cpumeter.cc), make the following changes:
20//   1.  Change cpumeter.h to include fieldmeterdecay.h instead of
21//       fieldmeter.h
22//   2.  Change CPUMeter to inherit from FieldMeterDecay, rather than
23//       FieldMeter.
24//   3.  Change the constructor call to use FieldMeterDecay(), rather than
25//       FieldMeter().
26//   4.  Make the checkResources () function in the meter set the
27//       dodecay_ variable according to the, e.g., xosview*cpuDecay resource.
28
29#ifdef HAVE_IOSTREAM
30#include <iostream>
31#else
32#include <iostream.h>
33#endif
34#ifdef HAVE_FSTREAM
35#include <fstream>
36#else
37#include <fstream.h>
38#endif
39#include <math.h>               //  For fabs()
40#include "general.h"
41#include "fieldmeter.h"
42#include "fieldmeterdecay.h"
43#include "xosview.h"
44
45CVSID("$Id: fieldmeterdecay.cc,v 1.1.1.1 2008/05/04 15:53:48 emasson Exp $");
46CVSID_DOT_H(FIELDMETERDECAY_H_CVSID);
47
48FieldMeterDecay::FieldMeterDecay( XOSView *parent,
49                int numfields, const char *title,
50                const char *legend, int docaptions, int dolegends,
51                int dousedlegends )
52: FieldMeter (parent, numfields, title, legend, docaptions, dolegends,
53              dousedlegends)
54{
55  decay_ = new float[numfields];
56  lastDecayval_ = new float[numfields];
57  for (int decayCtr = 0; decayCtr < numfields; decayCtr++) {
58    decay_[decayCtr] = 0.0;
59    lastDecayval_[decayCtr] = 0.0;
60  }
61  decay_[numfields-1] = 1.0;  //  Initialize to all free...
62  firsttime_ = 1;
63  dodecay_ = 1;
64}
65
66FieldMeterDecay::~FieldMeterDecay( void ){
67  delete[] decay_;
68  delete[] lastDecayval_;
69}
70
71void FieldMeterDecay::drawfields( int manditory ){
72  int twidth, x = x_;
73
74  if (!dodecay_)
75  {
76    //  If this meter shouldn't be done as a decaying splitmeter,
77    //  call the ordinary fieldmeter code.
78    FieldMeter::drawfields (manditory);
79    return;
80  }
81
82  if ( total_ == 0.0 )
83    return;
84
85//RADEKE was  int halfheight = height_ / 2;
86  int halfheight = 0 ; //was = height_ / 2
87  int decaytwidth, decayx = x_;
88 
89  //  This code is supposed to make the average display look just like
90  //  the ordinary display for the first drawfields, but it doesn't seem
91  //  to work too well.  But it's better than setting all decay_ fields
92  //  to 0.0 initially!
93
94  if (firsttime_) {
95    firsttime_ = 0;
96    for (int i = 0; i < numfields_; i++)
97         {
98                decay_[i] = 1.0*fields_[i]/total_;
99         }
100  }
101
102  //  Update the decay fields.  This is not quite accurate, since if
103  //  the screen is refreshed, we will update the decay fields more
104  //  often than we need to.  However, this makes the decay stuff
105  //  TOTALLY independent of the ????Meter methods.
106
107  //  The constant below can be modified for quicker or slower
108  //  exponential rates for the average.  No fancy math is done to
109  //  set it to correspond to a five-second decay or anything -- I
110  //  just played with it until I thought it looked good!  :)  BCG
111
112//RADEKE 101004 was #define ALPHA 0.97
113#define ALPHA 0.72 //was 0.93
114
115    /*  This is majorly ugly code.  It needs a rewrite.  BCG  */
116    /*  I think one good way to do it may be to normalize all of the
117     *  fields_ in a temporary array into the range 0.0 .. 1.0,
118     *  calculate the shifted starting positions and ending positions
119     *  for coloring, multiply by the pixel width of the meter, and
120     *  then turn to ints.  I think this will solve a whole bunch of
121     *  our problems with rounding that before we tackled at a whole
122     *  lot of places.  BCG */
123  for ( int i = 0 ; i < numfields_ ; i++ ){
124
125    decay_[i] = ALPHA*decay_[i] + (1-ALPHA)*(fields_[i]*1.0/total_);
126
127    //  We want to round the widths, rather than truncate.
128    twidth = (int) (0.5 + (width_ * (float) fields_[i]) / total_);
129    decaytwidth = (int) (0.5 + width_ * decay_[i]);
130    if (decaytwidth < 0.0)
131    {
132    //    std::cerr << "Error:  FieldMeterDecay " << name() << ":  decaytwidth of ";
133    //    std::cerr << decaytwidth << ", width of " << width_ << ", decay_[" << i;
134    //    std::cerr << "] of " << decay_[i] << std::endl;
135    decaytwidth =0;
136   
137    }
138
139    //  However, due to rounding, we may have gone one
140    //  pixel too far by the time we get to the later fields...
141    if (x + twidth > x_ + width_)
142      twidth = width_ + x_ - x;
143    if (decayx + decaytwidth > x_ + width_)
144      decaytwidth = width_ + x_ - decayx;
145
146    //  Also, due to rounding error, the last field may not go far
147    //  enough...
148    if ( (i == numfields_ - 1) && ((x + twidth) != (x_ + width_)) )
149      twidth = width_ + x_ - x;
150    if ( (i == numfields_ - 1) && ((decayx + decaytwidth) != (x_ + width_)))
151      decaytwidth = width_ + x_ - decayx;
152
153    parent_->setForeground( colors_[i] );
154    parent_->setStippleN(i%4);
155
156      //  drawFilledRectangle() adds one to its width and height.
157      //    Let's correct for that here.
158    if ( manditory || (twidth != lastvals_[i]) || (x != lastx_[i]) ){
159   
160    if (!checkX(x, twidth))
161       x=0;
162       
163//        std::cerr <<__FILE__ << ":" << __LINE__ <<std::endl;
164//RADEKE do'nt draw the hectic bar at all (sgi look)
165//      parent_->drawFilledRectangle( x, y_, twidth, halfheight );
166    }
167
168//RADEKE 101004 this hack removes the tiled (ugly) cpu meter, only decayed full hight
169// will be displayed, anyway what the Xresources says
170//    if ( manditory || (decay_[i] != lastDecayval_[i]) ){
171//      if (!checkX(decayx, decaytwidth))
172//        std::cerr <<__FILE__ << ":" << __LINE__ <<std::endl;
173//      parent_->drawFilledRectangle( decayx, y_+halfheight+1,
174//            decaytwidth, height_ - halfheight-1);
175//    }
176//// my values of 2 years experiance
177
178    if ( manditory || (decay_[i] != lastDecayval_[i]) ){
179 
180     if (!checkX(decayx, decaytwidth))
181        decayx=0;
182       
183//      std::cerr <<__FILE__ << ":" << __LINE__ <<std::endl;
184      parent_->drawFilledRectangle( decayx, y_+halfheight, decaytwidth, height_ - halfheight);
185    }
186
187//RADEKE 101004 SGI Stile of the meters.. gives them a shadow and white tickmarks
188  // the black bars
189   parent_->setForeground(000000);
190   parent_->drawFilledRectangle( x_, y_ +height_ , width_, height_/9);
191 // the white markers insinde the black bar
192   parent_->setForeground(16777215);
193   for(int k=0;k<=10;k++)
194     {
195     parent_->drawFilledRectangle( x_ +k*width_/10, y_+(height_ ),
196     0, height_ /12); //0 is better than any calculation here
197     }
198//end RADEKE
199
200    lastvals_[i] = twidth;
201    lastx_[i] = x;
202    lastDecayval_[i] = decay_[i];
203
204    parent_->setStippleN(0);    /*  Restore all-bits stipple.  */
205    if ( dousedlegends_ )
206      drawused( manditory );
207    x += twidth;
208
209    decayx += decaytwidth;
210
211  }
212
213  //parent_->flush();
214}
Note: See TracBrowser for help on using the browser.