source: rtems-graphics-toolkit/fltk-1.1.10/src/Fl_Valuator.cxx @ 513eea1

Last change on this file since 513eea1 was 513eea1, checked in by Joel Sherrill <joel.sherrill@…>, on 01/09/10 at 22:43:24

2010-01-08 Joel Sherrill <joel.sherrill@…>

fltk 1.1.10. imported

  • ORIGIN: Updated.
  • Property mode set to 100644
File size: 4.0 KB
Line 
1//
2// "$Id$"
3//
4// Valuator widget for the Fast Light Tool Kit (FLTK).
5//
6// Copyright 1998-2005 by Bill Spitzak and others.
7//
8// This library is free software; you can redistribute it and/or
9// modify it under the terms of the GNU Library General Public
10// License as published by the Free Software Foundation; either
11// version 2 of the License, or (at your option) any later version.
12//
13// This library is distributed in the hope that it will be useful,
14// but WITHOUT ANY WARRANTY; without even the implied warranty of
15// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16// Library General Public License for more details.
17//
18// You should have received a copy of the GNU Library General Public
19// License along with this library; if not, write to the Free Software
20// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
21// USA.
22//
23// Please report all bugs and problems on the following page:
24//
25//     http://www.fltk.org/str.php
26//
27
28// Base class for sliders and all other one-value "knobs"
29
30#include <FL/Fl.H>
31#include <FL/Fl_Valuator.H>
32#include <FL/math.h>
33#include <stdio.h>
34#include "flstring.h"
35
36Fl_Valuator::Fl_Valuator(int X, int Y, int W, int H, const char* L)
37  : Fl_Widget(X,Y,W,H,L) {
38  align(FL_ALIGN_BOTTOM);
39  when(FL_WHEN_CHANGED);
40  value_ = 0;
41  previous_value_ = 1;
42  min = 0;
43  max = 1;
44  A = 0.0;
45  B = 1;
46}
47
48const double epsilon = 4.66e-10;
49
50void Fl_Valuator::step(double s) {
51  if (s < 0) s = -s;
52  A = rint(s);
53  B = 1;
54  while (fabs(s-A/B) > epsilon && B<=(0x7fffffff/10)) {B *= 10; A = rint(s*B);}
55}
56
57void Fl_Valuator::precision(int p) {
58  A = 1.0;
59  for (B = 1; p--;) B *= 10;
60}
61
62void Fl_Valuator::value_damage() {damage(FL_DAMAGE_EXPOSE);} // by default do partial-redraw
63
64int Fl_Valuator::value(double v) {
65  clear_changed();
66  if (v == value_) return 0;
67  value_ = v;
68  value_damage();
69  return 1;
70}
71
72double Fl_Valuator::softclamp(double v) {
73  int which = (min<=max);
74  double p = previous_value_;
75  if ((v<min)==which && p!=min && (p<min)!=which) return min;
76  else if ((v>max)==which && p!=max && (p>max)!=which) return max;
77  else return v;
78}
79
80// inline void Fl_Valuator::handle_push() {previous_value_ = value_;}
81
82void Fl_Valuator::handle_drag(double v) {
83  if (v != value_) {
84    value_ = v;
85    value_damage();
86    set_changed();
87    if (when() & FL_WHEN_CHANGED) do_callback();
88  }
89}
90
91void Fl_Valuator::handle_release() {
92  if (when()&FL_WHEN_RELEASE) {
93    // insure changed() is off even if no callback is done.  It may have
94    // been turned on by the drag, and then the slider returned to it's
95    // initial position:
96    clear_changed();
97    // now do the callback only if slider in new position or always is on:
98    if (value_ != previous_value_ || when() & FL_WHEN_NOT_CHANGED) {
99      do_callback();
100    }
101  }
102}
103
104double Fl_Valuator::round(double v) {
105  if (A) return rint(v*B/A)*A/B;
106  else return v;
107}
108
109double Fl_Valuator::clamp(double v) {
110  if ((v<min)==(min<=max)) return min;
111  else if ((v>max)==(min<=max)) return max;
112  else return v;
113}
114
115double Fl_Valuator::increment(double v, int n) {
116  if (!A) return v+n*(max-min)/100;
117  if (min > max) n = -n;
118  return (rint(v*B/A)+n)*A/B;
119}
120
121int Fl_Valuator::format(char* buffer) {
122  double v = value();
123  // MRS: THIS IS A HACK - RECOMMEND ADDING BUFFER SIZE ARGUMENT
124  if (!A || !B) return snprintf(buffer, 128, "%g", v);
125
126  // Figure out how many digits are required to correctly format the
127  // value.
128  int i, c = 0;
129  char temp[32];
130  // output a number with many digits after the decimal point. This
131  // seems to be needed to get high precission
132  snprintf(temp, sizeof(temp), "%.12f", A/B);
133  // strip all trailing 0's
134  for (i=strlen(temp)-1; i>0; i--) {
135    if (temp[i]!='0') break;
136  }
137  // count digits until we find the decimal point (or comma or whatever
138  // letter is set in the current locale)
139  for (; i>0; i--, c++) {
140    if (!isdigit(temp[i])) break;
141  }
142
143  // MRS: THIS IS A HACK - RECOMMEND ADDING BUFFER SIZE ARGUMENT
144  return snprintf(buffer, 128, "%.*f", c, v);
145}
146
147//
148// End of "$Id$".
149//
Note: See TracBrowser for help on using the repository browser.