TGDoubleSlider.cxx

Go to the documentation of this file.
00001 // @(#)root/gui:$Id: TGDoubleSlider.cxx 35582 2010-09-22 13:38:27Z bellenot $
00002 // Author: Reiner Rohlfs   30/09/98
00003 
00004 /*************************************************************************
00005  * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers.               *
00006  * All rights reserved.                                                  *
00007  *                                                                       *
00008  * For the licensing terms see $ROOTSYS/LICENSE.                         *
00009  * For the list of contributors see $ROOTSYS/README/CREDITS.             *
00010  *************************************************************************/
00011 /**************************************************************************
00012 
00013     This source is based on Xclass95, a Win95-looking GUI toolkit.
00014     Copyright (C) 1996, 1997 David Barth, Ricky Ralston, Hector Peraza.
00015 
00016     Xclass95 is free software; you can redistribute it and/or
00017     modify it under the terms of the GNU Library General Public
00018     License as published by the Free Software Foundation; either
00019     version 2 of the License, or (at your option) any later version.
00020 
00021 **************************************************************************/
00022 
00023 //////////////////////////////////////////////////////////////////////////
00024 //                                                                      //
00025 // TGDoubleSlider, TGDoubleVSlider and TGDoubleHSlider                  //
00026 //                                                                      //
00027 // DoubleSlider widgets allow easy selection of a min and a max value   //
00028 // out of a range.                                                      //
00029 // DoubleSliders can be either horizontal or vertical oriented and      //
00030 // there is a choice of three different types of tick marks.            //
00031 //                                                                      //
00032 // To change the min value press the mouse near to the left / bottom    //
00033 // edge of the slider.                                                  //
00034 // To change the max value press the mouse near to the right / top      //
00035 // edge of the slider.                                                  //
00036 // To change both values simultaneously press the mouse near to the     //
00037 // center of the slider.                                                //
00038 //                                                                      //
00039 // TGDoubleSlider is an abstract base class. Use the concrete           //
00040 // TGDoubleVSlider and TGDoubleHSlider.                                 //
00041 //                                                                      //
00042 // Dragging the slider will generate the event:                         //
00043 // kC_VSLIDER, kSL_POS, slider id, 0  (for vertical slider)             //
00044 // kC_HSLIDER, kSL_POS, slider id, 0  (for horizontal slider)           //
00045 //                                                                      //
00046 // Pressing the mouse will generate the event:                          //
00047 // kC_VSLIDER, kSL_PRESS, slider id, 0  (for vertical slider)           //
00048 // kC_HSLIDER, kSL_PRESS, slider id, 0  (for horizontal slider)         //
00049 //                                                                      //
00050 // Releasing the mouse will generate the event:                         //
00051 // kC_VSLIDER, kSL_RELEASE, slider id, 0  (for vertical slider)         //
00052 // kC_HSLIDER, kSL_RELEASE, slider id, 0  (for horizontal slider)       //
00053 //                                                                      //
00054 // Use the functions GetMinPosition(), GetMaxPosition() and             //
00055 // GetPosition() to retrieve the position of the slider.                //
00056 //                                                                      //
00057 //////////////////////////////////////////////////////////////////////////
00058 
00059 #include "TGDoubleSlider.h"
00060 #include "TGPicture.h"
00061 #include "Riostream.h"
00062 #include "TSystem.h"
00063 
00064 
00065 ClassImp(TGDoubleSlider)
00066 ClassImp(TGDoubleVSlider)
00067 ClassImp(TGDoubleHSlider)
00068 
00069 //______________________________________________________________________________
00070 TGDoubleSlider::TGDoubleSlider(const TGWindow *p, UInt_t w, UInt_t h, UInt_t type, Int_t id,
00071                                UInt_t options, ULong_t back,
00072                                Bool_t reversed, Bool_t mark_ends)
00073    : TGFrame(p, w, h, options, back)
00074 {
00075    // Slider constructor.
00076 
00077    fSliderPic = 0;
00078 
00079    fWidgetId    = id;
00080    fWidgetFlags = kWidgetWantFocus;
00081    fMsgWindow   = p;
00082 
00083    fScaleType = type;
00084    fScale = 10;
00085    fMove = 0;
00086 
00087    fReversedScale = reversed;
00088    fMarkEnds = mark_ends;
00089 
00090    gVirtualX->GrabButton(fId, kAnyButton, kAnyModifier,
00091                          kButtonPressMask | kButtonReleaseMask |
00092                          kPointerMotionMask, kNone, kNone);
00093    AddInput(kPointerMotionMask);
00094    SetWindowName();
00095 }
00096 
00097 //______________________________________________________________________________
00098 void TGDoubleSlider::FixBounds(Float_t &min, Float_t &max)
00099 {
00100    // Avoid boundaries to be equal.
00101 
00102    if (min > max) min = max;
00103 
00104    Float_t eps = 1e-6;
00105    if (max - min < eps) {
00106       if (max == 0)
00107          max += eps;
00108       else
00109          max += max*eps;
00110       if (min == 0)
00111          min -= eps;
00112       else
00113          min -= min*eps;
00114    }
00115 }
00116 
00117 //______________________________________________________________________________
00118 TString TGDoubleSlider::GetSString() const
00119 {
00120    // Returns the slider type as a string - used in SavePrimitive()
00121 
00122    TString stype;
00123 
00124    if (fScaleType) {
00125       if (fScaleType & kDoubleScaleNo)  {
00126          if (stype.Length() == 0)
00127             stype  = "kDoubleScaleNo";
00128          else
00129             stype += " | kDoubleScaleNo";
00130       }
00131       if (fScaleType & kDoubleScaleDownRight) {
00132          if (stype.Length() == 0)
00133             stype  = "kDoubleScaleDownRight";
00134          else
00135             stype += " | kDoubleScaleDownRight";
00136       }
00137       if (fScaleType & kDoubleScaleBoth) {
00138          if (stype.Length() == 0)
00139             stype  = "kDoubleScaleBoth";
00140          else
00141             stype += " | kDoubleScaleBoth";
00142       }
00143    }
00144    return stype;
00145 }
00146 
00147 //______________________________________________________________________________
00148 void TGDoubleSlider::ChangeCursor(Event_t *event)
00149 {
00150    // Change the cursor shape depending on the slider area.
00151 
00152    static Cursor_t topCur = kNone, leftCur = kNone;
00153    static Cursor_t botCur = kNone, rightCur = kNone;
00154    Int_t hw = 0, wh = 0, xy = 0, yx = 0;
00155    Cursor_t minCur = kNone, maxCur = kNone;
00156 
00157    if (topCur == kNone)
00158       topCur    = gVirtualX->CreateCursor(kTopSide);
00159    if (leftCur == kNone)
00160       leftCur   = gVirtualX->CreateCursor(kLeftSide);
00161    if (botCur == kNone)
00162       botCur    = gVirtualX->CreateCursor(kBottomSide);
00163    if (rightCur == kNone)
00164       rightCur  = gVirtualX->CreateCursor(kRightSide);
00165    if (GetOptions() & kVerticalFrame) {
00166       hw = (Int_t)fWidth;
00167       wh = (Int_t)fHeight;
00168       xy = (Int_t)event->fX;
00169       yx = (Int_t)event->fY;
00170       minCur = topCur;
00171       maxCur = botCur;
00172    }
00173    else if (GetOptions() & kHorizontalFrame) {
00174       hw  = (Int_t)fHeight;
00175       wh  = (Int_t)fWidth;
00176       xy  = (Int_t)event->fY;
00177       yx  = (Int_t)event->fX;
00178       minCur = leftCur;
00179       maxCur = rightCur;
00180    }
00181    else return;
00182 
00183    Int_t relMin = (Int_t)((wh-16) * (fSmin - fVmin) / (fVmax - fVmin)) + 1;
00184    Int_t relMax = (Int_t)((wh-16) * (fSmax - fVmin) / (fVmax - fVmin) + 15);
00185    // constrain to the slider width
00186    if (xy > hw/2-7 && xy < hw/2+7 && fMove != 3) {
00187       // if the mouse pointer is in the top resizing zone,
00188       // and we are not already moving the the bottom side,
00189       // set the cursor shape as TopSide
00190       if ((yx <= (relMax - relMin) / 4 + relMin) &&
00191           (yx >= relMin) && (fMove != 2))
00192          gVirtualX->SetCursor(fId, minCur);
00193       // if the mouse pointer is in the bottom resizing zone,
00194       // and we are not already moving the the top side,
00195       // set the cursor shape as BottomSide
00196       else if ((yx >= (relMax - relMin) / 4 * 3 + relMin) &&
00197                (yx <= relMax) && (fMove != 1))
00198          gVirtualX->SetCursor(fId, maxCur);
00199       // if we are not moving any side, restore the cursor
00200       else if ((fMove < 1) || (fMove > 2))
00201          gVirtualX->SetCursor(fId, kNone);
00202    }
00203    // if we are not inside the slider, and not moving any side,
00204    // restore the cursor
00205    else if ((fMove < 1) || (fMove > 2))
00206       gVirtualX->SetCursor(fId, kNone);
00207 }
00208 
00209 //______________________________________________________________________________
00210 TGDoubleVSlider::TGDoubleVSlider(const TGWindow *p, UInt_t h, UInt_t type, Int_t id,
00211                                  UInt_t options, ULong_t back,
00212                                  Bool_t reversed, Bool_t mark_ends)
00213     : TGDoubleSlider(p, kDoubleSliderWidth, h, type, id, options, back,
00214                      reversed, mark_ends)
00215 {
00216    // Create a vertical slider widget.
00217 
00218    fSliderPic = fClient->GetPicture("sliderv.xpm");
00219 
00220    if (!fSliderPic)
00221       Error("TGDoubleVSlider", "sliderv.xpm not found");
00222    // set initial values
00223    fSmin = h/8*3; fSmax = h/8*5; fVmin = 0; fVmax = h;
00224    FixBounds(fVmin, fVmax);
00225    SetWindowName();
00226 }
00227 
00228 //______________________________________________________________________________
00229 TGDoubleVSlider::~TGDoubleVSlider()
00230 {
00231    // Delete vertical slider widget.
00232 
00233    if (fSliderPic) fClient->FreePicture(fSliderPic);
00234 }
00235 
00236 //______________________________________________________________________________
00237 void TGDoubleVSlider::DoRedraw()
00238 {
00239    // Redraw vertical slider widget.
00240 
00241    FixBounds(fVmin, fVmax);
00242 
00243    // cleanup the drawable
00244    gVirtualX->ClearWindow(fId);
00245 
00246    if (fSmin < fVmin) fSmin = fVmin;
00247    if (fSmax < fVmin) fSmax = fVmin;
00248    if (fSmin > fVmax) fSmin = fVmax;
00249    if (fSmax > fVmax) fSmax = fVmax;
00250    if (fSmin > fSmax) fSmin = fSmax = (fSmin + fSmax) / 2;
00251 
00252    int relMin = (int)((fHeight-16) * (fSmin - fVmin) / (fVmax - fVmin)) + 1;
00253    int relMax = (int)((fHeight-16) * (fSmax - fVmin) / (fVmax - fVmin) + 15);
00254 
00255    gVirtualX->DrawLine(fId, GetHilightGC()(), fWidth/2-6, relMin, fWidth/2+5, relMin);
00256    gVirtualX->DrawLine(fId, GetHilightGC()(), fWidth/2-6, relMin, fWidth/2-6, relMax);
00257    gVirtualX->DrawLine(fId, GetBlackGC()(),   fWidth/2+5, relMax, fWidth/2-6, relMax);
00258    gVirtualX->DrawLine(fId, GetBlackGC()(),   fWidth/2+5, relMax, fWidth/2+5, relMin);
00259 
00260    if (relMin-1 > 8) {
00261       gVirtualX->DrawLine(fId, GetShadowGC()(),  fWidth/2-1, 8, fWidth/2-1, relMin-1);
00262       gVirtualX->DrawLine(fId, GetHilightGC()(), fWidth/2+1, 8, fWidth/2+1, relMin-1);
00263       gVirtualX->DrawLine(fId, GetBlackGC()(),   fWidth/2,   8, fWidth/2,   relMin-1);
00264    }
00265    if (relMax+1 < (int)fHeight-8) {
00266       gVirtualX->DrawLine(fId, GetShadowGC()(),  fWidth/2-1, relMax+1, fWidth/2-1, fHeight-8);
00267       gVirtualX->DrawLine(fId, GetHilightGC()(), fWidth/2+1, relMax+1, fWidth/2+1, fHeight-8);
00268       gVirtualX->DrawLine(fId, GetBlackGC()(),   fWidth/2,   relMax+1, fWidth/2,   fHeight-8);
00269    }
00270 
00271    // check scale
00272    if (fScale == 1) fScale++;
00273    if (fScale * 2 > (int)fHeight) fScale = 0;
00274    if (fScale > 0 && !(fScaleType & kDoubleScaleNo)) {
00275       int lines = ((int)fHeight-16) / fScale;
00276       int remain = ((int)fHeight-16) % fScale;
00277       if (lines < 1) lines = 1;
00278       for (int i = 0; i <= lines; i++) {
00279          int y = i * fScale + (i * remain) / lines;
00280          gVirtualX->DrawLine(fId, GetBlackGC()(), fWidth/2+8, y+7, fWidth/2+10, y+7);
00281          if ((fScaleType & kDoubleScaleBoth))
00282             gVirtualX->DrawLine(fId, GetBlackGC()(), fWidth/2-9, y+7, fWidth/2-11, y+7);
00283       }
00284    }
00285 
00286    if (fSliderPic) {
00287       Int_t xpos = (fWidth/2) - (fSliderPic->GetWidth()/2);
00288       Int_t ypos = relMin + 2;
00289       fSliderPic->Draw(fId, GetBckgndGC()(), xpos, ypos);
00290       ypos = relMax - fSliderPic->GetHeight() - 2;
00291       fSliderPic->Draw(fId, GetBckgndGC()(), xpos, ypos);
00292    }
00293    if (fMarkEnds) {
00294       // Draw scaling zones.
00295       int y1 = (relMax - relMin) / 4 + relMin;
00296       int y2 = (relMax - relMin) / 4 * 3 + relMin;
00297       gVirtualX->DrawLine(fId, GetBlackGC()(), fWidth/2-6, y1, fWidth/2+5, y1);
00298       gVirtualX->DrawLine(fId, GetBlackGC()(), fWidth/2-6, y2, fWidth/2+5, y2);
00299    }
00300 }
00301 
00302 //______________________________________________________________________________
00303 Bool_t TGDoubleVSlider::HandleButton(Event_t *event)
00304 {
00305    // Handle mouse button event in vertical slider.
00306 
00307    if (event->fType == kButtonPress && event->fCode == kButton1) {
00308       // constrain to the slider width
00309       if (event->fX < (Int_t)fWidth/2-7 || event->fX > (Int_t)fWidth/2+7) {
00310          return kTRUE;
00311       }
00312       fPressPoint = event->fY;
00313       fPressSmin  = fSmin;
00314       fPressSmax  = fSmax;
00315 
00316       int relMin = (int)((fHeight-16) * (fSmin - fVmin) / (fVmax - fVmin)) + 1;
00317       int relMax = (int)((fHeight-16) * (fSmax - fVmin) / (fVmax - fVmin) + 15);
00318       if (fPressPoint < (relMax - relMin) / 4 + relMin)
00319          // move only min value
00320          fMove = 1;
00321       else if (fPressPoint > (relMax - relMin) / 4 * 3 + relMin)
00322          // move only max value
00323          fMove = 2;
00324       else
00325          // move min and max value
00326          fMove = 3;
00327 
00328       SendMessage(fMsgWindow, MK_MSG(kC_VSLIDER, kSL_PRESS), fWidgetId, 0);
00329       fClient->ProcessLine(fCommand, MK_MSG(kC_VSLIDER, kSL_PRESS), fWidgetId, 0);
00330       Pressed();
00331 
00332       // last argument kFALSE forces all specified events to this window
00333       gVirtualX->GrabPointer(fId, kButtonPressMask | kButtonReleaseMask |
00334                              kPointerMotionMask, kNone, kNone,
00335                              kTRUE, kFALSE);
00336    } else if (event->fType == kButtonRelease && event->fCode == kButton1) {
00337       SendMessage(fMsgWindow, MK_MSG(kC_VSLIDER, kSL_RELEASE), fWidgetId, 0);
00338       fClient->ProcessLine(fCommand, MK_MSG(kC_VSLIDER, kSL_RELEASE), fWidgetId, 0);
00339       Released();
00340       fMove = 0;
00341 
00342       gVirtualX->GrabPointer(0, 0, 0, 0, kFALSE);  // ungrab pointer
00343    } else
00344       fMove = 0;
00345 
00346    return kTRUE;
00347 }
00348 
00349 //______________________________________________________________________________
00350 Bool_t TGDoubleVSlider::HandleMotion(Event_t *event)
00351 {
00352    // Handle mouse motion event in vertical slider.
00353 
00354    ChangeCursor(event);
00355    if (fMove == 0) return kTRUE;
00356 
00357    static Long64_t was = gSystem->Now();
00358    Long64_t now = gSystem->Now();
00359 
00360    if ((now-was) < 50) return kTRUE;
00361    was = now;
00362 
00363    int       diff;
00364    Float_t   oldMin, oldMax;
00365 
00366    diff    = event->fY - fPressPoint;
00367    oldMin  = fSmin;
00368    oldMax  = fSmax;
00369 
00370    if (fMove == 1) {
00371       // change of min value
00372       fSmin = fPressSmin + diff * (fVmax - fVmin) / (fHeight-16);
00373       if (fSmin < fVmin) fSmin = fVmin;
00374       if (fSmin > fSmax) fSmin = fSmax;
00375    } else if (fMove == 2) {
00376       // change of max value
00377       fSmax = fPressSmax + diff * (fVmax - fVmin) / (fHeight-16);
00378       if (fSmax > fVmax) fSmax = fVmax;
00379       if (fSmax < fSmin) fSmax = fSmin;
00380    } else if (fMove == 3) {
00381       // change of min and of max value
00382       Float_t logicalDiff;
00383       logicalDiff = diff * (fVmax - fVmin) / (fHeight-16);
00384       if (fPressSmax + logicalDiff > fVmax)
00385          logicalDiff = fVmax - fPressSmax;
00386       if (fPressSmin + logicalDiff < fVmin)
00387          logicalDiff = fVmin - fPressSmin;
00388       fSmax = fPressSmax + logicalDiff;
00389       fSmin = fPressSmin + logicalDiff;
00390    }
00391 
00392    // check if position has changed
00393    if (fMove != 0 && (fSmax != oldMax || fSmin != oldMin)) {
00394       fClient->NeedRedraw(this);
00395       SendMessage(fMsgWindow, MK_MSG(kC_VSLIDER, kSL_POS), fWidgetId, 0);
00396       fClient->ProcessLine(fCommand, MK_MSG(kC_VSLIDER, kSL_POS), fWidgetId, 0);
00397       PositionChanged();
00398    }
00399    return kTRUE;
00400 }
00401 
00402 //______________________________________________________________________________
00403 TGDoubleHSlider::TGDoubleHSlider(const TGWindow *p, UInt_t w, UInt_t type, Int_t id,
00404                                  UInt_t options, ULong_t back,
00405                                  Bool_t reversed, Bool_t mark_ends)
00406     : TGDoubleSlider(p, w, kDoubleSliderHeight, type, id, options, back,
00407                      reversed, mark_ends)
00408 {
00409    // Create horizontal slider widget.
00410 
00411    fSliderPic = fClient->GetPicture("sliderh.xpm");
00412 
00413    if (!fSliderPic)
00414       Error("TGDoubleHSlider", "sliderh.xpm not found");
00415    // set initial values
00416    fSmin = w/8*3; fSmax = w/8*5; fVmin = 0; fVmax = w;
00417    FixBounds(fVmin, fVmax);
00418    SetWindowName();
00419 }
00420 
00421 //______________________________________________________________________________
00422 TGDoubleHSlider::~TGDoubleHSlider()
00423 {
00424    // Delete a horizontal slider widget.
00425 
00426    if (fSliderPic) fClient->FreePicture(fSliderPic);
00427 }
00428 
00429 //______________________________________________________________________________
00430 void TGDoubleHSlider::DoRedraw()
00431 {
00432    // Redraw horizontal slider widget.
00433 
00434    FixBounds(fVmin, fVmax);
00435 
00436    // cleanup drawable
00437    gVirtualX->ClearWindow(fId);
00438 
00439    if (fSmin < fVmin) fSmin = fVmin;
00440    if (fSmax > fVmax) fSmax = fVmax;
00441    if (fSmin > fSmax) fSmin = fSmax = (fSmin + fSmax) / 2;
00442 
00443    int relMin = (int)((fWidth-16) * (fSmin - fVmin) / (fVmax - fVmin)) + 1;
00444    int relMax = (int)((fWidth-16) * (fSmax - fVmin) / (fVmax - fVmin) + 15);
00445 
00446    gVirtualX->DrawLine(fId, GetHilightGC()(), relMin, fHeight/2-6, relMin, fHeight/2+5);
00447    gVirtualX->DrawLine(fId, GetHilightGC()(), relMax, fHeight/2-6, relMin, fHeight/2-6);
00448    gVirtualX->DrawLine(fId, GetBlackGC()(),   relMax, fHeight/2+5, relMax, fHeight/2-6);
00449    gVirtualX->DrawLine(fId, GetBlackGC()(),   relMin, fHeight/2+5, relMax, fHeight/2+5);
00450 
00451    if (relMin-1 > 8) {
00452       gVirtualX->DrawLine(fId, GetShadowGC()(),  8, fHeight/2-1, relMin-1, fHeight/2-1);
00453       gVirtualX->DrawLine(fId, GetHilightGC()(), 8, fHeight/2+1, relMin-1, fHeight/2+1);
00454       gVirtualX->DrawLine(fId, GetBlackGC()(),   8, fHeight/2,   relMin-1, fHeight/2);
00455    }
00456    if (relMax+1 < (int)fWidth-8) {
00457       gVirtualX->DrawLine(fId, GetShadowGC()(),  relMax+1, fHeight/2-1, fWidth-8, fHeight/2-1);
00458       gVirtualX->DrawLine(fId, GetHilightGC()(), relMax+1, fHeight/2+1, fWidth-8, fHeight/2+1);
00459       gVirtualX->DrawLine(fId, GetBlackGC()(),   relMax+1, fHeight/2,   fWidth-8, fHeight/2);
00460    }
00461 
00462    if (fScale == 1) fScale++;
00463    if (fScale * 2 > (int)fWidth) fScale = 0;
00464    if (fScale > 0 && !(fScaleType & kDoubleScaleNo)) {
00465       int lines = ((int)fWidth-16) / fScale;
00466       int remain = ((int)fWidth-16) % fScale;
00467       if (lines < 1) lines = 1;
00468       for (int i = 0; i <= lines; i++) {
00469          int x = i * fScale + (i * remain) / lines;
00470          gVirtualX->DrawLine(fId, GetBlackGC()(), x+7, fHeight/2+8, x+7, fHeight/2+10);
00471          if ((fScaleType & kDoubleScaleBoth))
00472             gVirtualX->DrawLine(fId, GetBlackGC()(), x+7, fHeight/2-9, x+7, fHeight/2-11);
00473       }
00474    }
00475 
00476    if (fSliderPic) {
00477       Int_t ypos = (fHeight/2) - (fSliderPic->GetHeight()/2);
00478       Int_t xpos = relMin + 2;
00479       fSliderPic->Draw(fId, GetBckgndGC()(), xpos, ypos);
00480       xpos = relMax - fSliderPic->GetWidth() - 2;
00481       fSliderPic->Draw(fId, GetBckgndGC()(), xpos, ypos);
00482    }
00483    if (fMarkEnds) {
00484       // Draw scaling zones.
00485       int x1 = (relMax - relMin) / 4 + relMin;
00486       int x2 = (relMax - relMin) / 4 * 3 + relMin;
00487       gVirtualX->DrawLine(fId, GetBlackGC()(), x1, fHeight/2-6, x1, fHeight/2+5);
00488       gVirtualX->DrawLine(fId, GetBlackGC()(), x2, fHeight/2-6, x2, fHeight/2+5);
00489    }
00490 }
00491 
00492 //______________________________________________________________________________
00493 Bool_t TGDoubleHSlider::HandleButton(Event_t *event)
00494 {
00495    // Handle mouse button event in horizontal slider widget.
00496 
00497    if (event->fType == kButtonPress && event->fCode == kButton1) {
00498       // constrain to the slider height
00499       if (event->fY < (Int_t)fHeight/2-7 || event->fY > (Int_t)fHeight/2+7) {
00500          return kTRUE;
00501       }
00502       fPressPoint = event->fX;
00503       fPressSmin  = fSmin;
00504       fPressSmax  = fSmax;
00505 
00506       int relMin = (int)((fWidth-16) * (fSmin - fVmin) / (fVmax - fVmin)) + 1;
00507       int relMax = (int)((fWidth-16) * (fSmax - fVmin) / (fVmax - fVmin) + 15);
00508       if (fPressPoint < (relMax - relMin) / 4 + relMin)
00509          // move only min value
00510          fMove = 1;
00511       else if (fPressPoint > (relMax - relMin) / 4 * 3 + relMin)
00512          // move only max value
00513          fMove = 2;
00514       else
00515          // move min and max value
00516          fMove = 3;
00517 
00518       SendMessage(fMsgWindow, MK_MSG(kC_HSLIDER, kSL_PRESS), fWidgetId, 0);
00519       fClient->ProcessLine(fCommand, MK_MSG(kC_HSLIDER, kSL_PRESS), fWidgetId, 0);
00520       Pressed();
00521 
00522       // last argument kFALSE forces all specified events to this window
00523       gVirtualX->GrabPointer(fId, kButtonPressMask | kButtonReleaseMask |
00524                              kPointerMotionMask, kNone, kNone,
00525                              kTRUE, kFALSE);
00526    } else if (event->fType == kButtonRelease && event->fCode == kButton1) {
00527       SendMessage(fMsgWindow, MK_MSG(kC_HSLIDER, kSL_RELEASE), fWidgetId, 0);
00528       fClient->ProcessLine(fCommand, MK_MSG(kC_HSLIDER, kSL_RELEASE), fWidgetId, 0);
00529       Released();
00530       fMove = 0;
00531 
00532       gVirtualX->GrabPointer(0, 0, 0, 0, kFALSE);  // ungrab pointer
00533    } else
00534       fMove = 0;
00535 
00536    return kTRUE;
00537 }
00538 
00539 //______________________________________________________________________________
00540 Bool_t TGDoubleHSlider::HandleMotion(Event_t *event)
00541 {
00542    // Handle mouse motion event in horizontal slide widget.
00543 
00544    ChangeCursor(event);
00545    if (fMove == 0) return kTRUE;
00546 
00547    static Long64_t was = gSystem->Now();
00548    Long64_t now = gSystem->Now();
00549 
00550    if ((now-was) < 50) return kTRUE;
00551    was = now;
00552 
00553    int     diff;
00554    Float_t oldMin, oldMax;
00555 
00556    diff    = event->fX - fPressPoint;
00557    oldMin  = fSmin;
00558    oldMax  = fSmax;
00559 
00560    if (fMove == 1) {
00561       // change of min value
00562       fSmin = fPressSmin + diff * (fVmax - fVmin) / (fWidth-16);
00563       if (fSmin < fVmin) fSmin = fVmin;
00564       if (fSmin > fSmax) fSmin = fSmax;
00565    } else if (fMove == 2) {
00566       // change of max value
00567       fSmax = fPressSmax + diff * (fVmax - fVmin) / (fWidth-16);
00568       if (fSmax > fVmax) fSmax = fVmax;
00569       if (fSmax < fSmin) fSmax = fSmin;
00570    } else if (fMove == 3) {
00571       // change of min and of max value
00572       Float_t logicalDiff;
00573       logicalDiff = diff * (fVmax - fVmin) / (fWidth-16);
00574       if (fPressSmax + logicalDiff > fVmax)
00575          logicalDiff = fVmax - fPressSmax;
00576       if (fPressSmin + logicalDiff < fVmin)
00577          logicalDiff = fVmin - fPressSmin;
00578       fSmax = fPressSmax + logicalDiff;
00579       fSmin = fPressSmin + logicalDiff;
00580    }
00581 
00582    // check if position has changed
00583    if (fMove != 0 && (fSmax != oldMax || fSmin != oldMin)) {
00584       fClient->NeedRedraw(this);
00585       SendMessage(fMsgWindow, MK_MSG(kC_HSLIDER, kSL_POS), fWidgetId, 0);
00586       fClient->ProcessLine(fCommand, MK_MSG(kC_HSLIDER, kSL_POS), fWidgetId, 0);
00587       PositionChanged();
00588    }
00589    return kTRUE;
00590 }
00591 
00592 //______________________________________________________________________________
00593 void TGDoubleHSlider::SavePrimitive(ostream &out, Option_t *option /*= ""*/)
00594 {
00595     // Save an horizontal slider as a C++ statement(s) on output stream out.
00596 
00597    SaveUserColor(out, option);
00598 
00599    out <<"   TGDoubleHSlider *";
00600    out << GetName() << " = new TGDoubleHSlider(" << fParent->GetName()
00601        << "," << GetWidth() << ",";
00602    out << GetSString() << "," << WidgetId() << ",";
00603    out << GetOptionString() << ",ucolor";
00604    if (fMarkEnds) {
00605       if (fReversedScale)
00606          out << ",kTRUE,kTRUE);" << endl;
00607       else
00608          out << ",kFALSE,kTRUE);" << endl;
00609    } else if (fReversedScale) {
00610       out << ",kTRUE);" << endl;
00611    } else {
00612       out << ");" << endl;
00613    }
00614    if (option && strstr(option, "keep_names"))
00615       out << "   " << GetName() << "->SetName(\"" << GetName() << "\");" << endl;
00616 
00617    if (fVmin != 0 || fVmax != (Int_t)fWidth)
00618       out << "   " << GetName() << "->SetRange(" << fVmin << "," << fVmax
00619           << ");" << endl;
00620 
00621    if (fSmin != fWidth/8*3 || fSmax != fWidth/8*5)
00622       out << "   " << GetName() << "->SetPosition(" << GetMinPosition()
00623           << "," << GetMaxPosition() << ");" << endl;
00624 
00625    if (fScale != 10)
00626       out << "   " << GetName() << "->SetScale(" << fScale << ");" << endl;
00627 
00628 }
00629 
00630 //______________________________________________________________________________
00631 void TGDoubleVSlider::SavePrimitive(ostream &out, Option_t *option /*= ""*/)
00632 {
00633     // Save an horizontal slider as a C++ statement(s) on output stream out.
00634 
00635    SaveUserColor(out, option);
00636 
00637    out<<"   TGDoubleVSlider *";
00638    out << GetName() << " = new TGDoubleVSlider("<< fParent->GetName()
00639        << "," << GetHeight() << ",";
00640    out << GetSString() << "," << WidgetId() << ",";
00641    out << GetOptionString() << ",ucolor";
00642    if (fMarkEnds) {
00643       if (fReversedScale)
00644          out << ",kTRUE,kTRUE);" << endl;
00645       else
00646          out << ",kFALSE,kTRUE);" << endl;
00647    } else if (fReversedScale) {
00648       out << ",kTRUE);" << endl;
00649    } else {
00650       out << ");" << endl;
00651    }
00652    if (option && strstr(option, "keep_names"))
00653       out << "   " << GetName() << "->SetName(\"" << GetName() << "\");" << endl;
00654 
00655    if (fVmin != 0 || fVmax != (Int_t)fHeight)
00656       out << "   " << GetName() <<"->SetRange(" << fVmin << "," << fVmax
00657           << ");" << endl;
00658 
00659 
00660    if (fSmin != fHeight/8*3 || fSmax != fHeight/8*5)
00661       out << "   " << GetName() << "->SetPosition(" << GetMinPosition()
00662           << "," << GetMaxPosition() << ");" << endl;
00663 
00664 
00665    if (fScale != 10)
00666       out << "   " << GetName() << "->SetScale(" << fScale << ");" << endl;
00667 
00668 }

Generated on Tue Jul 5 14:21:58 2011 for ROOT_528-00b_version by  doxygen 1.5.1