xosview  1.23
About: xosview is an X Windows based system monitor (cpu, memory, swap and network usage; interrupt and serial activities; load average).
  Fossies Dox: xosview-1.23.tar.gz  ("unofficial" and yet experimental doxygen-generated source code documentation)  

fieldmeter.cc
Go to the documentation of this file.
1 //
2 // Copyright (c) 1994, 1995, 2006 by Mike Romberg ( mike.romberg@noaa.gov )
3 //
4 // This file may be distributed under terms of the GPL
5 //
6 
7 #include "fieldmeter.h"
8 #include <stdio.h>
9 #include <stdlib.h>
10 #include <string.h>
11 #include <math.h>
12 #include <iostream>
13 
14 
15 FieldMeter::FieldMeter( XOSView *parent, int numfields, const char *title,
16  const char *legend, int docaptions, int dolegends,
17  int dousedlegends )
18 : Meter(parent, title, legend, docaptions, dolegends, dousedlegends){
19  /* We need to set print_ to something valid -- the meters
20  * apparently get drawn before the meters have a chance to call
21  * CheckResources() themselves. */
23  print_ = PERCENT;
24  metric_ = false;
25  usedoffset_ = 0;
26  used_ = 0;
27  lastused_ = -1;
28  fields_ = NULL;
29  colors_ = NULL;
30  lastvals_ = NULL;
31  lastx_ = NULL;
32  setNumFields(numfields);
33 }
34 
35 void
37 {
38  setNumFields(1);
39  setfieldcolor (0, "gray");
40  Meter::legend ("Disabled");
41  // And specify the total of 1.0, so the meter is grayed out.
42  total_ = 1.0;
43  fields_[0] = 1.0;
44 }
45 
46 
48  delete[] fields_;
49  delete[] colors_;
50  delete[] lastvals_;
51  delete[] lastx_;
52 }
53 
56  usedcolor_ = parent_->allocColor( parent_->getResource( "usedLabelColor") );
57 }
58 
59 
60 void FieldMeter::SetUsedFormat ( const char * const fmt ) {
61  /* Do case-insensitive compares. */
62  if (!strncasecmp (fmt, "percent", 8))
63  print_ = PERCENT;
64  else if (!strncasecmp (fmt, "autoscale", 10))
65  print_ = AUTOSCALE;
66  else if (!strncasecmp (fmt, "float", 6))
67  print_ = FLOAT;
68  else {
69  std::cerr << "Error: could not parse format of '" << fmt << "'.\n"
70  << " I expected one of 'percent', 'autoscale', or 'float'"
71  << " (Case-insensitive)." << std::endl;
72  exit(1);
73  }
74 }
75 
76 void FieldMeter::setUsed (double val, double total)
77 {
78  if (print_ == FLOAT)
79  used_ = val;
80  else if (print_ == PERCENT)
81  {
82  if (total != 0.0)
83  used_ = val / total * 100.0;
84  else
85  {
86  if (!printedZeroTotalMesg_) {
88  std::cerr << "Warning: " << name() << " meter had a zero total field! "
89  << "Would have caused a div-by-zero exception." << std::endl;
90  }
91  used_ = 0.0;
92  }
93  }
94  else if (print_ == AUTOSCALE)
95  used_ = val;
96  else {
97  std::cerr << "Error in " << name() << ": I can't handle a UsedType enum "
98  << "value of " << print_ << "!" << std::endl;
99  exit(1);
100  }
101 }
102 
103 void FieldMeter::reset( void ){
104  for ( int i = 0 ; i < numfields_ ; i++ )
105  lastvals_[i] = lastx_[i] = -1;
106 }
107 
108 void FieldMeter::setfieldcolor( int field, const char *color ){
109  colors_[field] = parent_->allocColor( color );
110 }
111 
112 void FieldMeter::setfieldcolor( int field, unsigned long color ) {
113  colors_[field] = color;
114 }
115 
116 void FieldMeter::draw( void ){
117  /* Draw the outline for the fieldmeter. */
119  parent_->drawRectangle( x_ - 1, y_ - 1, width_ + 2, height_ + 2 );
120  if ( dolegends_ ){
122 
123  int offset;
124  if ( dousedlegends_ )
125  offset = parent_->textWidth( "XXXXXXXXXX" );
126  else
127  offset = parent_->textWidth( "XXXXXX" );
128 
129  parent_->drawString( x_ - offset + 1, y_ + height_, title_ );
130  }
131 
132  drawlegend();
133  drawfields( 1 );
134 }
135 
137  char *tmp1, *tmp2, buff[100];
138  int n, x = x_;
139 
140  if (!docaptions_ || !dolegends_)
141  return;
142 
143  parent_->clear( x_, y_ - 5 - parent_->textHeight(),
144  width_ + 5, parent_->textHeight() + 4 );
145 
146  tmp1 = tmp2 = legend_;
147  for ( int i = 0 ; i < numfields_ ; i++ ){
148  n = 0;
149  while ( (*tmp2 != '/') && (*tmp2 != '\0') ){
150  if ( (*tmp2 == '\\') && (*(tmp2 + 1) == '/') ) // allow '/' in field as '\/'
151  memmove( tmp2, tmp2 + 1, strlen(tmp2) );
152  tmp2++;
153  n++;
154  }
155  tmp2++;
156  strncpy( buff, tmp1, n );
157  buff[n] = '\0';
158  parent_->setStippleN(i%4);
160  parent_->drawString( x, y_ - 5, buff );
161  x += parent_->textWidth( buff, n );
163  if ( i != numfields_ - 1 )
164  parent_->drawString( x, y_ - 5, "/" );
165  x += parent_->textWidth( "/", 1 );
166  tmp1 = tmp2;
167  }
168  parent_->setStippleN(0); /* Restore default all-bits stipple. */
169 }
170 
171 void FieldMeter::drawused( int mandatory ){
172  if ( !mandatory )
173  if ( lastused_ == used_ )
174  return;
175 
176  parent_->setStippleN(0); /* Use all-bits stipple. */
177  static const int onechar = parent_->textWidth( "X" );
178  if (!usedoffset_) // metric meters need extra space for '-' sign
179  usedoffset_ = ( metric_ ? parent_->textWidth( "XXXXXX" )
180  : parent_->textWidth( "XXXXX" ) );
181  char buf[10];
182 
183  if (print_ == PERCENT){
184  snprintf( buf, 10, "%d%%", (int)used_ );
185  }
186  else if (print_ == AUTOSCALE){
187  char scale[2];
188  double scaled_used = scaleValue(used_, scale, metric_);
189  /* For now, we can only print 3 characters, plus the optional sign and
190  * suffix, without overprinting the legends. Thus, we can
191  * print 965, or we can print 34, but we can't print 34.7 (the
192  * decimal point takes up one character). bgrayson */
193  if (scaled_used == 0.0)
194  snprintf (buf, 10, "0");
195  else {
196  if (scaled_used < 0 && !metric_)
197  snprintf (buf, 10, "-");
198  else if ( fabs(scaled_used) < 9.95 )
199  // 9.95 or above would get
200  // rounded to 10.0, which is too wide.
201  snprintf (buf, 10, "%.1f%s", scaled_used, scale);
202  else
203  snprintf (buf, 10, "%.0f%s", scaled_used, scale);
204  }
205  }
206  else {
207  if ( fabs(used_) < 99.95 )
208  snprintf( buf, 10, "%.1f", used_ );
209  else // drop the decimal if the string gets too long
210  snprintf( buf, 10, "%.0f", used_ );
211  }
212 
214  usedoffset_ - onechar / 2, parent_->textHeight() + 1 );
216  parent_->drawString( x_ - (strlen( buf ) + 1 ) * onechar + 2,
217  y_ + height_, buf );
218  lastused_ = used_;
219 }
220 
221 void FieldMeter::drawfields( int mandatory ){
222  int twidth, x = x_;
223 
224  if ( total_ == 0 )
225  return;
226 
227  for ( int i = 0 ; i < numfields_ ; i++ ){
228  /* Look for bogus values. */
229  if (fields_[i] < 0.0 && !metric_) {
230  /* Only print a warning 5 times per meter, followed by a
231  * message about no more warnings. */
232  numWarnings_ ++;
233  if (numWarnings_ < 5)
234  std::cerr << "Warning: meter " << name() << " had a negative value of "
235  << fields_[i] << " for field " << i << std::endl;
236  if (numWarnings_ == 5)
237  std::cerr << "Future warnings from the " << name() << " meter will not "
238  << "be displayed." << std::endl;
239  }
240 
241  twidth = (int)fabs(((width_ * fields_[i]) / total_));
242  if ( (i == numfields_ - 1) && ((x + twidth) != (x_ + width_)) )
243  twidth = width_ + x_ - x;
244 
245  if ( mandatory || (twidth != lastvals_[i]) || (x != lastx_[i]) ){
247  parent_->setStippleN(i%4);
248  parent_->drawFilledRectangle( x, y_, twidth, height_ );
249  parent_->setStippleN(0); /* Restore all-bits stipple. */
250  lastvals_[i] = twidth;
251  lastx_[i] = x;
252  }
253  x += twidth;
254  }
255  if ( dousedlegends_ )
256  drawused( mandatory );
257 }
258 
260  drawfields(0);
261 }
262 
264  numfields_ = n;
265  delete[] fields_;
266  delete[] colors_;
267  delete[] lastvals_;
268  delete[] lastx_;
269  fields_ = new double[numfields_];
270  colors_ = new unsigned long[numfields_];
271  lastvals_ = new int[numfields_];
272  lastx_ = new int[numfields_];
273 
274  total_ = 0;
275  for ( int i = 0 ; i < numfields_ ; i++ ){
276  fields_[i] = 0.0; /* egcs 2.91.66 bug !? don't do this and */
277  lastvals_[i] = lastx_[i] = 0; /* that in a single statement or it'll */
278  /* overwrite too much with 0 ... */
279  /* Thomas Waldmann ( tw@com-ma.de ) */
280  }
281 }
282 
283 bool FieldMeter::checkX(int x, int width) const {
284  if ((x < x_) || (x + width < x_)
285  || (x > x_ + width_) || (x + width > x_ + width_)){
286  std::cerr << "FieldMeter::checkX() : bad horiz values for meter : "
287  << name() << std::endl;
288 
289  std::cerr <<"value "<<x<<", width "<<width<<", total_ = "<<total_<<std::endl;
290 
291  for (int i = 0 ; i < numfields_ ; i++)
292  std::cerr <<"fields_[" <<i <<"] = " <<fields_[i] <<",";
293  std::cerr <<std::endl;
294 
295  return false;
296  }
297 
298  return true;
299 }
virtual ~FieldMeter(void)
Definition: fieldmeter.cc:47
void reset(void)
Definition: fieldmeter.cc:103
double total_
Definition: fieldmeter.h:41
int printedZeroTotalMesg_
Definition: fieldmeter.h:46
virtual void checkResources(void)
Definition: fieldmeter.cc:54
void setfieldcolor(int field, const char *color)
Definition: fieldmeter.cc:108
bool metric_
Definition: fieldmeter.h:48
int numWarnings_
Definition: fieldmeter.h:47
void drawlegend(void)
Definition: fieldmeter.cc:136
FieldMeter(XOSView *parent, int numfields, const char *title="", const char *legend="", int docaptions=0, int dolegends=0, int dousedlegends=0)
Definition: fieldmeter.cc:15
void setUsed(double val, double total)
Definition: fieldmeter.cc:76
void drawused(int mandatory)
Definition: fieldmeter.cc:171
virtual void drawfields(int mandatory=0)
Definition: fieldmeter.cc:221
int numfields_
Definition: fieldmeter.h:39
int usedoffset_
Definition: fieldmeter.h:49
unsigned long usedcolor_
Definition: fieldmeter.h:44
void checkevent(void)
Definition: fieldmeter.cc:259
void setNumFields(int n)
Definition: fieldmeter.cc:263
double * fields_
Definition: fieldmeter.h:40
unsigned long * colors_
Definition: fieldmeter.h:43
int * lastvals_
Definition: fieldmeter.h:42
int * lastx_
Definition: fieldmeter.h:42
double lastused_
Definition: fieldmeter.h:41
UsedType print_
Definition: fieldmeter.h:45
void draw(void)
Definition: fieldmeter.cc:116
double used_
Definition: fieldmeter.h:41
void SetUsedFormat(const char *const str)
Definition: fieldmeter.cc:60
bool checkX(int x, int width) const
Definition: fieldmeter.cc:283
void disableMeter(void)
Definition: fieldmeter.cc:36
Definition: meter.h:14
int x_
Definition: meter.h:53
int docaptions_
Definition: meter.h:53
int dolegends_
Definition: meter.h:53
virtual void checkResources(void)
Definition: meter.cc:33
int y_
Definition: meter.h:53
int dousedlegends_
Definition: meter.h:53
int width_
Definition: meter.h:53
char * legend_
Definition: meter.h:55
virtual const char * name(void) const
Definition: meter.h:20
static double scaleValue(double value, char *scale, bool metric)
Definition: meter.cc:67
unsigned long textcolor_
Definition: meter.h:56
const char * legend(void)
Definition: meter.h:27
char * title_
Definition: meter.h:55
XOSView * parent_
Definition: meter.h:52
int height_
Definition: meter.h:53
unsigned long foreground(void)
Definition: xwin.h:53
unsigned long allocColor(const char *name)
Definition: xwin.cc:383
void setForeground(unsigned long pixelvalue)
Definition: xwin.h:38
void drawString(int x, int y, const char *str)
Definition: xwin.h:69
int textHeight(void)
Definition: xwin.h:79
void setStippleN(int n)
Definition: xwin.h:48
void drawRectangle(int x, int y, int width, int height)
Definition: xwin.h:65
int textWidth(const char *str, int n)
Definition: xwin.h:73
const char * getResource(const char *name)
Definition: xwin.cc:362
void clear(void)
Definition: xwin.h:34
void drawFilledRectangle(int x, int y, int width, int height)
Definition: xwin.h:67