TGScrollBar.cxx

Go to the documentation of this file.
00001 // @(#)root/gui:$Id: TGScrollBar.cxx 35582 2010-09-22 13:38:27Z bellenot $
00002 // Author: Fons Rademakers   10/01/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 // TGScrollBar and TGScrollBarElement                                   //
00026 //                                                                      //
00027 // The classes in this file implement scrollbars. Scrollbars can be     //
00028 // either placed horizontal or vertical. A scrollbar contains three     //
00029 // TGScrollBarElements: The "head", "tail" and "slider". The head and   //
00030 // tail are fixed at either end and have the typical arrows in them.    //
00031 //                                                                      //
00032 // The TGHScrollBar will generate the following event messages:         //
00033 // kC_HSCROLL, kSB_SLIDERPOS, position, 0                               //
00034 // kC_HSCROLL, kSB_SLIDERTRACK, position, 0                             //
00035 //                                                                      //
00036 // The TGVScrollBar will generate the following event messages:         //
00037 // kC_VSCROLL, kSB_SLIDERPOS, position, 0                               //
00038 // kC_VSCROLL, kSB_SLIDERTRACK, position, 0                             //
00039 //                                                                      //
00040 //////////////////////////////////////////////////////////////////////////
00041 
00042 #include "TGScrollBar.h"
00043 #include "TGResourcePool.h"
00044 #include "TGPicture.h"
00045 #include "TImage.h"
00046 #include "TSystem.h"
00047 #include "TTimer.h"
00048 #include "TEnv.h"
00049 #include "Riostream.h"
00050 
00051 
00052 Pixmap_t TGScrollBar::fgBckgndPixmap = 0;
00053 Int_t    TGScrollBar::fgScrollBarWidth = kDefaultScrollBarWidth;
00054 
00055 ClassImp(TGScrollBarElement)
00056 ClassImp(TGScrollBar)
00057 ClassImp(TGHScrollBar)
00058 ClassImp(TGVScrollBar)
00059 
00060 
00061 //______________________________________________________________________________
00062 class TSBRepeatTimer : public TTimer {
00063 private:
00064    TGScrollBar   *fScrollBar;   // scroll bar
00065    Int_t                              fSmallInc;    // step
00066 public:
00067    TSBRepeatTimer(TGScrollBar *s, Long_t ms, Int_t inc) : TTimer(ms, kTRUE) 
00068       { fScrollBar = s;  fSmallInc = inc; }
00069       
00070    Bool_t Notify();
00071    Int_t  GetSmallInc() const { return fSmallInc; }
00072 };
00073 
00074 //______________________________________________________________________________
00075 Bool_t TSBRepeatTimer::Notify()
00076 {
00077    // Notify when timer times out and reset the timer.
00078 
00079    fScrollBar->HandleTimer(this);
00080    Reset();
00081    return kFALSE;
00082 }
00083 
00084 //______________________________________________________________________________
00085 TGScrollBarElement::TGScrollBarElement(const TGWindow *p, const TGPicture *pic,
00086                                        UInt_t w, UInt_t h, UInt_t options, Pixel_t back) :
00087                                        TGFrame(p, w, h, options | kOwnBackground, back)
00088 {
00089    // Constructor.
00090 
00091    fPic = fPicN = pic;
00092    fState = kButtonUp;
00093    fPicD = 0;
00094 }
00095 
00096 //______________________________________________________________________________
00097 TGScrollBarElement::~TGScrollBarElement()
00098 {
00099    // destructor
00100 
00101    if (fPicD) {
00102       fClient->FreePicture(fPicD);
00103    }
00104 }
00105 
00106 //______________________________________________________________________________
00107 void TGScrollBarElement::SetState(Int_t state)
00108 {
00109    // Change state of scrollbar element (either up or down).
00110 
00111    if (state != fState) {
00112       switch (state) {
00113          case kButtonDown:
00114             fOptions &= ~kRaisedFrame;
00115             fOptions |= kSunkenFrame;
00116             break;
00117          case kButtonUp:
00118          case kButtonDisabled:
00119             fOptions &= ~kSunkenFrame;
00120             fOptions |= kRaisedFrame;
00121             break;
00122       }
00123       fState = state;
00124       fClient->NeedRedraw(this);
00125    }
00126 }
00127 
00128 //______________________________________________________________________________
00129 void TGScrollBarElement::SetEnabled(Bool_t on)
00130 {
00131    // Enable/Disable scroll bar button chaging the state.
00132 
00133    if (on) {
00134       if (fState == kButtonUp) {
00135          return;
00136       }
00137       SetState(kButtonUp);
00138       fPic = fPicN;
00139    } else {
00140       if (fState == kButtonDisabled) {
00141          return;
00142       }
00143       SetState(kButtonDisabled);
00144 
00145       if (!fPicD) {
00146          TImage *img = TImage::Create();
00147          TImage *img2 = TImage::Create();
00148 
00149          TString back = gEnv->GetValue("Gui.BackgroundColor", "#c0c0c0");
00150          img2->FillRectangle(back.Data(), 0, 0, fPic->GetWidth(), fPic->GetHeight());
00151          img->SetImage(fPicN->GetPicture(), fPicN->GetMask());
00152          Pixmap_t mask = img->GetMask();
00153          img2->Merge(img, "overlay");
00154 
00155          TString name = "disbl_";
00156          name += fPic->GetName();
00157          fPicD = fClient->GetPicturePool()->GetPicture(name.Data(), img2->GetPixmap(),
00158                                                        mask);
00159          delete img;
00160          delete img2;
00161       }
00162       fPic = fPicD;
00163    }
00164    fClient->NeedRedraw(this);
00165 }
00166 
00167 //______________________________________________________________________________
00168 void TGScrollBarElement::DrawBorder()
00169 {
00170    // Draw border around scollbar element.
00171 
00172    switch (fOptions & (kSunkenFrame | kRaisedFrame)) {
00173       case kSunkenFrame: // pressed
00174          gVirtualX->DrawLine(fId, GetBlackGC()(), 0, 0, fWidth-2, 0);
00175          gVirtualX->DrawLine(fId, GetBlackGC()(), 0, 0, 0, fHeight-2);
00176          gVirtualX->DrawLine(fId, GetShadowGC()(),  1, 1, fWidth-3, 1);
00177          gVirtualX->DrawLine(fId, GetShadowGC()(),  1, 1, 1, fHeight-3);
00178 
00179          gVirtualX->DrawLine(fId, GetWhiteGC()(),  0, fHeight-1, fWidth-1, fHeight-1);
00180          gVirtualX->DrawLine(fId, GetWhiteGC()(),  fWidth-1, fHeight-1, fWidth-1, 1);
00181          gVirtualX->DrawLine(fId, GetBckgndGC()(),  1, fHeight-2, fWidth-2, fHeight-2);
00182          gVirtualX->DrawLine(fId, GetBckgndGC()(),  fWidth-2, fHeight-2, fWidth-2, 2);
00183 
00184          if (fPic) {
00185             int x = (fWidth - fPic->GetWidth()) >> 1;
00186             int y = (fHeight - fPic->GetHeight()) >> 1;
00187             fPic->Draw(fId, GetBckgndGC()(), x+1, y+1); // 3, 3
00188          }
00189          break;
00190 
00191       case kRaisedFrame: // normal
00192       case kButtonDisabled:
00193          gVirtualX->DrawLine(fId, GetBckgndGC()(), 0, 0, fWidth-2, 0);
00194          gVirtualX->DrawLine(fId, GetBckgndGC()(), 0, 0, 0, fHeight-2);
00195          gVirtualX->DrawLine(fId, GetHilightGC()(), 1, 1, fWidth-3, 1);
00196          gVirtualX->DrawLine(fId, GetHilightGC()(), 1, 1, 1, fHeight-3);
00197 
00198          gVirtualX->DrawLine(fId, GetShadowGC()(),  1, fHeight-2, fWidth-2, fHeight-2);
00199          gVirtualX->DrawLine(fId, GetShadowGC()(),  fWidth-2, fHeight-2, fWidth-2, 1);
00200          gVirtualX->DrawLine(fId, GetBlackGC()(), 0, fHeight-1, fWidth-1, fHeight-1);
00201          gVirtualX->DrawLine(fId, GetBlackGC()(), fWidth-1, fHeight-1, fWidth-1, 0);
00202 
00203          if (fPic) {
00204             int x = (fWidth - fPic->GetWidth()) >> 1;
00205             int y = (fHeight - fPic->GetHeight()) >> 1;
00206             fPic->Draw(fId, GetBckgndGC()(), x, y); // 2, 2
00207          }
00208          break;
00209 
00210       default:
00211          break;
00212    }
00213 }
00214 
00215 //______________________________________________________________________________
00216 TGScrollBar::TGScrollBar(const TGWindow *p, UInt_t w, UInt_t h,
00217                          UInt_t options, Pixel_t back) :
00218    TGFrame(p, w, h, options | kOwnBackground, back),
00219    fX0(0), fY0(0), fXp(0), fYp(0), fDragging(kFALSE), fGrabPointer(kTRUE),
00220    fRange(0), fPsize(0), fPos(0), fSliderSize(0), fSliderRange(0),
00221    fSmallInc(1), fHead(0), fTail(0), fSlider(0), fHeadPic(0),
00222    fTailPic(0), fRepeat(0), fSubw()
00223 {
00224    // Constructor.
00225 
00226    fAccelerated = kFALSE;
00227 
00228    fMsgWindow = p;
00229    SetBackgroundPixmap(GetBckgndPixmap());
00230    SetWindowName();
00231 }
00232 
00233 //______________________________________________________________________________
00234 TGScrollBar::~TGScrollBar()
00235 {
00236    // Delete a scrollbar (either horizontal or vertical).
00237 
00238    delete fHead;
00239    delete fTail;
00240    delete fSlider;
00241    if (fHeadPic) fClient->FreePicture(fHeadPic);
00242    if (fTailPic) fClient->FreePicture(fTailPic);
00243    if (fRepeat) { delete fRepeat; fRepeat = 0; }
00244 }
00245 
00246 //______________________________________________________________________________
00247 Bool_t TGScrollBar::HandleTimer(TTimer *t)
00248 {
00249    // Handle repeat timer for horizontal or vertical scrollbar. Every time
00250    // timer times out we move slider.
00251 
00252    // shorten time out time to 50 milli seconds
00253    t->SetTime(50);
00254 
00255    Window_t  dum1, dum2;
00256    Event_t   ev;
00257 
00258    ev.fCode    = kButton1;
00259    ev.fType    = kButtonPress;
00260    ev.fUser[0] = fSubw;
00261 
00262    if (IsAccelerated()) {
00263       ++fSmallInc;
00264       if (fSmallInc > 100) fSmallInc = 100;
00265    }
00266 
00267    gVirtualX->QueryPointer(fId, dum1, dum2, ev.fXRoot, ev.fYRoot, ev.fX, ev.fY,
00268                       ev.fState);
00269 
00270    HandleButton(&ev);
00271 
00272    return kTRUE;
00273 }
00274 
00275 //______________________________________________________________________________
00276 Pixmap_t TGScrollBar::GetBckgndPixmap()
00277 {
00278    // Static method returning scrollbar background pixmap.
00279 
00280    static Bool_t init = kFALSE;
00281    if (!init) {
00282       fgBckgndPixmap = gClient->GetResourcePool()->GetCheckeredPixmap();
00283       init = kTRUE;
00284    }
00285    return fgBckgndPixmap;
00286 }
00287 
00288 //______________________________________________________________________________
00289 Int_t TGScrollBar::GetScrollBarWidth()
00290 {
00291    // Static method returning the scrollbar width.
00292 
00293    return fgScrollBarWidth;
00294 }
00295 
00296 //______________________________________________________________________________
00297 void TGScrollBar::ChangeBackground(Pixel_t back)
00298 {
00299    // Change background color
00300 
00301    TGFrame::ChangeBackground(back);
00302    fHead->ChangeBackground(back);
00303    fTail->ChangeBackground(back);
00304    fSlider->ChangeBackground(back);
00305 }
00306 
00307 //______________________________________________________________________________
00308 TGHScrollBar::TGHScrollBar(const TGWindow *p, UInt_t w, UInt_t h,
00309                            UInt_t options, ULong_t back) :
00310     TGScrollBar(p, w, h, options, back)
00311 {
00312    // Create a horizontal scrollbar widget.
00313 
00314    fHeadPic = fClient->GetPicture("arrow_left.xpm");
00315    fTailPic = fClient->GetPicture("arrow_right.xpm");
00316 
00317    if (!fHeadPic || !fTailPic) {
00318       Error("TGHScrollBar", "arrow_*.xpm not found");
00319       return;
00320    }
00321    fHead   = new TGScrollBarElement(this, fHeadPic, fgScrollBarWidth, fgScrollBarWidth,
00322                                     kRaisedFrame);
00323    fTail   = new TGScrollBarElement(this, fTailPic, fgScrollBarWidth, fgScrollBarWidth,
00324                                     kRaisedFrame);
00325    fSlider = new TGScrollBarElement(this, 0, fgScrollBarWidth, 50,
00326                                     kRaisedFrame);
00327 
00328    gVirtualX->GrabButton(fId, kAnyButton, kAnyModifier, kButtonPressMask |
00329                          kButtonReleaseMask | kPointerMotionMask, kNone, kNone);
00330 
00331    fDragging = kFALSE;
00332    fX0 = fY0 = (fgScrollBarWidth = TMath::Max(fgScrollBarWidth, 5));
00333    fPos = 0;
00334 
00335    fRange = TMath::Max((Int_t) w - (fgScrollBarWidth << 1), 1);
00336    fPsize = fRange >> 1;
00337 
00338    fSliderSize  = 50;
00339    fSliderRange = 1;
00340 
00341    fHead->SetEditDisabled(kEditDisable | kEditDisableGrab);
00342    fTail->SetEditDisabled(kEditDisable | kEditDisableGrab);
00343    fSlider->SetEditDisabled(kEditDisable | kEditDisableGrab);
00344    fEditDisabled = kEditDisableLayout | kEditDisableHeight | kEditDisableBtnEnable;
00345 }
00346 
00347 //______________________________________________________________________________
00348 void TGHScrollBar::Layout()
00349 {
00350    // Layout and move horizontal scrollbar components.
00351 
00352    // Should also recalculate the slider size and range, etc.
00353    fHead->Move(0, 0);
00354    fHead->Resize(fgScrollBarWidth, fgScrollBarWidth);
00355    fTail->Move(fWidth-fgScrollBarWidth, 0);
00356    fTail->Resize(fgScrollBarWidth, fgScrollBarWidth);
00357 
00358    if (fSlider->GetX() != fX0) {
00359       fSlider->Move(fX0, 0);
00360       fSlider->Resize(50, fgScrollBarWidth);
00361    }
00362 }
00363 
00364 //______________________________________________________________________________
00365 Bool_t TGHScrollBar::HandleButton(Event_t *event)
00366 {
00367    // Handle a mouse button event in a horizontal scrolbar.
00368 
00369    Int_t newpos;
00370 
00371    if (event->fCode == kButton4) {
00372       if (!fHead->IsEnabled()) {
00373          return kFALSE;
00374       }
00375       //scroll left
00376       newpos = fPos - fPsize;
00377       if (newpos<0) newpos = 0;
00378       SetPosition(newpos);
00379       return kTRUE;
00380    }
00381    if (event->fCode == kButton5) {
00382       if (!fTail->IsEnabled()) {
00383          return kFALSE;
00384       }
00385       // scroll right
00386       newpos = fPos + fPsize;
00387       SetPosition(newpos);
00388       return kTRUE;
00389    }
00390 
00391    if (event->fType == kButtonPress) {
00392       if (event->fCode == kButton3) {
00393          fX0 = event->fX - fSliderSize/2;
00394          fX0 = TMath::Max(fX0, fgScrollBarWidth);
00395          fX0 = TMath::Min(fX0, fgScrollBarWidth + fSliderRange);
00396          ULong_t pos = (ULong_t)(fX0 - fgScrollBarWidth) * (ULong_t)(fRange-fPsize) / (ULong_t)fSliderRange;
00397          fPos = (Int_t)pos;
00398 
00399          fPos = TMath::Max(fPos, 0);
00400          fPos = TMath::Min(fPos, fRange-fPsize);
00401          fSlider->Move(fX0, 0);
00402 
00403          SendMessage(fMsgWindow, MK_MSG(kC_HSCROLL, kSB_SLIDERTRACK), fPos, 0);
00404          PositionChanged(fPos);
00405          return kTRUE;
00406       }
00407 
00408       // fUser[0] contains the subwindow (child) in which the event occured
00409       // (see GX11Gui.cxx)
00410       Window_t subw = (Window_t)event->fUser[0];
00411 
00412       if (subw == fSlider->GetId()) {
00413          fXp = event->fX - fX0;
00414          fYp = event->fY - fY0;
00415          fDragging = kTRUE;
00416 
00417       } else {
00418 
00419          if (!fRepeat)
00420             fRepeat = new TSBRepeatTimer(this, 400, fSmallInc); // 500
00421          fRepeat->Reset();
00422          gSystem->AddTimer(fRepeat);
00423          fSubw = subw;
00424 
00425          if (subw == fHead->GetId()) {
00426             //if (!fHead->IsEnabled()) {
00427              //  return kFALSE;
00428             //}
00429             fHead->SetState(kButtonDown);
00430             fPos -= fSmallInc;
00431          } else if (subw == fTail->GetId()) {
00432             //if (!fTail->IsEnabled()) {
00433            //    return kFALSE;
00434            // }
00435             fTail->SetState(kButtonDown);
00436             fPos += fSmallInc;
00437          } else if (event->fX > fgScrollBarWidth && event->fX < fX0)
00438             fPos -= fPsize;
00439          else if (event->fX > fX0+fSliderSize && event->fX < (Int_t)fWidth-fgScrollBarWidth)
00440             fPos += fPsize;
00441 
00442          fPos = TMath::Max(fPos, 0);
00443          fPos = TMath::Min(fPos, fRange-fPsize);
00444 
00445          fX0 = fgScrollBarWidth + fPos * fSliderRange / TMath::Max(fRange-fPsize, 1);
00446 
00447          fX0 = TMath::Max(fX0, fgScrollBarWidth);
00448          fX0 = TMath::Min(fX0, fgScrollBarWidth + fSliderRange);
00449 
00450          fSlider->Move(fX0, 0);
00451 
00452          SendMessage(fMsgWindow, MK_MSG(kC_HSCROLL, kSB_SLIDERTRACK), fPos, 0);
00453          PositionChanged(fPos);
00454       }
00455 
00456       // last argument kFALSE forces all specified events to this window
00457       if (fGrabPointer && !fClient->IsEditable())
00458          gVirtualX->GrabPointer(fId, kButtonPressMask | kButtonReleaseMask |
00459                                 kPointerMotionMask, kNone, kNone,
00460                                 kTRUE, kFALSE);
00461    } else {
00462       fHead->SetState(kButtonUp);
00463       fTail->SetState(kButtonUp);
00464 
00465       if (fRepeat) {
00466          fRepeat->Remove();
00467          fRepeat->SetTime(400);  // might have been shortened in HandleTimer()
00468          fSmallInc = ((TSBRepeatTimer*)fRepeat)->GetSmallInc();
00469       }
00470 
00471       fDragging = kFALSE;
00472 
00473       fPos = TMath::Max(fPos, 0);
00474       fPos = TMath::Min(fPos, fRange-fPsize);
00475 
00476       SendMessage(fMsgWindow, MK_MSG(kC_HSCROLL, kSB_SLIDERPOS), fPos, 0);
00477       PositionChanged(fPos);
00478 
00479       if (fGrabPointer)
00480          gVirtualX->GrabPointer(0, 0, 0, 0, kFALSE);  // ungrab pointer
00481    }
00482    return kTRUE;
00483 }
00484 
00485 //______________________________________________________________________________
00486 Bool_t TGHScrollBar::HandleMotion(Event_t *event)
00487 {
00488    // Handle mouse motion event in a horizontal scrollbar.
00489 
00490    if (fDragging) {
00491       fX0 = event->fX - fXp;
00492       fY0 = event->fY - fYp;
00493 
00494       fX0 = TMath::Max(fX0, fgScrollBarWidth);
00495       fX0 = TMath::Min(fX0, fgScrollBarWidth + fSliderRange);
00496       fSlider->Move(fX0, 0);
00497       ULong_t pos = (ULong_t)(fX0 - fgScrollBarWidth) * (ULong_t)(fRange-fPsize) / (ULong_t)fSliderRange;
00498       fPos = (Int_t)pos;
00499 
00500       fPos = TMath::Max(fPos, 0);
00501       fPos = TMath::Min(fPos, fRange-fPsize);
00502 
00503       SendMessage(fMsgWindow, MK_MSG(kC_HSCROLL, kSB_SLIDERTRACK), fPos, 0);
00504       PositionChanged(fPos);
00505    }
00506    return kTRUE;
00507 }
00508 
00509 //______________________________________________________________________________
00510 void TGHScrollBar::SetRange(Int_t range, Int_t page_size)
00511 {
00512    // Set range of horizontal scrollbar.
00513 
00514    fRange = TMath::Max(range, 1);
00515    fPsize = TMath::Max(page_size, 0);
00516    fPos = TMath::Max(fPos, 0);
00517    fPos = TMath::Min(fPos, fRange-fPsize);
00518 
00519    fSliderSize = TMath::Max(fPsize * (fWidth - (fgScrollBarWidth << 1)) /
00520                             fRange, (UInt_t) 6);
00521    fSliderSize = TMath::Min((UInt_t)fSliderSize, fWidth - (fgScrollBarWidth << 1));
00522 
00523    fSliderRange = TMath::Max(fWidth - (fgScrollBarWidth << 1) - fSliderSize,
00524                              (UInt_t) 1);
00525 
00526    fX0 = fgScrollBarWidth + fPos * fSliderRange / TMath::Max(fRange-fPsize, 1);
00527    fX0 = TMath::Max(fX0, fgScrollBarWidth);
00528    fX0 = TMath::Min(fX0, fgScrollBarWidth + fSliderRange);
00529 
00530    fSlider->Move(fX0, 0);
00531    fSlider->Resize(fSliderSize, fgScrollBarWidth);
00532 
00533    //  fPos = (fX0 - fgScrollBarWidth) * (fRange-fPsize) / fSliderRange;
00534 
00535    SendMessage(fMsgWindow, MK_MSG(kC_HSCROLL, kSB_SLIDERPOS), fPos, 0);
00536    PositionChanged(fPos);
00537    RangeChanged(fRange);
00538    PageSizeChanged(fPsize);
00539 }
00540 
00541 //______________________________________________________________________________
00542 void TGHScrollBar::SetPosition(Int_t pos)
00543 {
00544    // Set logical slider position of horizontal scrollbar.
00545 
00546    fPos = TMath::Max(pos, 0);
00547    fPos = TMath::Min(pos, fRange-fPsize);
00548 
00549    fX0 = fgScrollBarWidth + fPos * fSliderRange / TMath::Max(fRange-fPsize, 1);
00550    fX0 = TMath::Max(fX0, fgScrollBarWidth);
00551    fX0 = TMath::Min(fX0, fgScrollBarWidth + fSliderRange);
00552 
00553    fSlider->Move(fX0, 0);
00554    fSlider->Resize(fSliderSize, fgScrollBarWidth);
00555 
00556    SendMessage(fMsgWindow, MK_MSG(kC_HSCROLL, kSB_SLIDERPOS), fPos, 0);
00557    PositionChanged(fPos);
00558 }
00559 
00560 
00561 //______________________________________________________________________________
00562 TGVScrollBar::TGVScrollBar(const TGWindow *p, UInt_t w, UInt_t h,
00563                            UInt_t options, ULong_t back) :
00564     TGScrollBar(p, w, h, options, back)
00565 {
00566    // Create a vertical scrollbar.
00567 
00568    fHeadPic = fClient->GetPicture("arrow_up.xpm");
00569    fTailPic = fClient->GetPicture("arrow_down.xpm");
00570 
00571    if (!fHeadPic || !fTailPic) {
00572       Error("TGVScrollBar", "arrow_*.xpm not found");
00573       return;
00574    }
00575    fHead   = new TGScrollBarElement(this, fHeadPic, fgScrollBarWidth, fgScrollBarWidth,
00576                                     kRaisedFrame);
00577    fTail   = new TGScrollBarElement(this, fTailPic, fgScrollBarWidth, fgScrollBarWidth,
00578                                     kRaisedFrame);
00579    fSlider = new TGScrollBarElement(this, 0, fgScrollBarWidth, 50,
00580                                     kRaisedFrame);
00581 
00582    gVirtualX->GrabButton(fId, kAnyButton, kAnyModifier, kButtonPressMask |
00583                          kButtonReleaseMask | kPointerMotionMask, kNone, kNone);
00584 
00585    fDragging = kFALSE;
00586    fX0 = fY0 = (fgScrollBarWidth = TMath::Max(fgScrollBarWidth, 5));
00587    fPos = 0;
00588 
00589    fRange = TMath::Max((Int_t) h - (fgScrollBarWidth << 1), 1);
00590    fPsize = fRange >> 1;
00591 
00592    fSliderSize  = 50;
00593    fSliderRange = 1;
00594 
00595    fHead->SetEditDisabled(kEditDisable | kEditDisableGrab);
00596    fTail->SetEditDisabled(kEditDisable | kEditDisableGrab);
00597    fSlider->SetEditDisabled(kEditDisable | kEditDisableGrab);
00598    fEditDisabled = kEditDisableLayout | kEditDisableWidth | kEditDisableBtnEnable;
00599 }
00600 
00601 //______________________________________________________________________________
00602 void TGVScrollBar::Layout()
00603 {
00604    // Layout and move vertical scrollbar components.
00605 
00606    // Should recalculate fSliderSize, fSliderRange, fX0, fY0, etc. too...
00607    fHead->Move(0, 0);
00608    fHead->Resize(fgScrollBarWidth, fgScrollBarWidth);
00609    fTail->Move(0, fHeight-fgScrollBarWidth);
00610    fTail->Resize(fgScrollBarWidth, fgScrollBarWidth);
00611 
00612    if (fSlider->GetY() != fY0) {
00613       fSlider->Move(0, fY0);
00614       fSlider->Resize(fgScrollBarWidth, 50);
00615    }
00616 }
00617 
00618 //______________________________________________________________________________
00619 Bool_t TGVScrollBar::HandleButton(Event_t *event)
00620 {
00621    // Handle mouse button event in vertical scrollbar.
00622 
00623    Int_t newpos;
00624 
00625    if (event->fCode == kButton4) {
00626       if (!fHead->IsEnabled()) {
00627          return kFALSE;
00628       }
00629       //scroll up
00630       newpos = fPos - fPsize;
00631       if (newpos<0) newpos = 0;
00632       SetPosition(newpos);
00633       return kTRUE;
00634    }
00635    if (event->fCode == kButton5) {
00636       if (!fTail->IsEnabled()) {
00637          return kFALSE;
00638       }
00639 
00640       // scroll down
00641       newpos = fPos + fPsize;
00642       SetPosition(newpos);
00643       return kTRUE;
00644    }
00645 
00646    if (event->fType == kButtonPress) {
00647       if (event->fCode == kButton3) {
00648          fY0 = event->fY - fSliderSize/2;
00649          fY0 = TMath::Max(fY0, fgScrollBarWidth);
00650          fY0 = TMath::Min(fY0, fgScrollBarWidth + fSliderRange);
00651          ULong_t pos = (ULong_t)(fY0 - fgScrollBarWidth) * (ULong_t)(fRange-fPsize) / (ULong_t)fSliderRange;
00652          fPos = (Int_t)pos;
00653 
00654          fPos = TMath::Max(fPos, 0);
00655          fPos = TMath::Min(fPos, fRange-fPsize);
00656          fSlider->Move(0, fY0);
00657 
00658          SendMessage(fMsgWindow, MK_MSG(kC_VSCROLL, kSB_SLIDERTRACK), fPos, 0);
00659          PositionChanged(fPos);
00660          return kTRUE;
00661       }
00662 
00663       // fUser[0] contains the subwindow (child) in which the event occured
00664       // (see GX11Gui.cxx)
00665       Window_t subw = (Window_t)event->fUser[0];
00666 
00667       if (subw == fSlider->GetId()) {
00668          fXp = event->fX - fX0;
00669          fYp = event->fY - fY0;
00670          fDragging = kTRUE;
00671 
00672       } else {
00673 
00674          if (!fRepeat)
00675             fRepeat = new TSBRepeatTimer(this, 400, fSmallInc); // 500
00676          fRepeat->Reset();
00677          gSystem->AddTimer(fRepeat);
00678          fSubw = subw;
00679 
00680          if (subw == fHead->GetId()) {
00681             //if (!fHead->IsEnabled()) {
00682             //   return kFALSE;
00683            // }
00684             fHead->SetState(kButtonDown);
00685             fPos -= fSmallInc;
00686          } else if (subw == fTail->GetId()) {
00687             //if (!fTail->IsEnabled()) {
00688             //   return kFALSE;
00689             //}
00690             fTail->SetState(kButtonDown);
00691             fPos += fSmallInc;
00692          } else if (event->fY > fgScrollBarWidth && event->fY < fY0)
00693             fPos -= fPsize;
00694          else if (event->fY > fY0+fSliderSize && event->fY < (Int_t)fHeight-fgScrollBarWidth)
00695             fPos += fPsize;
00696 
00697          fPos = TMath::Max(fPos, 0);
00698          fPos = TMath::Min(fPos, fRange-fPsize);
00699 
00700          ULong_t y0 = (ULong_t)fgScrollBarWidth + (ULong_t)fPos * (ULong_t)fSliderRange / (ULong_t)TMath::Max(fRange-fPsize, 1);
00701          fY0 = (Int_t)y0;
00702 
00703          fY0 = TMath::Max(fY0, fgScrollBarWidth);
00704          fY0 = TMath::Min(fY0, fgScrollBarWidth + fSliderRange);
00705 
00706          fSlider->Move(0, fY0);
00707 
00708          SendMessage(fMsgWindow, MK_MSG(kC_VSCROLL, kSB_SLIDERTRACK), fPos, 0);
00709          PositionChanged(fPos);
00710       }
00711 
00712       // last argument kFALSE forces all specified events to this window
00713       if (fGrabPointer && !fClient->IsEditable())
00714          gVirtualX->GrabPointer(fId, kButtonPressMask | kButtonReleaseMask |
00715                                 kPointerMotionMask, kNone, kNone,
00716                                 kTRUE, kFALSE);
00717    } else {
00718       fHead->SetState(kButtonUp);
00719       fTail->SetState(kButtonUp);
00720 
00721       if (fRepeat) {
00722          fRepeat->Remove();
00723          fRepeat->SetTime(400);  // might have been shortened in HandleTimer()
00724          fSmallInc = ((TSBRepeatTimer*)fRepeat)->GetSmallInc();
00725       }
00726 
00727       fDragging = kFALSE;
00728 
00729       fPos = TMath::Max(fPos, 0);
00730       fPos = TMath::Min(fPos, fRange-fPsize);
00731 
00732       SendMessage(fMsgWindow, MK_MSG(kC_VSCROLL, kSB_SLIDERPOS), fPos, 0);
00733       PositionChanged(fPos);
00734 
00735       if (fGrabPointer) {
00736          gVirtualX->GrabPointer(0, 0, 0, 0, kFALSE);  // ungrab pointer
00737       }
00738    }
00739    return kTRUE;
00740 }
00741 
00742 //______________________________________________________________________________
00743 Bool_t TGVScrollBar::HandleMotion(Event_t *event)
00744 {
00745    // Handle mouse motion in a vertical scrollbar.
00746 
00747    if (fDragging) {
00748       fX0 = event->fX - fXp;
00749       fY0 = event->fY - fYp;
00750 
00751       fY0 = TMath::Max(fY0, fgScrollBarWidth);
00752       fY0 = TMath::Min(fY0, fgScrollBarWidth + fSliderRange);
00753       fSlider->Move(0, fY0);
00754       ULong_t pos = (ULong_t)(fY0 - fgScrollBarWidth) * (ULong_t)(fRange-fPsize) / fSliderRange;
00755       fPos = (Int_t)pos;
00756 
00757       fPos = TMath::Max(fPos, 0);
00758       fPos = TMath::Min(fPos, fRange-fPsize);
00759 
00760       SendMessage(fMsgWindow, MK_MSG(kC_VSCROLL, kSB_SLIDERTRACK), fPos, 0);
00761       PositionChanged(fPos);
00762    }
00763    return kTRUE;
00764 }
00765 
00766 //______________________________________________________________________________
00767 void TGVScrollBar::SetRange(Int_t range, Int_t page_size)
00768 {
00769    // Set range of vertical scrollbar.
00770 
00771    fRange = TMath::Max(range, 1);
00772    fPsize = TMath::Max(page_size, 0);
00773    fPos = TMath::Max(fPos, 0);
00774    fPos = TMath::Min(fPos, fRange-fPsize);
00775 
00776    fSliderSize = TMath::Max(fPsize * (fHeight - (fgScrollBarWidth << 1)) /
00777                             fRange, (UInt_t) 6);
00778    fSliderSize = TMath::Min((UInt_t)fSliderSize, fHeight - (fgScrollBarWidth << 1));
00779 
00780    fSliderRange = TMath::Max(fHeight - (fgScrollBarWidth << 1) - fSliderSize,
00781                              (UInt_t)1);
00782 
00783    ULong_t y0 = (ULong_t)fgScrollBarWidth + (ULong_t)fPos * (ULong_t)fSliderRange / (ULong_t)TMath::Max(fRange-fPsize, 1);
00784    fY0 = (Int_t)y0;
00785    fY0 = TMath::Max(fY0, fgScrollBarWidth);
00786    fY0 = TMath::Min(fY0, fgScrollBarWidth + fSliderRange);
00787 
00788    fSlider->Move(0, fY0);
00789    fSlider->Resize(fgScrollBarWidth, fSliderSize);
00790 
00791    //  fPos = (fY0 - fgScrollBarWidth) * (fRange-fPsize) / fSliderRange;
00792 
00793 
00794    SendMessage(fMsgWindow, MK_MSG(kC_VSCROLL, kSB_SLIDERPOS), fPos, 0);
00795    PositionChanged(fPos);
00796    RangeChanged(fRange);
00797    PageSizeChanged(fPsize);
00798 }
00799 
00800 //______________________________________________________________________________
00801 void TGVScrollBar::SetPosition(Int_t pos)
00802 {
00803    // Set logical slider position of vertical scrollbar.
00804 
00805    fPos = TMath::Max(pos, 0);
00806    fPos = TMath::Min(pos, fRange-fPsize);
00807 
00808    ULong_t y0 = (ULong_t)fgScrollBarWidth + (ULong_t)fPos * (ULong_t)fSliderRange / (ULong_t)TMath::Max(fRange-fPsize, 1);
00809    fY0 = (Int_t)y0;
00810    fY0 = TMath::Max(fY0, fgScrollBarWidth);
00811    fY0 = TMath::Min(fY0, fgScrollBarWidth + fSliderRange);
00812 
00813    fSlider->Move(0, fY0);
00814    fSlider->Resize(fgScrollBarWidth, fSliderSize);
00815 
00816    SendMessage(fMsgWindow, MK_MSG(kC_VSCROLL, kSB_SLIDERPOS), fPos, 0);
00817    PositionChanged(fPos);
00818 }
00819 
00820 //______________________________________________________________________________
00821 void TGHScrollBar::SavePrimitive(ostream &out, Option_t *option /*= ""*/)
00822 {
00823     // Save an horizontal scrollbar as a C++ statement(s) on output stream out.
00824 
00825    if (fBackground != GetDefaultFrameBackground()) SaveUserColor(out, option);
00826 
00827    out <<"   TGHScrollBar *";
00828    out << GetName() << " = new TGHScrollBar(" << fParent->GetName()
00829        << "," << GetWidth() << "," << GetHeight();
00830 
00831    if (fBackground == GetDefaultFrameBackground()) {
00832       if (!GetOptions()) {
00833          out <<");" << endl;
00834       } else {
00835          out << "," << GetOptionString() <<");" << endl;
00836       }
00837    } else {
00838       out << "," << GetOptionString() << ",ucolor);" << endl;
00839    }
00840    if (option && strstr(option, "keep_names"))
00841       out << "   " << GetName() << "->SetName(\"" << GetName() << "\");" << endl;
00842 
00843    out << "   " << GetName() <<"->SetRange(" << GetRange() << "," << GetPageSize() << ");" << endl;
00844    out << "   " << GetName() <<"->SetPosition(" << GetPosition() << ");" << endl;
00845 }
00846 
00847 //______________________________________________________________________________
00848 void TGVScrollBar::SavePrimitive(ostream &out, Option_t *option /*= ""*/)
00849 {
00850     // Save an vertical scrollbar as a C++ statement(s) on output stream out.
00851 
00852    if (fBackground != GetDefaultFrameBackground()) SaveUserColor(out, option);
00853 
00854    out<<"   TGVScrollBar *";
00855    out << GetName() <<" = new TGVScrollBar("<< fParent->GetName()
00856        << "," << GetWidth() << "," << GetHeight();
00857 
00858    if (fBackground == GetDefaultFrameBackground()) {
00859 
00860       if (!GetOptions()) {
00861          out <<");" << endl;
00862       } else {
00863          out << "," << GetOptionString() <<");" << endl;
00864       }
00865    } else {
00866       out << "," << GetOptionString() << ",ucolor);" << endl;
00867    }
00868    if (option && strstr(option, "keep_names"))
00869       out << "   " << GetName() << "->SetName(\"" << GetName() << "\");" << endl;
00870 
00871    out << "   " << GetName() <<"->SetRange(" << GetRange() << "," << GetPageSize() << ");" << endl;
00872    out << "   " << GetName() <<"->SetPosition(" << GetPosition() << ");" << endl;
00873 }

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