TGToolTip.cxx

Go to the documentation of this file.
00001 // @(#)root/gui:$Id: TGToolTip.cxx 36154 2010-10-07 13:55:09Z rdm $
00002 // Author: Fons Rademakers   22/02/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 // TGToolTip                                                            //
00026 //                                                                      //
00027 // A tooltip can be a one or multiple lines help text that is displayed //
00028 // in a window when the mouse cursor overs a widget, without clicking   //
00029 // it. A small box appears with suplementary information regarding the  //
00030 // item being hovered over.                                             //                               //
00031 //                                                                      //
00032 // A multiline tooltip can be created by inserting a new-line character //
00033 // "\n" in the tooltip string. For example:                             //
00034 //                                                                      //
00035 // fButton->SetToolTipText("Go to the ROOT page\n (http://root.cern.ch) //
00036 //                                                                      //
00037 //////////////////////////////////////////////////////////////////////////
00038 
00039 #include "TGToolTip.h"
00040 #include "TGLabel.h"
00041 #include "TGResourcePool.h"
00042 #include "TTimer.h"
00043 #include "TSystem.h"
00044 #include "TVirtualPad.h"
00045 #include "TBox.h"
00046 
00047 
00048 ClassImp(TGToolTip)
00049 
00050 //______________________________________________________________________________
00051 class TTipDelayTimer : public TTimer {
00052 private:
00053    TGToolTip   *fTip;  // tooltip
00054 public:
00055    TTipDelayTimer(TGToolTip *tip, Long_t ms) : TTimer(ms, kTRUE) { fTip = tip; }
00056    Bool_t Notify();
00057 };
00058 
00059 //______________________________________________________________________________
00060 Bool_t TTipDelayTimer::Notify()
00061 {
00062    // Notify when timer times out and reset the timer.
00063 
00064    fTip->HandleTimer(0);
00065    Reset();
00066    return kFALSE;
00067 }
00068 
00069 
00070 //______________________________________________________________________________
00071 TGToolTip::TGToolTip(const TGWindow *p, const TGFrame *f, const char *text,
00072                      Long_t delayms)
00073    : TGCompositeFrame(p, 10, 10, kTempFrame | kHorizontalFrame | kRaisedFrame)
00074 {
00075    // Create a tool tip. P is the tool tips parent window (normally
00076    // fClient->GetRoot(), f is the frame to which the tool tip is associated,
00077    // text is the tool tip one-liner and delayms is the delay in ms before
00078    // the tool tip is shown.
00079 
00080    SetWindowAttributes_t attr;
00081    attr.fMask             = kWAOverrideRedirect | kWASaveUnder;
00082    attr.fOverrideRedirect = kTRUE;
00083    attr.fSaveUnder        = kTRUE;
00084 
00085    gVirtualX->ChangeWindowAttributes(fId, &attr);
00086    SetBackgroundColor(fClient->GetResourcePool()->GetTipBgndColor());
00087 
00088    fLabel = new TGLabel(this, text);
00089    fLabel->SetBackgroundColor(fClient->GetResourcePool()->GetTipBgndColor());
00090 
00091    AddFrame(fLabel, fL1 = new TGLayoutHints(kLHintsLeft | kLHintsTop,
00092                                             2, 3, 0, 0));
00093    MapSubwindows();
00094    Resize(GetDefaultSize());
00095 
00096    fWindow = f;
00097    fPad    = 0;
00098    fBox    = 0;
00099    fX = fY = -1;
00100    fDelay = new TTipDelayTimer(this, delayms);
00101 }
00102 
00103 //______________________________________________________________________________
00104 TGToolTip::TGToolTip(const TGWindow *p, const TBox *box, const char *text,
00105                      Long_t delayms)
00106    : TGCompositeFrame(p, 10, 10, kTempFrame | kHorizontalFrame | kRaisedFrame)
00107 {
00108    // Create a tool tip. P is the tool tips parent window (normally
00109    // fClient->GetRoot(), box is the area to which the tool tip is associated,
00110    // text is the tool tip one-liner and delayms is the delay in ms before
00111    // the tool tip is shown. When using this ctor with the box argument
00112    // you have to use Reset(const TVirtualPad *parent).
00113 
00114    SetWindowAttributes_t attr;
00115    attr.fMask             = kWAOverrideRedirect | kWASaveUnder;
00116    attr.fOverrideRedirect = kTRUE;
00117    attr.fSaveUnder        = kTRUE;
00118 
00119    gVirtualX->ChangeWindowAttributes(fId, &attr);
00120    SetBackgroundColor(fClient->GetResourcePool()->GetTipBgndColor());
00121 
00122    fLabel = new TGLabel(this, text);
00123    fLabel->SetBackgroundColor(fClient->GetResourcePool()->GetTipBgndColor());
00124 
00125    AddFrame(fLabel, fL1 = new TGLayoutHints(kLHintsLeft | kLHintsTop,
00126                                             2, 3, 0, 0));
00127    MapSubwindows();
00128    Resize(GetDefaultSize());
00129 
00130    fWindow = 0;
00131    fPad    = 0;
00132    fBox    = box;
00133    fDelay = new TTipDelayTimer(this, delayms);
00134 }
00135 
00136 //______________________________________________________________________________
00137 TGToolTip::TGToolTip(const TBox *box, const char *text,Long_t delayms)
00138    : TGCompositeFrame(gClient->GetRoot(), 10, 10, kTempFrame | kHorizontalFrame | kRaisedFrame)
00139 {
00140    // Create a tool tip in the parent window gClient->GetRoot(),
00141    // box is the area to which the tool tip is associated,
00142    // text is the tool tip one-liner and delayms is the delay in ms before
00143    // the tool tip is shown. When using this ctor with the box argument
00144    // you have to use Reset(const TVirtualPad *parent).
00145 
00146    SetWindowAttributes_t attr;
00147    attr.fMask             = kWAOverrideRedirect | kWASaveUnder;
00148    attr.fOverrideRedirect = kTRUE;
00149    attr.fSaveUnder        = kTRUE;
00150 
00151    gVirtualX->ChangeWindowAttributes(fId, &attr);
00152    SetBackgroundColor(fClient->GetResourcePool()->GetTipBgndColor());
00153 
00154    fLabel = new TGLabel(this, text);
00155    fLabel->SetBackgroundColor(fClient->GetResourcePool()->GetTipBgndColor());
00156 
00157    AddFrame(fLabel, fL1 = new TGLayoutHints(kLHintsLeft | kLHintsTop,
00158                                             2, 3, 0, 0));
00159    MapSubwindows();
00160    Resize(GetDefaultSize());
00161 
00162    fWindow = 0;
00163    fPad    = 0;
00164    fBox    = box;
00165    fDelay = new TTipDelayTimer(this, delayms);
00166 }
00167 
00168 //______________________________________________________________________________
00169 TGToolTip::TGToolTip(Int_t x, Int_t y, const char *text, Long_t delayms)
00170    : TGCompositeFrame(gClient->GetDefaultRoot(), 10, 10, kTempFrame | kHorizontalFrame | kRaisedFrame)
00171 {
00172    // Create a tool tip on global coordinates x, y.
00173    // text is the tool tip one-liner and delayms is the delay in ms before
00174    // the tool tip is shown.
00175 
00176    SetWindowAttributes_t attr;
00177    attr.fMask             = kWAOverrideRedirect | kWASaveUnder;
00178    attr.fOverrideRedirect = kTRUE;
00179    attr.fSaveUnder        = kTRUE;
00180 
00181    gVirtualX->ChangeWindowAttributes(fId, &attr);
00182    SetBackgroundColor(fClient->GetResourcePool()->GetTipBgndColor());
00183 
00184    fLabel = new TGLabel(this, text);
00185    fLabel->SetBackgroundColor(fClient->GetResourcePool()->GetTipBgndColor());
00186 
00187    AddFrame(fLabel, fL1 = new TGLayoutHints(kLHintsLeft | kLHintsTop,
00188                                             2, 3, 0, 0));
00189    MapSubwindows();
00190    Resize(GetDefaultSize());
00191 
00192    fWindow = 0;
00193    fPad    = 0;
00194    fBox    = 0;
00195    fX      = x;
00196    fY      = y;
00197    fDelay = new TTipDelayTimer(this, delayms);
00198 }
00199 
00200 //______________________________________________________________________________
00201 TGToolTip::~TGToolTip()
00202 {
00203    // Delete a tool tip object.
00204 
00205    delete fDelay;
00206    delete fLabel;
00207    delete fL1;
00208 }
00209 
00210 //______________________________________________________________________________
00211 void TGToolTip::DrawBorder()
00212 {
00213    // Draw border of tool tip window.
00214 
00215    gVirtualX->DrawLine(fId, GetShadowGC()(), 0, 0, fWidth-2, 0);
00216    gVirtualX->DrawLine(fId, GetShadowGC()(), 0, 0, 0, fHeight-2);
00217    gVirtualX->DrawLine(fId, GetBlackGC()(),  0, fHeight-1, fWidth-1, fHeight-1);
00218    gVirtualX->DrawLine(fId, GetBlackGC()(),  fWidth-1, fHeight-1, fWidth-1, 0);
00219 }
00220 
00221 //______________________________________________________________________________
00222 void TGToolTip::Show(Int_t x, Int_t y)
00223 {
00224    // Show tool tip window.
00225 
00226    Move(x, y);
00227    MapWindow();
00228    RaiseWindow();
00229 
00230    Long_t args[2];
00231    args[0] = x;
00232    args[1] = y;
00233 
00234    Emit("Show(Int_t,Int_t)", args);
00235 }
00236 
00237 //______________________________________________________________________________
00238 void TGToolTip::Hide()
00239 {
00240    // Hide tool tip window. Use this method to hide the tool tip in a client
00241    // class.
00242 
00243    UnmapWindow();
00244 
00245    fDelay->Remove();
00246 
00247    Emit("Hide()");
00248 }
00249 
00250 //______________________________________________________________________________
00251 void TGToolTip::Reset()
00252 {
00253    // Reset tool tip popup delay timer. Use this method to activate tool tip
00254    // in a client class.
00255 
00256    fDelay->Reset();
00257    gSystem->AddTimer(fDelay);
00258 
00259    Emit("Reset()");
00260 }
00261 
00262 //______________________________________________________________________________
00263 void TGToolTip::Reset(const TVirtualPad *parent)
00264 {
00265    // Reset tool tip popup delay timer. Use this method to activate tool tip
00266    // in a client class. Use this method for graphics objects drawn in a
00267    // TCanvas, also the tool tip must have been created with the ctor
00268    // taking the TBox as argument.
00269 
00270    fPad = parent;
00271 
00272    fDelay->Reset();
00273    gSystem->AddTimer(fDelay);
00274 }
00275 
00276 //______________________________________________________________________________
00277 Bool_t TGToolTip::HandleTimer(TTimer *)
00278 {
00279    // If tool tip delay timer times out show tool tip window.
00280 
00281    Int_t    x = 0, y = 0, px1 = 0, px2 = 0, py1 = 0, py2 = 0;
00282    Window_t wtarget;
00283 
00284    if (fWindow) {
00285       gVirtualX->TranslateCoordinates(fWindow->GetId(), GetParent()->GetId(),
00286                                       fX == -1 ? Int_t(fWindow->GetWidth() >> 1) : fX,
00287                                       fY == -1 ? Int_t(fWindow->GetHeight()) : fY,
00288                                       x, y, wtarget);
00289    } else if(fPad) {
00290       if (fBox) {
00291          px1 = fPad->XtoAbsPixel(fBox->GetX1());
00292          px2 = fPad->XtoAbsPixel(fBox->GetX2());
00293          py1 = fPad->YtoAbsPixel(fBox->GetY1());
00294          py2 = fPad->YtoAbsPixel(fBox->GetY2());
00295       } else {
00296          px1 = fPad->XtoAbsPixel(fPad->GetX1());
00297          px2 = fPad->XtoAbsPixel(fPad->GetX2());
00298          py1 = fPad->YtoAbsPixel(fPad->GetY1());
00299          py2 = fPad->YtoAbsPixel(fPad->GetY2());
00300       }
00301       gVirtualX->TranslateCoordinates(gVirtualX->GetWindowID(fPad->GetCanvasID()),
00302                                       GetParent()->GetId(),
00303                                       px1 + ((px2-px1) >> 1), py1,
00304                                       x, y, wtarget);
00305    } else {
00306       x = fX;
00307       y = fY;
00308    }
00309 
00310    Int_t move = 0;
00311    Window_t dum1, dum2;
00312    UInt_t mask = 0;
00313    Int_t mx, my;
00314    UInt_t screenW = fClient->GetDisplayWidth();
00315    UInt_t screenH = fClient->GetDisplayHeight();
00316 
00317    gVirtualX->QueryPointer(gVirtualX->GetDefaultRootWindow(),
00318                            dum1, dum2, mx, my, mx, my, mask);
00319 
00320    fLabel->SetWrapLength(-1);
00321    Resize(GetDefaultSize());
00322 
00323    // don't allow tooltip text lines longer than half the screen size
00324    if (fWidth > (screenW/2))
00325       fLabel->SetWrapLength((screenW/2)-15);
00326    Resize(GetDefaultSize());
00327 
00328    if (x + fWidth > screenW) {
00329       x = screenW - fWidth;
00330       move += 1;
00331    }
00332 
00333    if (y+4 + GetHeight() > screenH) {
00334       y = screenH - (fHeight + 25);
00335       move += 2;
00336    }
00337 
00338    // check if the mouse is inside the tooltip (may happen after
00339    // adjusting the position when out of screen) and place the tooltip
00340    // on the other side of the mouse pointer
00341    TGRectangle rect(x, y, x+fWidth, y+fHeight);
00342    if (rect.Contains(mx, my)) {
00343       if (move == 1) { // left
00344          if (fWidth+15 < (UInt_t)mx)
00345             x = mx - fWidth - 15;
00346          else if (my + fHeight+15 < screenH)
00347             y = my + 15;
00348          else if (fHeight+15 < (UInt_t)my)
00349             y = my - fHeight - 15;
00350       }
00351       else if (move == 2) { // up
00352          if (mx + fWidth+15 < screenW)
00353             x = mx + 15;
00354          else if (fHeight+15 < (UInt_t)my)
00355             y = my - fHeight - 15;
00356          else if (fWidth+15 < (UInt_t)mx)
00357             x = mx - fWidth - 15;
00358       }
00359       else { // up & left, right, down, ...
00360          if (my + fHeight+15 < screenH)
00361             y = my + 15;
00362          else if (mx + fWidth+15 < screenW)
00363             x = mx + 15;
00364          else if (fWidth+15 < (UInt_t)mx)
00365             x = mx - fWidth - 15;
00366          else if (fHeight+15 < (UInt_t)my)
00367             y = my - fHeight - 15;
00368       }
00369    }
00370 
00371    Show(x, y+4);
00372 
00373    fDelay->Remove();
00374 
00375    return kTRUE;
00376 }
00377 
00378 //______________________________________________________________________________
00379 void TGToolTip::SetText(const char *new_text)
00380 {
00381    // Set new tool tip text.
00382 
00383    fLabel->SetText(new TGString(new_text));
00384    Resize(GetDefaultSize());
00385 }
00386 
00387 //______________________________________________________________________________
00388 void TGToolTip::SetDelay(Long_t delayms)
00389 {
00390    // Set delay in milliseconds.
00391 
00392    fDelay->SetTime(delayms);
00393 }
00394 
00395 //______________________________________________________________________________
00396 void TGToolTip::SetPosition(Int_t x, Int_t y)
00397 {
00398    // Set popup position within specified frame (as specified in the ctor).
00399    // To get back default behaviour (in the middle just below the designated
00400    // frame) set position to -1,-1.
00401 
00402    fX = x;
00403    fY = y;
00404 
00405    if (fX < -1)
00406       fX = 0;
00407    if (fY < -1)
00408       fY = 0;
00409 
00410    if (fWindow) {
00411       if (fX > (Int_t) fWindow->GetWidth())
00412          fX = fWindow->GetWidth();
00413       if (fY > (Int_t) fWindow->GetHeight())
00414          fY = fWindow->GetHeight();
00415    }
00416 }
00417 
00418 //______________________________________________________________________________
00419 const TGString *TGToolTip::GetText() const
00420 {
00421    // Get the tool tip text.
00422 
00423    return fLabel->GetText();
00424 
00425 }

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