00001 #ifndef SLIDER_IMPLEMENTATION_FILE
00002 #define SLIDER_IMPLEMENTATION_FILE
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
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;
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
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
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
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
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
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
00194
00195
00196 LOG(isprintf("setting slider in value to %d", real_value));
00197
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