Back to index

plt-scheme  4.2.1
Slider.cc
Go to the documentation of this file.
00001 /*                                                      -*- C++ -*-
00002  *
00003  * Purpose: slider panel item
00004  *
00005  * Authors: Markus Holzem and Julian Smart
00006  *
00007  * Copyright: (C) 2004-2009 PLT Scheme Inc.
00008  * Copyright: (C) 1995, AIAI, University of Edinburgh (Julian)
00009  * Copyright: (C) 1995, GNU (Markus)
00010  *
00011  * This program is free software; you can redistribute it and/or modify
00012  * it under the terms of the GNU General Public License as published by
00013  * the Free Software Foundation; either version 2 of the License, or
00014  * (at your option) any later version.
00015  *
00016  * This program is distributed in the hope that it will be useful,
00017  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00018  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00019  * GNU General Public License for more details.
00020  *
00021  * You should have received a copy of the GNU General Public License
00022  * along with this program; if not, write to the Free Software
00023  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
00024  * 02110-1301 USA.
00025  */
00026 
00027 #ifdef __GNUG__
00028 #pragma implementation "Slider.h"
00029 #endif
00030 
00031 #define  Uses_XtIntrinsic
00032 #define  Uses_wxSlider
00033 #include "wx.h"
00034 #define  Uses_TraversingEnforcerWidget
00035 #define  Uses_SliderWidget
00036 #include "widgets.h"
00037 
00038 //-----------------------------------------------------------------------------
00039 // create and destroy button
00040 //-----------------------------------------------------------------------------
00041 
00042 wxSlider::wxSlider(wxPanel *panel, wxFunction func, char *label,
00043                  int _value, int min_value, int max_value, int width,
00044                  int x, int y, long style, wxFont *_font, char *name) : wxItem(font)
00045 {
00046     __type = wxTYPE_SLIDER;
00047 
00048     minimum = maximum = value = 0;
00049 
00050     Create(panel, func, label, _value, min_value, max_value, width, 
00051           x, y, style, name);
00052 }
00053 
00054 Bool wxSlider::Create(wxPanel *panel, wxFunction func, char *label,
00055                     int init_value, int min_value, int max_value, int length,
00056                     int x, int y, long style, char *name)
00057 {
00058     double swidth, sheight; 
00059     Bool vert;
00060     wxWindow_Xintern *ph;
00061     Widget wgt;
00062 
00063     ChainToPanel(panel, style, name);
00064 
00065     if (style & wxVERTICAL_LABEL)
00066       vert = 1;
00067     else if (style & wxHORIZONTAL_LABEL)
00068       vert = 0;
00069     else
00070       vert = (panel->GetLabelPosition() == wxVERTICAL);
00071    
00072     // label = wxGetCtlLabel(label);
00073 
00074     minimum = min_value;
00075     maximum = max_value;
00076 
00077     ph = parent->GetHandle();
00078 
00079     // create frame
00080     wgt = XtVaCreateWidget
00081        (name, xfwfTraversingEnforcerWidgetClass, ph->handle,
00082         XtNlabel,       label,
00083         XtNalignment,   vert ? XfwfTop : XfwfLeft,
00084         XtNbackground,  wxGREY_PIXEL,
00085         XtNforeground,  wxBLACK_PIXEL,
00086         XtNhighlightColor, wxCTL_HIGHLIGHT_PIXEL,
00087         XtNfont,        font->GetInternalFont(),
00088 #ifdef WX_USE_XFT
00089         XtNxfont,       font->GetInternalAAFont(),
00090 #endif
00091         XtNframeType,   XfwfSunken,
00092         XtNframeWidth,  2,
00093         XtNshrinkToFit, TRUE,
00094         NULL);
00095     if (!(style & wxINVISIBLE))
00096       XtManageChild(wgt);
00097     else
00098       XtRealizeWidget(wgt);
00099     X->frame = wgt;
00100     // compute sizes of the slider widget
00101     if (style & (wxHORIZONTAL << 2)) {
00102       swidth = sheight = 20;
00103     } else {
00104       char tempstring[80];
00105       int mxv, mnv;
00106       mxv = abs(max_value); mnv = abs(min_value);
00107       sprintf(tempstring, "-%d", max(mxv, mnv));
00108       GetTextExtent(tempstring, &swidth, &sheight);
00109       swidth += 8; sheight += 8; // shadows and margin
00110     }
00111     if (length <= 0)
00112       length = 100;
00113     // create the slider widget
00114     wgt = XtVaCreateManagedWidget
00115        ("slider", xfwfSlider2WidgetClass, X->frame,
00116         XtNbackground,    wxDARK_GREY_PIXEL,
00117         XtNforeground,    wxBLACK_PIXEL,
00118         XtNthumbColor,    wxGREY_PIXEL,
00119         XtNfont,          font->GetInternalFont(),
00120 #ifdef WX_USE_XFT
00121         XtNxfont,         font->GetInternalAAFont(),
00122 #endif
00123         XtNwidth,         style & wxVERTICAL ? ((int)swidth) : length,
00124         XtNheight,        style & wxVERTICAL ? length : ((int)sheight),
00125         XtNframeType,     XfwfRaised,
00126         XtNframeWidth,    0,
00127         XtNhighlightThickness, 0,
00128         NULL);
00129     X->handle = wgt;
00130     if (style & wxVERTICAL) {
00131        XfwfResizeThumb(X->handle, 1.0, min(0.9,sheight/length));
00132     } else {
00133        XfwfResizeThumb(X->handle, min(0.9, swidth/length), 1.0);
00134     }
00135     SetValue(init_value);
00136     // set data declared in wxItem
00137     callback = func;
00138     XtAddCallback(X->handle, XtNscrollCallback, wxSlider::EventCallback,
00139                 (XtPointer)saferef);
00140     // panel positioning
00141     panel->PositionItem(this, x, y, -1, -1);
00142     AddEventHandlers();
00143 
00144     if (style & wxINVISIBLE)
00145       Show(FALSE);
00146 
00147     return TRUE;
00148 }
00149 
00150 void wxSlider::OnSize(int width, int height)
00151 {
00152   if (style & (wxHORIZONTAL << 2)) {
00153     if (style & wxVERTICAL) {
00154       XfwfResizeThumb(X->handle, 1.0, 0.2);
00155     } else {
00156       XfwfResizeThumb(X->handle, 0.2, 1.0);
00157     }
00158   } else {
00159     double swidth, sheight;
00160     char tempstring[80];
00161     Dimension length;
00162     int mxv, mnv;
00163     mxv = abs(maximum); mnv = abs(minimum);
00164     sprintf(tempstring, "-%d", max(mxv, mnv));
00165     GetTextExtent(tempstring, &swidth, &sheight);
00166     swidth += 8; sheight += 8; // shadows and margin
00167     if (style & wxVERTICAL) {
00168       XtVaGetValues(X->handle, XtNheight, &length, NULL);
00169       if (length > height) length = height;
00170       XfwfResizeThumb(X->handle, 1.0, min(0.9,sheight/length));
00171     } else {
00172       XtVaGetValues(X->handle, XtNwidth, &length, NULL);
00173       if (length > width) length = width;
00174       XfwfResizeThumb(X->handle, min(0.9, swidth/length), 1.0);
00175     }
00176   }
00177 
00178   wxItem::OnSize(width, height);
00179 }
00180 
00181 //-----------------------------------------------------------------------------
00182 // methods to access internal data
00183 //-----------------------------------------------------------------------------
00184 
00185 void wxSlider::SetValue(int new_value)
00186 {
00187     if (minimum <= new_value && new_value <= maximum) {
00188       value = new_value;
00189       if (!(style & (wxHORIZONTAL << 2))) {
00190        char tempstring[80];
00191        sprintf(tempstring, "%d", value);
00192        XtVaSetValues(X->handle, XtNlabel, tempstring, NULL);
00193       }
00194       if (style & wxVERTICAL)
00195        XfwfMoveThumb(X->handle,
00196                     0.0, ((double)value-minimum)/((double)maximum-minimum));
00197       else
00198        XfwfMoveThumb(X->handle,
00199                     ((double)value-minimum)/((double)maximum-minimum), 0.0);
00200     }
00201 }
00202 
00203 void wxSlider::Command(wxCommandEvent *event)
00204 {
00205   ProcessCommand(event);
00206 }
00207 
00208 //-----------------------------------------------------------------------------
00209 // callbacks for xfwfGroupWidgetClass
00210 //-----------------------------------------------------------------------------
00211 
00212 void wxSlider::EventCallback(Widget WXUNUSED(w),
00213                           XtPointer dclient, XtPointer dcall)
00214 {
00215     wxSlider       *slider = (wxSlider *)GET_SAFEREF(dclient);
00216     XfwfScrollInfo *info   = (XfwfScrollInfo*)dcall;
00217     Bool           process = FALSE;
00218     int            new_value = 0;
00219 
00220     if ((slider->style & wxVERTICAL) && (info->flags & XFWF_VPOS)) {
00221        if (info->reason == XfwfSPageUp || info->reason == XfwfSPageDown) {
00222          if (slider->value > slider->minimum) {
00223            new_value = slider->value + ((info->reason == XfwfSPageUp)
00224                                     ? -1
00225                                     : 1);
00226            process = TRUE;
00227            slider->SetValue(new_value);
00228          }
00229        } else {
00230          new_value = (int)(slider->minimum 
00231                          + info->vpos * (slider->maximum-slider->minimum));
00232          process = (new_value != slider->value);
00233        }
00234     } else if (!(slider->style & wxVERTICAL) && (info->flags & XFWF_HPOS)) {
00235        if (info->reason == XfwfSPageLeft || info->reason == XfwfSPageRight) {
00236          if (slider->value < slider->maximum) {
00237            new_value = slider->value + ((info->reason == XfwfSPageLeft)
00238                                     ? -1
00239                                     : 1);
00240            process = TRUE;
00241            slider->SetValue(new_value);
00242          }
00243        } else {
00244          new_value = (int)(slider->minimum
00245                          + info->hpos * (slider->maximum-slider->minimum));
00246          process = (new_value != slider->value);
00247        }
00248     }
00249 
00250     if (process) {
00251        wxCommandEvent *event;
00252 
00253        // set and display new value
00254        slider->value = new_value;
00255        if (!(slider->style & (wxHORIZONTAL << 2))) {
00256          char tempstring[80];
00257          sprintf(tempstring, "%d", new_value);
00258          XtVaSetValues(slider->X->handle, XtNlabel, tempstring, NULL);
00259        }
00260        // process event
00261        event = new wxCommandEvent(wxEVENT_TYPE_SLIDER_COMMAND);
00262        slider->ProcessCommand(event);
00263     }
00264 
00265 #ifdef MZ_PRECISE_GC
00266     XFORM_RESET_VAR_STACK;
00267 #endif
00268 }