slider.cpp

Go to the documentation of this file.
00001 #ifndef SLIDER_IMPLEMENTATION_FILE
00002 #define SLIDER_IMPLEMENTATION_FILE
00003 
00004 /*****************************************************************************\
00005 *                                                                             *
00006 *  Name   : slider                                                            *
00007 *  Author : Chris Koeritz                                                     *
00008 *                                                                             *
00009 *******************************************************************************
00010 * Copyright (c) 1991-$now By Author.  This program is free software; you can  *
00011 * redistribute it and/or modify it under the terms of the GNU General Public  *
00012 * License as published by the Free Software Foundation; either version 2 of   *
00013 * the License or (at your option) any later version.  This is online at:      *
00014 *     http://www.fsf.org/copyleft/gpl.html                                    *
00015 * Please send any updates to: fred@gruntose.com                               *
00016 \*****************************************************************************/
00017 
00018 // Implementation Details:
00019 //
00020 // Methods:
00021 //
00022 //   real_h_or_v(to_translate)
00023 //
00024 //     Returns the real windowing h_or_v needed for our virtual
00025 //     h_or_v.
00026 
00027 #include "slider.h"
00028 
00029 #include <wp_passive/wp_implementation.h>
00030 
00031 #include <math.h>
00032 
00033 #ifdef __XWINDOWS__
00034   #include <Xm/Scale.h>
00035   #include <Xm/ArrowB.h>
00036   #include <Xm/RowColumn.h>
00037 #elif defined(OS_2)
00038 #elif defined(MS_WINDOWS)
00039 #endif
00040 
00041 const int SLIDER_MINIMUM = 0;
00042 const int SLIDER_MAXIMUM = 32767;  // suitable for short ints...
00043 
00044 const double ONE_HALF = 0.5;
00045 
00046 const char *sliderSuffix = "slider";
00047 const char *arrowSuffix = "arrow";
00048 const char *minimum_Suffix = "min";
00049 const char *maximum_Suffix = "max";
00050     
00051 slider::slider(manager &parent, const c_point &origin, const char *name,
00052     slider_orientation h_or_v, double minValue, double maxValue,
00053     double granularity, const color &foreground, const color &background)
00054 : worker(parent, c_rectangle(origin, origin),
00055     create_holder(parent.self(), name, h_or_v),
00056     foreground, background),
00057   slider_w(NIL), maximum_ArrowName(name), minimum_ArrowName(name),
00058   sliderName(name), current_value(minValue), minimum_value(minValue),
00059   maximum_value(maxValue), granularity(granularity)
00060 {
00061   sliderName += sliderSuffix;
00062   minimum_ArrowName += minimum_Suffix;
00063   minimum_ArrowName += arrowSuffix;
00064   maximum_ArrowName += maximum_Suffix;
00065   maximum_ArrowName += arrowSuffix;
00066 
00067   // Note: Xt toolkit checks assertion that minValue is less than maxValue.
00068 
00069   int maximum_Dir, minimum_Dir;
00070 
00071   if (h_or_v == HORIZONTAL_SLIDER) {
00072     maximum_Dir = XmARROW_LEFT;
00073     minimum_Dir = XmARROW_RIGHT;
00074   } else {
00075     maximum_Dir = XmARROW_UP;
00076     minimum_Dir = XmARROW_DOWN;
00077   }
00078 
00079   if (granularity != 0.0) {
00080     /* create left (up) arrow */
00081     argument_list wargs;
00082     wargs.add(XmNarrowDirection, maximum_Dir);
00083     wargs.add(XtNborderWidth, XtArgVal(0));
00084     wargs.add(XmNshadowThickness, XtArgVal(0));
00085     maximum_Arrow = XtCreateManagedWidget
00086       (maximum_ArrowName.s(), xmArrowButtonWidgetClass, self(), wargs.generate(),
00087        wargs.number());
00088     nub temp(maximum_Arrow, maximum_Arrow);
00089     temp.set_foreground(foreground);
00090     temp.set_background(background);
00091     XtAddCallback
00092       (maximum_Arrow, XmNactivateCallback, XtCallbackProc(more_arrow_callback),
00093        XtPointer(this));
00094   }
00095 
00096   /* Create slider bar */
00097   slider_w = create_slider
00098     (self(), sliderName.s(), h_or_v, SLIDER_MINIMUM, SLIDER_MAXIMUM);
00099   nub temp(slider_w, slider_w);
00100   temp.set_foreground(foreground);
00101   temp.set_background(background);
00102 
00103   if (granularity != 0.0) {
00104     /* Create right (down) arrow */
00105     argument_list wargs;
00106     wargs.add(XmNarrowDirection, minimum_Dir);
00107     wargs.add(XtNborderWidth, XtArgVal(0));
00108     wargs.add(XmNshadowThickness, XtArgVal(0));
00109     minimum_Arrow = XtCreateManagedWidget
00110       (minimum_ArrowName.s(), xmArrowButtonWidgetClass, self(),
00111        wargs.generate(), wargs.number());
00112     nub temp(minimum_Arrow, minimum_Arrow);
00113     temp.set_foreground(foreground);
00114     temp.set_background(background);
00115     XtAddCallback
00116       (minimum_Arrow, XmNactivateCallback, XtCallbackProc(less_arrow_callback),
00117        XtPointer(this));
00118   }
00119 
00120   XtManageChild(self());
00121   if (granularity != 0.0) {
00122     XtManageChild(maximum_Arrow);
00123     XtManageChild(minimum_Arrow);
00124   }
00125 }
00126 
00127 slider::~slider()
00128 {
00129   XtRemoveCallback(slider_w, XmNvalueChangedCallback,
00130     (XtCallbackProc)slider_callback, XtPointer(this));
00131   XtRemoveCallback(slider_w, XmNdragCallback,
00132     (XtCallbackProc)slider_callback, XtPointer(this));
00133   if (granularity != 0.0) {
00134     XtRemoveCallback
00135       (maximum_Arrow, XmNactivateCallback, XtCallbackProc(more_arrow_callback),
00136        XtPointer(this));
00137     XtRemoveCallback
00138       (minimum_Arrow, XmNactivateCallback, XtCallbackProc(less_arrow_callback),
00139        XtPointer(this));
00140   }
00141 }
00142 
00143 window_handle slider::create_holder
00144   (window_handle parent, const char *name, slider_orientation h_or_v)
00145 {
00146   /* Create a row columun widget to hold the arrow slider components */
00147   argument_list wargs;
00148   wargs.add
00149     (XmNorientation, real_orientation(h_or_v));
00150   window_handle holder = XtCreateManagedWidget
00151     (name, xmRowColumnWidgetClass, parent, wargs.generate(), wargs.number());
00152   nub temp(holder, holder);
00153   color f = foreground();
00154   color b = background();
00155   temp.set_foreground(f);
00156   temp.set_background(b);
00157   return holder;
00158 }
00159 
00160 window_handle slider::create_slider
00161   (window_handle parent, const char *name, slider_orientation h_or_v, int minValue,
00162    int maxValue)
00163 {
00164   argument_list wargs;
00165   wargs.add(XmNminimum, minValue);
00166   wargs.add(XmNmaximum, maxValue);
00167   wargs.add(XmNorientation, real_orientation(h_or_v));
00168   wargs.add(XtNborderWidth, XtArgVal(0));
00169   window_handle w = XtCreateManagedWidget
00170     (name, xmScaleWidgetClass, parent, wargs.generate(), wargs.number());
00171   nub temp(w, w);
00172   color f = foreground();
00173   color b = background();
00174   temp.set_foreground(f);
00175   temp.set_background(b);
00176 
00177   XtAddCallback(w, XmNvalueChangedCallback, 
00178     (XtCallbackProc)slider_callback, XtPointer(this));
00179   XtAddCallback(w, XmNdragCallback,
00180     (XtCallbackProc)slider_callback, XtPointer(this));
00181 
00182   XtManageChild(w);
00183   return w;
00184 }
00185 
00186 void slider::value(double value, bool trigger_event)
00187 {
00188   FUNCDEF("value");
00189   check_value(value);
00190 
00191   double percent = (current_value - minimum_value) / (maximum_value - minimum_value);
00192   int real_value = int(percent * ((double) SLIDER_MAXIMUM));
00193 //  int integerValue = (int) ((double) floor((double) (intRangeVal + ONE_HALF)));
00194 //  intCurrent_Value = integerValue;
00195 
00196 LOG(isprintf("setting slider in value to %d", real_value));
00197   // set the value on the widget
00198   argument_list wargs;
00199   wargs.add(XmNvalue, real_value);
00200   XtSetValues(slider_w, wargs.generate(), wargs.number());
00201 
00202   if (trigger_event) slider_moved_event(current_value);
00203 }
00204 
00205 void slider::check_value(double value)
00206 {
00207   FUNCDEF("check_value");
00208   if ( (value < minimum_value) || (value > maximum_value) ) {
00209     continuable_error(class_name(), func, isprintf("warning: the value is not within the selectable range of the slider (%f passed, %f is the max)", value, maximum_value).s());
00210   }
00211 
00212   if (value < minimum_value) value = minimum_value;
00213   if (value > maximum_value) value = maximum_value;
00214 
00215   double rounded = round_to_granularity(value, minimum_value, granularity);
00216 
00217   current_value = rounded;
00218 }
00219 
00220 double slider::value() { return current_value; }
00221 
00222 void slider::less_arrow_callback(window_handle, slider *the_slider, XmAnyCallbackStruct *)
00223 {
00224   FUNCDEF("less_arrow_callback");
00225 LOG("less arrow");
00226 LOG(isprintf("curr=%d, min=%d", the_slider->current_value, the_slider->minimum_value));
00227   if (the_slider->current_value - the_slider->granularity
00228       < the_slider->minimum_value)
00229     the_slider->value(the_slider->minimum_value, true);
00230   else
00231     the_slider->value(the_slider->current_value - the_slider->granularity, true);
00232 }
00233 
00234 void slider::more_arrow_callback(window_handle, slider *the_slider, XmAnyCallbackStruct *)
00235 {
00236   FUNCDEF("more_arrow_callback");
00237 LOG(isprintf("more arrow: curr=%d, max=%d", the_slider->current_value, the_slider->maximum_value));
00238   if (the_slider->current_value + the_slider->granularity
00239       > the_slider->maximum_value)
00240     the_slider->value(the_slider->maximum_value, true);
00241   else
00242     the_slider->value(the_slider->current_value + the_slider->granularity, true);
00243 }
00244 
00245 void slider::slider_callback(window_handle , slider *me, XmScaleCallbackStruct *call_data)
00246 {
00247   FUNCDEF("slider_callback");
00248 LOG("slider callback:");
00249   me->current_value = call_data->value;
00250 LOG(isprintf("at value=%d", me->current_value));
00251   double percent = (me->current_value / double(SLIDER_MAXIMUM));
00252 LOG(isprintf(" at percent=%d", percent));
00253   double unrounded = me->minimum_value
00254     + (percent * (me->maximum_value - me->minimum_value));
00255 LOG(isprintf(" unrounded=%d", unrounded));
00256   me->current_value = me->round_to_granularity
00257     (unrounded, me->minimum_value, me->granularity);
00258   me->slider_moved_event(me->current_value);
00259 }
00260 
00261 double slider::round_to_granularity
00262   (double unrounded, double minimum_value, double granularity)
00263 {
00264   return floor( (unrounded - minimum_value) / granularity + ONE_HALF) *
00265      granularity + minimum_value;
00266 }
00267 
00268 void slider::slider_moved_event(double value)
00269 {
00270   FUNCDEF("slider_moved_event");
00271   LOG(isprintf("slider got moved to %d.", value));
00272 }
00273 
00274 #ifdef __XWINDOWS__
00275 int slider::real_orientation(slider_orientation to_translate)
00276   { return (to_translate == HORIZONTAL_SLIDER)? XmHORIZONTAL : XmVERTICAL; }
00277 #elif defined(OS_2)
00278 #elif defined(MS_WINDOWS)
00279 #endif
00280 
00281 
00282 #endif //SLIDER_IMPLEMENTATION_FILE
00283 

Generated on Fri Nov 28 04:29:04 2008 for HOOPLE Libraries by  doxygen 1.5.1