TGListBox.cxx

Go to the documentation of this file.
00001 // @(#)root/gui:$Id: TGListBox.cxx 36119 2010-10-06 14:10:03Z rdm $
00002 // Author: Fons Rademakers   12/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 // TGListBox, TGLBContainer, TGLBEntry and TGTextLBEntry                //
00026 //                                                                      //
00027 // A listbox is a box, possibly with scrollbar, containing entries.     //
00028 // Currently entries are simple text strings (TGTextLBEntry).           //
00029 // A TGListBox looks a lot like a TGCanvas. It has a TGViewPort         //
00030 // containing a TGLBContainer which contains the entries and it also    //
00031 // has a vertical scrollbar which becomes visible if there are more     //
00032 // items than fit in the visible part of the container.                 //
00033 //                                                                      //
00034 // The TGListBox is user callable. The other classes are service        //
00035 // classes of the listbox.                                              //
00036 //                                                                      //
00037 // Selecting an item in the listbox will generate the event:            //
00038 // kC_COMMAND, kCM_LISTBOX, listbox id, item id.                        //
00039 //                                                                      //
00040 //////////////////////////////////////////////////////////////////////////
00041 
00042 #include "TGPicture.h"
00043 #include "TGListBox.h"
00044 #include "TGScrollBar.h"
00045 #include "TGResourcePool.h"
00046 #include "TSystem.h"
00047 #include "Riostream.h"
00048 #include <stdlib.h>
00049 
00050 
00051 const TGFont *TGTextLBEntry::fgDefaultFont = 0;
00052 TGGC         *TGTextLBEntry::fgDefaultGC = 0;
00053 
00054 ClassImp(TGLBEntry)
00055 ClassImp(TGTextLBEntry)
00056 ClassImp(TGLineLBEntry)
00057 ClassImp(TGLBContainer)
00058 ClassImp(TGListBox)
00059 
00060 //______________________________________________________________________________
00061 TGLBEntry::TGLBEntry(const TGWindow *p, Int_t id, UInt_t options, Pixel_t back) :
00062              TGFrame(p, 10, 10, options | kOwnBackground, back)
00063 {
00064    // Base class entry constructor.
00065 
00066    fActive = kFALSE;
00067    fEntryId = id;
00068    fBkcolor = back;
00069    fEditDisabled = kEditDisable | kEditDisableGrab;
00070 
00071    SetWindowName();
00072 }
00073 
00074 //______________________________________________________________________________
00075 void TGLBEntry::Activate(Bool_t a)
00076 {
00077    // Toggle active state of listbox entry.
00078 
00079    if (fActive == a) return;
00080    fActive = a;
00081    DoRedraw();
00082 }
00083 
00084 //______________________________________________________________________________
00085 void TGLBEntry::Toggle()
00086 {
00087    // Toggle active state of listbox entry.
00088 
00089    fActive = !fActive;
00090    DoRedraw();
00091 }
00092 
00093 
00094 //////////////////////////////////////////////////////////////////////////
00095 //                                                                      //
00096 // TGTextLBEntry                                                        //
00097 //                                                                      //
00098 // Text string listbox entries.                                         //
00099 // A TGTextLBEntry is for TGListBox internal use.                       //
00100 //                                                                      //
00101 //////////////////////////////////////////////////////////////////////////
00102 
00103 //______________________________________________________________________________
00104 TGTextLBEntry::TGTextLBEntry(const TGWindow *p, TGString *s, Int_t id,
00105       GContext_t norm, FontStruct_t font, UInt_t options, ULong_t back) :
00106    TGLBEntry(p, id, options, back)
00107 {
00108    // Create a text listbox entry. The TGString is adopted.
00109 
00110    fText        = s;
00111    fTextChanged = kTRUE;
00112    fFontStruct  = font;
00113    fNormGC      = norm;
00114 
00115    int max_ascent, max_descent;
00116 
00117    if (fText) fTWidth  = gVirtualX->TextWidth(fFontStruct, fText->GetString(), fText->GetLength());
00118    gVirtualX->GetFontProperties(fFontStruct, max_ascent, max_descent);
00119    fTHeight = max_ascent + max_descent;
00120    Resize(fTWidth, fTHeight + 1);
00121    fEditDisabled = kEditDisable | kEditDisableGrab;
00122    SetWindowName();
00123 }
00124 
00125 //______________________________________________________________________________
00126 TGTextLBEntry::~TGTextLBEntry()
00127 {
00128    // Delete text listbox entry.
00129 
00130    if (fText) delete fText;
00131 }
00132 
00133 //______________________________________________________________________________
00134 void TGTextLBEntry::DrawCopy(Handle_t id, Int_t x, Int_t y)
00135 {
00136    // Draw text listbox entry on window/pixmap.
00137 
00138    int max_ascent, max_descent;
00139 
00140    y += (fHeight - fTHeight) >> 1;
00141 
00142    gVirtualX->GetFontProperties(fFontStruct, max_ascent, max_descent);
00143 
00144    if (fActive) {
00145       gVirtualX->SetForeground(fNormGC, fgDefaultSelectedBackground );
00146       gVirtualX->FillRectangle(id,fNormGC, x, y, fWidth, fHeight);
00147       gVirtualX->SetForeground(fNormGC, fClient->GetResourcePool()->GetSelectedFgndColor());
00148       fText->Draw(id, fNormGC, x + 3, y + max_ascent);
00149    } else {
00150       gVirtualX->SetForeground(fNormGC, fBkcolor);
00151       gVirtualX->FillRectangle(id, fNormGC, x, y, fWidth, fHeight);
00152       gVirtualX->SetForeground(fNormGC, GetForeground());
00153       fText->Draw(id, fNormGC, x + 3, y + max_ascent);
00154    }
00155 }
00156 
00157 //______________________________________________________________________________
00158 void TGTextLBEntry::DoRedraw()
00159 {
00160    // Redraw text listbox entry.
00161 
00162    if (fId) DrawCopy(fId, 0, 0);
00163 }
00164 
00165 //______________________________________________________________________________
00166 void TGTextLBEntry::SetText(TGString *new_text)
00167 {
00168    // Set or change text in text entry.
00169 
00170    if (fText) delete fText;
00171    fText = new_text;
00172    fTextChanged = kTRUE;
00173 
00174    int max_ascent, max_descent;
00175    fTWidth = gVirtualX->TextWidth(fFontStruct, fText->GetString(), fText->GetLength());
00176    gVirtualX->GetFontProperties(fFontStruct, max_ascent, max_descent);
00177    fTHeight = max_ascent + max_descent;
00178 
00179    Resize(fTWidth + 3, fTHeight + 1);
00180 
00181    DoRedraw();
00182 }
00183 
00184 //______________________________________________________________________________
00185 FontStruct_t TGTextLBEntry::GetDefaultFontStruct()
00186 {
00187    // Return default font structure in use for a text listbox entry.
00188 
00189    if (!fgDefaultFont)
00190       fgDefaultFont = gClient->GetResourcePool()->GetDefaultFont();
00191    return fgDefaultFont->GetFontStruct();
00192 }
00193 
00194 //______________________________________________________________________________
00195 const TGGC &TGTextLBEntry::GetDefaultGC()
00196 {
00197    // Return default graphics context in use for a text listbox entry.
00198 
00199    if (!fgDefaultGC)
00200       fgDefaultGC = new TGGC(*gClient->GetResourcePool()->GetFrameGC());
00201    return *fgDefaultGC;
00202 }
00203 
00204 //////////////////////////////////////////////////////////////////////////
00205 //                                                                      //
00206 // TGLineLBEntry                                                        //
00207 //                                                                      //
00208 // Line style and width listbox entries.                                //
00209 //                                                                      //
00210 //////////////////////////////////////////////////////////////////////////
00211 
00212 //______________________________________________________________________________
00213 TGLineLBEntry::TGLineLBEntry(const TGWindow *p, Int_t id, const char *str,
00214                              UInt_t w, Style_t style, UInt_t options, ULong_t back) :
00215    TGTextLBEntry(p, new TGString(str), id, GetDefaultGC()(),
00216                  GetDefaultFontStruct(), options, back)
00217 {
00218    // Create the line style listbox entry.
00219 
00220    GCValues_t gcv;
00221 
00222    gcv.fMask =  kGCLineStyle | kGCLineWidth | kGCFillStyle | kGCDashList;
00223    fLineWidth = gcv.fLineWidth  = w;
00224    gcv.fFillStyle  = kFillSolid;
00225    gcv.fDashLen = 2;
00226    gcv.fDashOffset = 0;
00227    memcpy(gcv.fDashes, "\x5\x5", 3);
00228    gcv.fLineStyle = kLineOnOffDash;
00229    fLineGC = fClient->GetGC(&gcv, kTRUE);
00230    SetLineStyle(style);
00231 
00232    int max_ascent, max_descent;
00233 
00234    fTWidth  = gVirtualX->TextWidth(GetDefaultFontStruct(), "8", 1);
00235    fTWidth += 15;                     // for drawing
00236    gVirtualX->GetFontProperties(GetDefaultFontStruct(),
00237                                 max_ascent, max_descent);
00238    fTHeight = max_ascent + max_descent;
00239 
00240    Resize(fTWidth, fTHeight + 1);
00241    fEditDisabled = kEditDisable | kEditDisableGrab;
00242    SetWindowName();
00243 }
00244 
00245 //______________________________________________________________________________
00246 TGLineLBEntry::~TGLineLBEntry()
00247 {
00248    // Delete line style listbox entry.
00249 
00250    fClient->FreeGC(fLineGC);
00251 }
00252 
00253 //______________________________________________________________________________
00254 void  TGLineLBEntry::Update(TGLBEntry *e)
00255 {
00256    // Update line style listbox entry.
00257 
00258    TGTextLBEntry::Update(e);
00259 
00260    fClient->FreeGC(fLineGC);
00261    fLineGC = ((TGLineLBEntry *)e)->GetLineGC();
00262    fLineGC->AddReference();
00263 }
00264 
00265 //______________________________________________________________________________
00266 void TGLineLBEntry::SetLineStyle(Style_t linestyle)
00267 {
00268    // Set the line style corresponding to the TPad line styles.
00269 
00270    static const char* dashed = "\x3\x3";
00271    static const char* dotted= "\x1\x2";
00272    static const char* dasheddotted = "\x3\x4\x1\x4";
00273    static const char* ls05 = "\x5\x3\x1\x3";
00274    static const char* ls06 = "\x5\x3\x1\x3\x1\x3\x1\x3";
00275    static const char* ls07 = "\x5\x5";
00276    static const char* ls08 = "\x5\x3\x1\x3\x1\x3";
00277    static const char* ls09 = "\x20\x5";
00278    static const char* ls10 = "\x20\x10\x1\x10";
00279 
00280 
00281    if (linestyle <= 1)  {
00282       fLineGC->SetLineStyle(kLineSolid);
00283    } else {
00284       switch (linestyle) {
00285          case 2:
00286             fLineGC->SetDashList(dashed, 2);
00287             break;
00288          case 3:
00289             fLineGC->SetDashList(dotted, 2);
00290             break;
00291          case 4:
00292             fLineGC->SetDashList(dasheddotted, 4);
00293             break;
00294          case 5:
00295             fLineGC->SetDashList(ls05, 4);
00296             break;
00297          case 6:
00298             fLineGC->SetDashList(ls06, 8);
00299             break;
00300          case 7:
00301             fLineGC->SetDashList(ls07, 2);
00302             break;
00303          case 8:
00304             fLineGC->SetDashList(ls08, 6);
00305             break;
00306          case 9:
00307             fLineGC->SetDashList(ls09, 2);
00308             break;
00309          case 10:
00310             fLineGC->SetDashList(ls10, 4);
00311             break;
00312       }
00313    }
00314    fLineGC->SetCapStyle(0); // flat cap
00315    fLineStyle = linestyle;
00316 }
00317 
00318 //______________________________________________________________________________
00319 void TGLineLBEntry::SetLineWidth(Int_t width)
00320 {
00321    // Set or change line witdh in an entry.
00322 
00323    fLineWidth = width;
00324    fLineGC->SetLineWidth(fLineWidth);
00325 }
00326 
00327 //______________________________________________________________________________
00328 void TGLineLBEntry::DrawCopy(Handle_t id, Int_t x, Int_t y)
00329 {
00330    // Draw copy on window/pixmap.
00331 
00332    TGTextLBEntry::DrawCopy(id, x, y);
00333    if (!strcmp(TGTextLBEntry::GetTitle(),"None")) return;
00334    if (fActive) {
00335       gVirtualX->SetForeground(fLineGC->GetGC(),
00336                                fClient->GetResourcePool()->GetSelectedFgndColor());
00337    } else {
00338       gVirtualX->SetForeground(fLineGC->GetGC(),
00339                                fClient->GetResourcePool()->GetBlackColor());
00340    }
00341    gVirtualX->DrawLine(id, fLineGC->GetGC(), x + fTWidth + 5, y + fHeight/2,
00342                        x + fWidth - 5, y + fHeight/2);
00343 }
00344 
00345 //______________________________________________________________________________
00346 void TGLineLBEntry::DoRedraw()
00347 {
00348    // Redraw line style listbox entry.
00349 
00350    if (fId) DrawCopy(fId, 0, 0);
00351 }
00352 
00353 //////////////////////////////////////////////////////////////////////////
00354 //                                                                      //
00355 // TGIconLBEntry                                                        //
00356 //                                                                      //
00357 // Icon + text listbox entry.                                           //
00358 //                                                                      //
00359 //////////////////////////////////////////////////////////////////////////
00360 
00361 //______________________________________________________________________________
00362 TGIconLBEntry::TGIconLBEntry(const TGWindow *p, Int_t id, const char *str,
00363                              const TGPicture *pic,
00364                              UInt_t /*w*/, Style_t /*style*/, UInt_t options, ULong_t back) :
00365    TGTextLBEntry(p, new TGString(str), id, GetDefaultGC()(),
00366                  GetDefaultFontStruct(), options, back)
00367 {
00368    // Create the icon & text listbox entry.
00369 
00370    int max_ascent, max_descent;
00371 
00372    fPicture = pic;
00373    if (fPicture) {
00374       fTWidth += fPicture->GetWidth() + 4;
00375       ((TGPicture *)pic)->AddReference();
00376    }
00377    else
00378       fTWidth += 20;
00379    gVirtualX->GetFontProperties(GetDefaultFontStruct(),
00380                                 max_ascent, max_descent);
00381    fTHeight = max_ascent + max_descent;
00382    if (fPicture && fPicture->GetHeight() > fTHeight)
00383       fTHeight = fPicture->GetHeight();
00384 
00385    Resize(fTWidth, fTHeight + 1);
00386    fEditDisabled = kEditDisable | kEditDisableGrab;
00387    SetWindowName();
00388 }
00389 
00390 //______________________________________________________________________________
00391 TGIconLBEntry::~TGIconLBEntry()
00392 {
00393    // Delete icon & text listbox entry.
00394 
00395    fClient->FreePicture(fPicture);
00396 }
00397 
00398 //______________________________________________________________________________
00399 void  TGIconLBEntry::Update(TGLBEntry *e)
00400 {
00401    // Update icon & text listbox entry.
00402 
00403    TGTextLBEntry::Update(e);
00404 }
00405 
00406 //______________________________________________________________________________
00407 void TGIconLBEntry::DrawCopy(Handle_t id, Int_t x, Int_t y)
00408 {
00409    // Draw copy on window/pixmap.
00410 
00411    Int_t off_x = 0;
00412    if (fPicture) {
00413       fPicture->Draw(id, fNormGC, x + 2, y);
00414       off_x = fPicture->GetWidth() + 4;
00415    }
00416    TGTextLBEntry::DrawCopy(id, x + off_x, y);
00417 }
00418 
00419 //______________________________________________________________________________
00420 void TGIconLBEntry::DoRedraw()
00421 {
00422    // Redraw icon & text listbox entry.
00423 
00424    if (fId) DrawCopy(fId, 0, 0);
00425 }
00426 
00427 //___________________________________________________________________________
00428 void TGIconLBEntry::SetPicture(const TGPicture *pic)
00429 {
00430    // Change the icon of listbox entry containing icon & text.
00431 
00432    fClient->FreePicture(fPicture);
00433 
00434    ((TGPicture *)pic)->AddReference();
00435 
00436    fPicture   = pic;
00437 }
00438 
00439 /////////////////////////////////////////////////////////////////////////////////
00440 class TGLBFrameElement : public TGFrameElement {
00441 public:
00442    TGLBFrameElement(TGFrame *f, TGLayoutHints *l) : TGFrameElement(f, l) {}
00443    virtual ~TGLBFrameElement() {}
00444 
00445    Bool_t IsSortable() const { return kTRUE; }
00446    Int_t  Compare(const TObject *obj) const {
00447       if (!fFrame->InheritsFrom(TGTextLBEntry::Class())) {
00448          return 0;
00449       }
00450       TGTextLBEntry *f1 = (TGTextLBEntry*)fFrame;
00451       TGTextLBEntry *f2 = (TGTextLBEntry *) ((TGFrameElement *) obj)->fFrame;
00452 
00453 
00454       double d1, d2;
00455       const char *t1 = f1->GetText()->Data();
00456       const char *t2 = f2->GetText()->Data();
00457 
00458       if ((d1 = atof(t1)) && (d2 = atof(t2))) {
00459          return (d1 > d2);
00460       } else {
00461          return strcmp(t1, t2);
00462       }
00463       return 0;
00464    }
00465 };
00466 
00467 //////////////////////////////////////////////////////////////////////////
00468 //                                                                      //
00469 // TGLBContainer                                                        //
00470 //                                                                      //
00471 // A Composite frame that contains a list of TGLBEnties.                //
00472 // A TGLBContainer is for TGListBox internal use.                       //
00473 //                                                                      //
00474 //////////////////////////////////////////////////////////////////////////
00475 
00476 //______________________________________________________________________________
00477 TGLBContainer::TGLBContainer(const TGWindow *p, UInt_t w, UInt_t h,
00478                              UInt_t options, ULong_t back) :
00479    TGContainer(p, w, h, options, back)
00480 {
00481    // Create a listbox container.
00482 
00483    fLastActive = 0;
00484    fMsgWindow  = p;
00485    fMultiSelect = kFALSE;
00486    fChangeStatus = kFALSE;
00487 
00488    SetWindowName();
00489    fEditDisabled = kEditDisableGrab | kEditDisableBtnEnable | kEditDisableKeyEnable;
00490 }
00491 
00492 //______________________________________________________________________________
00493 TGLBContainer::~TGLBContainer()
00494 {
00495    // Delete the listbox container.
00496 
00497    Cleanup();
00498 }
00499 
00500 //______________________________________________________________________________
00501 void TGLBContainer::Layout()
00502 {
00503    // Layout container
00504 
00505    TGContainer::Layout();
00506    TGFrame::Resize(fListBox->GetViewPort()->GetWidth(), fHeight);
00507 }
00508 
00509 //______________________________________________________________________________
00510 void TGLBContainer::DoRedraw()
00511 {
00512    // redraw
00513 
00514    return TGContainer::DoRedraw();
00515 }
00516 
00517 //______________________________________________________________________________
00518 void TGLBContainer::AddEntry(TGLBEntry *lbe, TGLayoutHints *lhints)
00519 {
00520    // Add listbox entry with hints to container. To show entry call
00521    // MapSubwindows() and Layout().
00522 
00523    // DEPRECATED: the color should always be set in the TGLBEntry ctor
00524    //lbe->SetBackgroundColor(fgWhitePixel);
00525 
00526    TGLBFrameElement *nw = new TGLBFrameElement(lbe, lhints ? lhints : fgDefaultHints);
00527    fList->Add(nw);
00528    ClearViewPort();
00529 }
00530 
00531 //______________________________________________________________________________
00532 void TGLBContainer::InsertEntry(TGLBEntry *lbe, TGLayoutHints *lhints, Int_t afterID)
00533 {
00534    // Insert listbox entry after specified entry with id afterID. If afterID = -1
00535    // then add entry at head of list. To show entry call MapSubwindows() and
00536    // Layout().
00537 
00538    // DEPRECATED: the color should always be set in the TGLBEntry ctor
00539    //lbe->SetBackgroundColor(fgWhitePixel);
00540 
00541    TGLBEntry      *e;
00542    TGFrameElement *el, *nw;
00543    TIter next(fList);
00544 
00545    while ((el = (TGFrameElement *) next())) {
00546       e = (TGLBEntry *) el->fFrame;
00547       if (e->EntryId() == afterID) break;
00548    }
00549 
00550    if (!el && afterID != -1) {
00551       nw = new TGLBFrameElement(lbe, lhints ? lhints : fgDefaultHints);
00552       fList->Add(nw);
00553    } else {
00554       nw = new TGLBFrameElement(lbe, lhints);
00555       nw->fFrame  = lbe;
00556       nw->fLayout = lhints;
00557       nw->fState  = 1;
00558       //lbe->SetFrameElement(nw);
00559 
00560       if (afterID == -1)
00561          fList->AddFirst(nw);
00562       else
00563          fList->AddAfter(el, nw);
00564    }
00565    ClearViewPort();
00566 }
00567 
00568 //______________________________________________________________________________
00569 void TGLBContainer::AddEntrySort(TGLBEntry *lbe, TGLayoutHints *lhints)
00570 {
00571    // Insert listbox entry before the list box entry with a higher id.
00572    // To show entry call MapSubwindows() and Layout().
00573 
00574    // DEPRECATED: the color should always be set in the TGLBEntry ctor
00575    //lbe->SetBackgroundColor(fgWhitePixel);
00576 
00577    TGLBEntry      *e;
00578    TGFrameElement *el, *nw;
00579    TIter next(fList);
00580 
00581    while ((el = (TGFrameElement *) next())) {
00582       e = (TGLBEntry *) el->fFrame;
00583       if (e->EntryId() > lbe->EntryId()) break;
00584    }
00585 
00586    if (!el) {
00587       nw = new TGLBFrameElement(lbe, lhints ? lhints : fgDefaultHints);
00588       fList->Add(nw);
00589    } else {
00590       nw = new TGLBFrameElement(lbe, lhints);
00591       nw->fFrame  = lbe;
00592       nw->fLayout = lhints;
00593       nw->fState  = 1;
00594       //lbe->SetFrameElement(nw);
00595 
00596       fList->AddBefore(el, nw);
00597    }
00598    ClearViewPort();
00599 }
00600 
00601 //______________________________________________________________________________
00602 void TGLBContainer::RemoveEntry(Int_t id)
00603 {
00604    // Remove the entry with specified id from the listbox container.
00605    // To update the listbox call Layout().
00606 
00607    TGLBEntry      *e;
00608    TGFrameElement *el;
00609    TGLayoutHints  *l;
00610 
00611    TIter next(fList);
00612 
00613    while ((el = (TGFrameElement *) next())) {
00614       e = (TGLBEntry *) el->fFrame;
00615       l = el->fLayout;
00616       if (e->EntryId() == id) {
00617          if (fLastActive == e) fLastActive = 0;
00618          e->DestroyWindow();
00619          fList->Remove(el);  // avoid calling RemoveFrame(e)
00620          delete el;          // item
00621          delete e;
00622          delete l;
00623          break;
00624       }
00625    }
00626    ClearViewPort();
00627 }
00628 
00629 //______________________________________________________________________________
00630 void TGLBContainer::RemoveEntries(Int_t from_ID, Int_t to_ID)
00631 {
00632    // Remove entries from from_ID to to_ID (including).
00633    // To update the listbox call Layout().
00634 
00635    TGLBEntry      *e;
00636    TGFrameElement *el;
00637    TGLayoutHints  *l;
00638 
00639    TIter next(fList);
00640 
00641    while ((el = (TGFrameElement *) next())) {
00642       e = (TGLBEntry *) el->fFrame;
00643       l = el->fLayout;
00644       if ((e->EntryId() >= from_ID) && (e->EntryId() <= to_ID)) {
00645          if (fLastActive == e) fLastActive = 0;
00646          e->DestroyWindow();
00647          fList->Remove(el);  // avoid calling RemoveFrame(e)
00648          delete el;          // idem
00649          delete e;
00650          delete l;
00651       }
00652    }
00653    ClearViewPort();
00654 }
00655 
00656 //______________________________________________________________________________
00657 void TGLBContainer::RemoveAll()
00658 {
00659    // Remove all entries in this container.
00660 
00661    TGLBEntry      *e;
00662    TGFrameElement *el;
00663    TGLayoutHints  *l;
00664 
00665    TIter next(fList);
00666 
00667    while ((el = (TGFrameElement *) next())) {
00668       e = (TGLBEntry *) el->fFrame;
00669       l = el->fLayout;
00670       if (fLastActive == e) fLastActive = 0;
00671       e->DestroyWindow();
00672       fList->Remove(el);  // avoid calling RemoveFrame(e)
00673       delete el;          // item
00674       delete e;
00675       delete l;
00676    }
00677    ClearViewPort();
00678 }
00679 
00680 //______________________________________________________________________________
00681 TGLBEntry *TGLBContainer::Select(Int_t id)
00682 {
00683    // Select the entry with the specified id.
00684    // Returns the selected TGLBEntry.
00685 
00686    return Select(id, kTRUE);
00687 }
00688 
00689 //______________________________________________________________________________
00690 TGLBEntry *TGLBContainer::Select(Int_t id, Bool_t sel)
00691 {
00692    // Select / deselect the entry with the specified id.
00693    // Returns the selected TGLBEntry.
00694 
00695    TGLBEntry      *f;
00696    TGFrameElement *el;
00697 
00698    if (!fMultiSelect && fLastActive) {
00699       fLastActive->Activate(kFALSE);
00700       fLastActive = 0;
00701    }
00702 
00703    TIter next(fList);
00704    while ((el = (TGFrameElement *) next())) {
00705       f = (TGLBEntry *) el->fFrame;
00706       if (f->EntryId() == id) {
00707          f->Activate(sel);
00708          if (fMultiSelect == kFALSE && sel == kTRUE) {
00709             fLastActive = f;
00710             fLastActiveEl = el;
00711          }
00712          ClearViewPort();
00713          return f;
00714       }
00715    }
00716 
00717    return 0;
00718 }
00719 
00720 //______________________________________________________________________________
00721 Int_t TGLBContainer::GetSelected() const
00722 {
00723    // Returns id of selected entry. In case of no selected entry or
00724    // if multi selection is switched on returns -1.
00725 
00726    if (fLastActive == 0) return -1;
00727    return fLastActive->EntryId();
00728 }
00729 
00730 //______________________________________________________________________________
00731 Bool_t TGLBContainer::GetSelection(Int_t id)
00732 {
00733    // Returns kTrue if entry id is selected.
00734 
00735    TGLBEntry     *f;
00736    TGFrameElement *el;
00737 
00738    TIter next(fList);
00739    while ((el = (TGFrameElement *) next())) {
00740       f = (TGLBEntry *) el->fFrame;
00741       if (f->EntryId() == id)
00742          return f->IsActive();
00743    }
00744 
00745    return kFALSE;
00746 }
00747 
00748 //______________________________________________________________________________
00749 void TGLBContainer::GetSelectedEntries(TList *selected)
00750 {
00751    // Adds all selected entries (TGLBEntry) of the list box into
00752    // the list selected.
00753 
00754    TGLBEntry      *f;
00755    TGFrameElement *el;
00756 
00757    TIter next(fList);
00758    while ((el = (TGFrameElement *) next())) {
00759       f = (TGLBEntry *) el->fFrame;
00760       if (f->IsActive()) {
00761          selected->Add(f);
00762       }
00763    }
00764 }
00765 
00766 //______________________________________________________________________________
00767 void TGLBContainer::SetMultipleSelections(Bool_t multi)
00768 {
00769    // Enables and disables multiple selections of entries.
00770 
00771    TGFrameElement *el;
00772 
00773    fMultiSelect = multi;
00774    if (!fMultiSelect) {
00775       // deselect all entries
00776       TIter next(fList);
00777       while ((el = (TGFrameElement *) next())) {
00778          ((TGLBEntry *)(el->fFrame))->Activate(kFALSE);
00779       }
00780    }
00781    fLastActive = 0;
00782    fLastActiveEl = 0;
00783    ClearViewPort();
00784 }
00785 
00786 //______________________________________________________________________________
00787 TGVScrollBar *TGLBContainer::GetVScrollbar() const
00788 {
00789    // Return a pointer to vertical scroll bar.
00790 
00791    return fListBox ? fListBox->GetVScrollbar() : 0;
00792 }
00793 
00794 //______________________________________________________________________________
00795 void TGLBContainer::SetVsbPosition(Int_t newPos)
00796 {
00797    // Set new vertical scroll bar position.
00798 
00799    TGVScrollBar *vb = GetVScrollbar();
00800 
00801    if (vb && vb->IsMapped()) {
00802       vb->SetPosition(newPos);
00803    }
00804 }
00805 
00806 //______________________________________________________________________________
00807 Bool_t TGLBContainer::HandleButton(Event_t *event)
00808 {
00809    // Handle mouse button event in the listbox container.
00810 
00811    int xf0, yf0, xff, yff;
00812 
00813    TGLBEntry *f;
00814    TGFrameElement *el;
00815    TGLBEntry *last = fLastActive;
00816 
00817    TGPosition pos = GetPagePosition();
00818    Int_t x = pos.fX + event->fX;
00819    Int_t y = pos.fY + event->fY;
00820    Bool_t activate = kFALSE;
00821 
00822    // do not handle "context menu button" during guibuilding
00823    if (fClient->IsEditable() && (event->fCode == kButton3)) {
00824       return kTRUE;
00825    }
00826 
00827    TGVScrollBar *vb = GetVScrollbar();
00828 
00829    if ((event->fCode == kButton4) && vb){
00830       // scroll 2 lines up (a button down is always followed by a button up)
00831       Int_t newpos = vb->GetPosition() - 1;
00832       if (newpos < 0) newpos = 0;
00833       vb->SetPosition(newpos);
00834       ClearViewPort();
00835       return kTRUE;
00836    }
00837    if ((event->fCode == kButton5) && vb) {
00838       // scroll 2 lines down (a button down is always followed by a button up)
00839       Int_t newpos = vb->GetPosition() + 1;
00840       vb->SetPosition(newpos);
00841       ClearViewPort();
00842       return kTRUE;
00843    }
00844 
00845    gVirtualX->SetInputFocus(fId);
00846 
00847    if (fMultiSelect) {
00848       if (event->fType == kButtonPress) {
00849          TIter next(fList);
00850          while ((el = (TGFrameElement *) next())) {
00851             f = (TGLBEntry *) el->fFrame;
00852             xf0 = f->GetX();
00853             yf0 = f->GetY();
00854             xff = xf0 + f->GetWidth();
00855             yff = yf0 + f->GetHeight();
00856 
00857             activate = fMapSubwindows ? (f->GetId() == (Window_t)event->fUser[0]) :
00858                         (x > xf0) && (x < xff) && (y > yf0) &&  (y < yff);
00859 
00860             if (activate)  {
00861                fLastActive = f;
00862                fLastActiveEl = el;
00863                f->Toggle();
00864                fChangeStatus = f->IsActive() ? 1 : 0;
00865                SendMessage(fMsgWindow, MK_MSG(kC_CONTAINER, kCT_ITEMCLICK),
00866                            f->EntryId(), 0);
00867                break;
00868             }
00869          }
00870       } else {
00871          fChangeStatus = -1;
00872       }
00873    } else {
00874       if (event->fType == kButtonPress) {
00875          if (fLastActive) {
00876             fLastActive->Activate(kFALSE);
00877             fLastActive = 0;
00878          }
00879          TIter next(fList);
00880          while ((el = (TGFrameElement *) next())) {
00881             f = (TGLBEntry *) el->fFrame;
00882             xf0 = f->GetX();
00883             yf0 = f->GetY();
00884             xff = xf0 + f->GetWidth();
00885             yff = yf0 + f->GetHeight();
00886 
00887             activate = fMapSubwindows ? (f->GetId() == (Window_t)event->fUser[0]) :
00888                         (x > xf0) && (x < xff) && (y > yf0) &&  (y < yff) && !f->IsActive();
00889 
00890             if (activate)  {
00891                f->Activate(kTRUE);
00892                fLastActive = f;
00893                fLastActiveEl = el;
00894             } else {
00895                f->Activate(kFALSE);
00896             }
00897          }
00898       } else {
00899          if (fLastActive) {
00900             f = fLastActive;
00901             SendMessage(fMsgWindow, MK_MSG(kC_CONTAINER, kCT_ITEMCLICK),
00902                         f->EntryId(), 0);
00903          }
00904       }
00905    }
00906    if (event->fType == kButtonRelease) {
00907       fScrolling = kFALSE;
00908       gSystem->RemoveTimer(fScrollTimer);
00909    }
00910    if (fChangeStatus || (last != fLastActive))
00911       ClearViewPort();
00912    // trick to avoid mouse move events between the mouse click
00913    // and the unmapping...
00914    if (fListBox->GetParent()->InheritsFrom("TGComboBoxPopup"))
00915       fListBox->GetContainer()->RemoveInput(kPointerMotionMask);
00916    return kTRUE;
00917 }
00918 
00919 //______________________________________________________________________________
00920 Bool_t TGLBContainer::HandleDoubleClick(Event_t *)
00921 {
00922    // Handle double click mouse event in the listbox container.
00923 
00924    if (!fMultiSelect) {
00925       if (fLastActive) {
00926          TGLBEntry *f = fLastActive;
00927          SendMessage(fMsgWindow, MK_MSG(kC_CONTAINER, kCT_ITEMDBLCLICK),
00928                      f->EntryId(), 0);
00929       }
00930    }
00931    return kTRUE;
00932 }
00933 
00934 //______________________________________________________________________________
00935 Bool_t TGLBContainer::HandleMotion(Event_t *event)
00936 {
00937    // Handle mouse motion event in listbox container.
00938 
00939    int xf0, yf0, xff, yff;
00940 
00941    static Long64_t was = gSystem->Now();
00942    Long64_t now = gSystem->Now();
00943 
00944    if ((now-was) < 50) return kFALSE;
00945    was = now;
00946 
00947    TGLBEntry *f;
00948    TGFrameElement *el;
00949    TGPosition pos = GetPagePosition();
00950    TGDimension dim = GetPageDimension();
00951    Int_t x = pos.fX + event->fX;
00952    Int_t y = pos.fY + event->fY;
00953    Bool_t activate = kFALSE;
00954    TGLBEntry *last = fLastActive;
00955 
00956    if (fMultiSelect) {
00957 
00958       if ((event->fY < 10) || (event->fY > Int_t(dim.fHeight) - 10)) {
00959          if (!fScrolling) {
00960             fScrollTimer->Reset();
00961             gSystem->AddTimer(fScrollTimer);
00962          }
00963          fScrolling = kTRUE;
00964       }
00965       else if (fChangeStatus >= 0) {
00966          TIter next(fList);
00967          while ((el = (TGFrameElement *) next())) {
00968             f = (TGLBEntry *) el->fFrame;
00969             xf0 = f->GetX();
00970             yf0 = f->GetY();
00971             xff = xf0 + f->GetWidth();
00972             yff = yf0 + f->GetHeight();
00973             activate = fMapSubwindows ? (f->GetId() == (Window_t)event->fUser[0]) :
00974                         (x > xf0) && (x < xff) && (y > yf0) &&  (y < yff);
00975 
00976             if (activate) {
00977                if (fChangeStatus != (f->IsActive() ? 1 : 0)) {
00978                   f->Toggle();
00979                   ClearViewPort();
00980                   SendMessage(fMsgWindow, MK_MSG(kC_CONTAINER, kCT_ITEMCLICK),
00981                               f->EntryId(), 0);
00982                }
00983                break;
00984             }
00985          }
00986       }
00987    } else if (fListBox->GetParent()->InheritsFrom("TGComboBoxPopup")) {
00988       TIter next(fList);
00989       while ((el = (TGFrameElement *) next())) {
00990          f = (TGLBEntry *) el->fFrame;
00991          xf0 = f->GetX();
00992          yf0 = f->GetY();
00993          xff = xf0 + f->GetWidth();
00994          yff = yf0 + f->GetHeight();
00995 
00996          activate = fMapSubwindows ? (f->GetId() == (Window_t)event->fUser[0]) :
00997                         (x > xf0) && (x < xff) && (y > yf0) &&  (y < yff)  && !f->IsActive();
00998 
00999          if (activate)  {
01000             f->Activate(kTRUE);
01001             fLastActive = f;
01002          } else {
01003             f->Activate(kFALSE);
01004          }
01005          if (last != fLastActive) {
01006             ClearViewPort();
01007          }
01008       }
01009    }
01010    return kTRUE;
01011 }
01012 
01013 //______________________________________________________________________________
01014 void TGLBContainer::OnAutoScroll()
01015 {
01016    // Autoscroll while close to & beyond  The Wall
01017 
01018    TGFrameElement* el = 0;
01019    TGLBEntry *f = 0;
01020    Int_t yf0, yff;
01021    Bool_t changed = kFALSE;
01022 
01023    TGDimension dim = GetPageDimension();
01024    TGPosition pos = GetPagePosition();
01025 
01026    Window_t  dum1, dum2;
01027    Event_t   ev;
01028    ev.fType  = kButtonPress;
01029    Int_t     x, y;
01030 
01031    // Where's the cursor?
01032    gVirtualX->QueryPointer(fId,dum1,dum2,ev.fXRoot,ev.fYRoot,x,y,ev.fState);
01033    TGVScrollBar *vb = GetVScrollbar();
01034    if (y > 0 && y < 10) {
01035       // scroll 1 line up
01036       Int_t newpos = vb->GetPosition() - 1;
01037       if (newpos < 0) newpos = 0;
01038       vb->SetPosition(newpos);
01039       changed = kTRUE;
01040    }
01041    else if (y > (Int_t)dim.fHeight - 10 && y < (Int_t)dim.fHeight) {
01042       // scroll 1 line down
01043       Int_t newpos = vb->GetPosition() + 1;
01044       vb->SetPosition(newpos);
01045       changed = kTRUE;
01046    }
01047    if (changed && fChangeStatus >= 0) {
01048       pos = GetPagePosition();
01049       TIter next(fList);
01050       while ((el = (TGFrameElement *) next())) {
01051          f = (TGLBEntry *) el->fFrame;
01052          yf0 = f->GetY();
01053          yff = yf0 + f->GetHeight();
01054          if ((y + pos.fY > yf0) && (y + pos.fY < yff)) {
01055             if (fChangeStatus != (f->IsActive() ? 1 : 0)) {
01056                f->Toggle();
01057                ClearViewPort();
01058                SendMessage(fMsgWindow, MK_MSG(kC_CONTAINER, kCT_ITEMCLICK),
01059                            f->EntryId(), 0);
01060             }
01061             break;
01062          }
01063       }
01064    }
01065 }
01066 
01067 //______________________________________________________________________________
01068 void TGLBContainer::ActivateItem(TGFrameElement *el)
01069 {
01070    // Activate item.
01071 
01072    TGContainer::ActivateItem(el);
01073    fLastActive = (TGLBEntry *)el->fFrame;
01074 }
01075 
01076 //______________________________________________________________________________
01077 Int_t TGLBContainer::GetPos(Int_t id)
01078 {
01079    // Returns the position in the list box of the entry id.
01080    // The first position has position no 0. Returns -1 if entry id
01081    // is not in the list of entries.
01082 
01083    Int_t          pos = 0;
01084    TGLBEntry      *f;
01085    TGFrameElement *el;
01086 
01087    TIter next(fList);
01088    while ((el = (TGFrameElement *) next())) {
01089       f = (TGLBEntry *) el->fFrame;
01090       if (f->EntryId() == id)
01091          return pos;
01092       pos++;
01093    }
01094 
01095    return -1;
01096 }
01097 
01098 
01099 //////////////////////////////////////////////////////////////////////////
01100 //                                                                      //
01101 // TGListBox                                                            //
01102 //                                                                      //
01103 // A listbox contains a container frame which is viewed through a       //
01104 // viewport. If the container is larger than the viewport than a        //
01105 // vertical scrollbar is added.                                         //
01106 //                                                                      //
01107 // Selecting an item in the listbox will generate the event:            //
01108 // kC_COMMAND, kCM_LISTBOX, listbox id, item id.                        //
01109 //                                                                      //
01110 //////////////////////////////////////////////////////////////////////////
01111 
01112 //______________________________________________________________________________
01113 TGListBox::TGListBox(const TGWindow *p, Int_t id,
01114                      UInt_t options, ULong_t back) :
01115    TGCompositeFrame(p, 10, 10, options, back)
01116 {
01117    // Create a listbox.
01118 
01119    fMsgWindow = p;
01120    fWidgetId  = id;
01121 
01122    fItemVsize = 1;
01123    fIntegralHeight = kTRUE;
01124 
01125    InitListBox();
01126 }
01127 
01128 //______________________________________________________________________________
01129 TGListBox::~TGListBox()
01130 {
01131    // Delete a listbox widget.
01132 
01133    if (!MustCleanup()) {
01134       delete fVScrollbar;
01135       delete fVport;
01136       delete fLbc;
01137    }
01138 }
01139 
01140 //______________________________________________________________________________
01141 void TGListBox::InitListBox()
01142 {
01143    // Initiate the internal classes of a list box.
01144 
01145    fVport = new TGViewPort(this, 6, 6, kChildFrame | kOwnBackground, fgWhitePixel);
01146    fVScrollbar = new TGVScrollBar(this, kDefaultScrollBarWidth, 6);
01147    fLbc = new TGLBContainer(fVport, 10, 10, kVerticalFrame, fgWhitePixel);
01148    fLbc->fViewPort = fVport;
01149    fLbc->Associate(this);
01150    fLbc->SetListBox(this);
01151    SetContainer(fLbc);
01152 
01153    AddFrame(fVport, 0);
01154    AddFrame(fVScrollbar, 0);
01155 
01156    fVScrollbar->Associate(this);
01157 
01158    fVScrollbar->AddInput(kButtonPressMask | kButtonReleaseMask |
01159                          kPointerMotionMask);
01160    fLbc->RemoveInput(kPointerMotionMask);
01161    fLbc->AddInput(kButtonPressMask | kButtonReleaseMask | kButtonMotionMask);
01162 
01163    fVport->SetEditDisabled(kEditDisable | kEditDisableGrab);
01164    fVScrollbar->SetEditDisabled(kEditDisable | kEditDisableGrab | kEditDisableBtnEnable);
01165    fLbc->SetEditDisabled(kEditDisableGrab | kEditDisableBtnEnable | kEditDisableKeyEnable);
01166    fEditDisabled = kEditDisableLayout;
01167 
01168    // layout manager is not used
01169    delete fLayoutManager;
01170    fLayoutManager = 0;
01171 }
01172 
01173 //______________________________________________________________________________
01174 void TGListBox::DrawBorder()
01175 {
01176    // Draw borders of the list box widget.
01177 
01178    switch (fOptions & (kSunkenFrame | kRaisedFrame | kDoubleBorder)) {
01179       case kSunkenFrame | kDoubleBorder:
01180          gVirtualX->DrawLine(fId, GetShadowGC()(), 0, 0, fWidth-2, 0);
01181          gVirtualX->DrawLine(fId, GetShadowGC()(), 0, 0, 0, fHeight-2);
01182          gVirtualX->DrawLine(fId, GetBlackGC()(), 1, 1, fWidth-3, 1);
01183          gVirtualX->DrawLine(fId, GetBlackGC()(), 1, 1, 1, fHeight-3);
01184 
01185          gVirtualX->DrawLine(fId, GetHilightGC()(), 0, fHeight-1, fWidth-1, fHeight-1);
01186          gVirtualX->DrawLine(fId, GetHilightGC()(), fWidth-1, fHeight-1, fWidth-1, 0);
01187          gVirtualX->DrawLine(fId, GetBckgndGC()(),  1, fHeight-2, fWidth-2, fHeight-2);
01188          gVirtualX->DrawLine(fId, GetBckgndGC()(),  fWidth-2, 1, fWidth-2, fHeight-2);
01189          break;
01190 
01191       default:
01192          TGCompositeFrame::DrawBorder();
01193          break;
01194    }
01195 }
01196 
01197 //______________________________________________________________________________
01198 void TGListBox::AddEntry(TGString *s, Int_t id)
01199 {
01200    // Add entry with specified string and id to listbox. The id will be
01201    // used in the event processing routine when the item is selected.
01202    // The string will be adopted by the listbox.
01203 
01204    TGTextLBEntry *lbe;
01205    TGLayoutHints *lhints;
01206 
01207    lbe = new TGTextLBEntry(fLbc, s, id);
01208    lhints = new TGLayoutHints(kLHintsExpandX | kLHintsTop);
01209    fItemVsize = TMath::Max(fItemVsize, lbe->GetDefaultHeight());
01210    fLbc->AddEntry(lbe, lhints);
01211 }
01212 
01213 //______________________________________________________________________________
01214 void TGListBox::AddEntry(const char *s, Int_t id)
01215 {
01216    // Add entry with specified string and id to listbox. The id will be
01217    // used in the event processing routine when the item is selected.
01218 
01219    AddEntry(new TGString(s), id);
01220 }
01221 
01222 //______________________________________________________________________________
01223 void TGListBox::AddEntry(TGLBEntry *lbe, TGLayoutHints *lhints)
01224 {
01225    // Add specified TGLBEntry and TGLayoutHints to listbox. The
01226    // entry and layout will be adopted and later deleted by the listbox.
01227 
01228    fItemVsize = TMath::Max(fItemVsize, lbe->GetDefaultHeight());
01229    fLbc->AddEntry(lbe, lhints);
01230 }
01231 
01232 //______________________________________________________________________________
01233 void TGListBox::AddEntrySort(TGString *s, Int_t id)
01234 {
01235    // Add entry with specified string and id to listbox sorted by increasing id.
01236    // This sorting works proberly only if EntrySort functions are used to add
01237    // entries without mixing them with other add or insert functions.  The id will be
01238    // used in the event processing routine when the item is selected.
01239    // The string will be adopted by the listbox.
01240 
01241    TGTextLBEntry *lbe;
01242    TGLayoutHints *lhints;
01243 
01244    lbe = new TGTextLBEntry(fLbc, s, id);
01245    lhints = new TGLayoutHints(kLHintsExpandX | kLHintsTop);
01246    fItemVsize = TMath::Max(fItemVsize, lbe->GetDefaultHeight());
01247    fLbc->AddEntrySort(lbe, lhints);
01248 }
01249 
01250 //______________________________________________________________________________
01251 void TGListBox::AddEntrySort(const char *s, Int_t id)
01252 {
01253    // Add entry with specified string and id to listbox sorted by increasing id.
01254    // This sorting works proberly only if EntrySort functions are used to add
01255    // entries without mixing them with other add or insert functions. The id will be
01256    // used in the event processing routine when the item is selected.
01257 
01258    AddEntrySort(new TGString(s), id);
01259 }
01260 
01261 //______________________________________________________________________________
01262 void TGListBox::AddEntrySort(TGLBEntry *lbe, TGLayoutHints *lhints)
01263 {
01264    // Add specified TGLBEntry and TGLayoutHints to listbox sorted by increasing id.
01265    // This sorting works proberly only if EntrySort functions are used to add
01266    // entries without mixing them with other add or insert functions. The
01267    // entry and layout will be adopted and later deleted by the listbox.
01268 
01269    fItemVsize = TMath::Max(fItemVsize, lbe->GetDefaultHeight());
01270    fLbc->AddEntrySort(lbe, lhints);
01271 }
01272 
01273 //______________________________________________________________________________
01274 void TGListBox::InsertEntry(TGString *s, Int_t id, Int_t afterID)
01275 {
01276    // Insert entry with specified string and id behind the entry with afterID.
01277    // The string will be adopted and later deleted by the listbox.
01278 
01279    TGTextLBEntry *lbe;
01280    TGLayoutHints *lhints;
01281 
01282    lbe = new TGTextLBEntry(fLbc, s, id);
01283    lhints = new TGLayoutHints(kLHintsExpandX | kLHintsTop);
01284    fItemVsize = TMath::Max(fItemVsize, lbe->GetDefaultHeight());
01285    fLbc->InsertEntry(lbe, lhints, afterID);
01286 }
01287 
01288 //______________________________________________________________________________
01289 void TGListBox::InsertEntry(const char *s, Int_t id, Int_t afterID)
01290 {
01291    // Insert entry with specified string and id behind the entry with afterID.
01292 
01293    InsertEntry(new TGString(s), id, afterID);
01294 }
01295 
01296 //______________________________________________________________________________
01297 void TGListBox::NewEntry(const char *s)
01298 {
01299    // method used to add entry via context menu
01300 
01301    Int_t selected = fLbc->GetSelected();
01302 
01303    // no selected entry or the last entry
01304    if ((selected < 0) || (selected == GetNumberOfEntries())) {
01305       AddEntry(s, GetNumberOfEntries()+1);
01306    } else {
01307       InsertEntry(s, GetNumberOfEntries()+1, selected);
01308    }
01309    Layout();
01310 }
01311 
01312 //______________________________________________________________________________
01313 void TGListBox:: RemoveEntry(Int_t id)
01314 {
01315    // remove entry with id.
01316    // If id = -1 - the selected entry/entries is/are removed.
01317    //
01318 
01319    if (id >= 0) {
01320       fLbc->RemoveEntry(id);
01321       Layout();
01322       return;
01323    }
01324    if (!fLbc->GetMultipleSelections()) {
01325       fLbc->RemoveEntry(fLbc->GetSelected());
01326       Layout();
01327       return;
01328    }
01329    TList li;
01330    fLbc->GetSelectedEntries(&li);
01331    TGLBEntry *e;
01332    TIter next(&li);
01333 
01334    while ((e = (TGLBEntry*)next())) {
01335       fLbc->RemoveEntry(e->EntryId());
01336    }
01337    Layout();
01338 }
01339 
01340 //______________________________________________________________________________
01341 void TGListBox::RemoveAll()
01342 {
01343    // Remove all entries.
01344 
01345    fLbc->RemoveAll();
01346    Layout();
01347 }
01348 
01349 //______________________________________________________________________________
01350 void TGListBox::RemoveEntries(Int_t from_ID, Int_t to_ID)
01351 {
01352    // Remove a range of entries defined by from_ID and to_ID.
01353 
01354    fLbc->RemoveEntries(from_ID, to_ID);
01355    Layout();
01356 }
01357 
01358 //______________________________________________________________________________
01359 void TGListBox::InsertEntry(TGLBEntry *lbe, TGLayoutHints *lhints, int afterID)
01360 {
01361    // Insert the specified TGLBEntry and layout hints behind afterID.
01362    // The entry and layout will be adopted and later deleted by the listbox.
01363 
01364    fItemVsize = TMath::Max(fItemVsize, lbe->GetDefaultHeight());
01365    fLbc->InsertEntry(lbe, lhints, afterID);
01366 }
01367 
01368 //______________________________________________________________________________
01369 TGLBEntry *TGListBox::GetEntry(Int_t id) const
01370 {
01371    // Returns list box entry with specified id.
01372 
01373    TIter next(fLbc->GetList());
01374    TGFrameElement *el;
01375 
01376    while ((el = (TGFrameElement *)next())) {
01377       TGLBEntry *lbe = (TGLBEntry *)el->fFrame;
01378       if (lbe->EntryId() == id) return lbe;
01379    }
01380    return 0;
01381 }
01382 
01383 //______________________________________________________________________________
01384 void TGListBox::SetTopEntry(Int_t id)
01385 {
01386    // Scroll the entry with id to the top of the listbox.
01387 
01388    Int_t idPos;
01389 
01390    idPos = fLbc->GetPos(id);
01391 
01392    // id not found in list of entries
01393    if (idPos < 0)
01394       return;
01395 
01396    // call layout to define the range of the scroll bars
01397    Layout();
01398 
01399    // SetPosition will send a message which will handled by
01400    // the function TGListBox::ProcessMessage. Now ProcessMessage will
01401    // set the viewport. SetPosition also will check that the idPos is
01402    // not out of range.
01403    fVScrollbar->SetPosition(idPos);
01404 }
01405 
01406 //______________________________________________________________________________
01407 void TGListBox::Resize(UInt_t w, UInt_t h)
01408 {
01409    // Resize the listbox widget. If fIntegralHeight is true make the height
01410    // an integral number of the maximum height of a single entry.
01411 
01412    if (fIntegralHeight)
01413       h = TMath::Max(fItemVsize, ((h - (fBorderWidth << 1)) / fItemVsize) * fItemVsize)
01414                      + (fBorderWidth << 1);
01415 
01416    TGCompositeFrame::Resize(w, h);
01417    DoRedraw();
01418 }
01419 
01420 //______________________________________________________________________________
01421 void TGListBox::MoveResize(Int_t x, Int_t y, UInt_t w, UInt_t h)
01422 {
01423    // Move and resize the listbox widget.
01424 
01425    if (fIntegralHeight)
01426       h = TMath::Max(fItemVsize, ((h - (fBorderWidth << 1)) / fItemVsize) * fItemVsize)
01427                      + (fBorderWidth << 1);
01428    TGCompositeFrame::MoveResize(x, y, w, h);
01429    DoRedraw();
01430 }
01431 
01432 //______________________________________________________________________________
01433 TGDimension TGListBox::GetDefaultSize() const
01434 {
01435    // Return default size of listbox widget.
01436 
01437    UInt_t h;
01438 
01439    if (fIntegralHeight)
01440       h = TMath::Max(fItemVsize, ((fHeight - (fBorderWidth << 1)) / fItemVsize) * fItemVsize)
01441                      + (fBorderWidth << 1);
01442    else
01443       h = fHeight;
01444 
01445    return TGDimension(fWidth, h);
01446 }
01447 
01448 //______________________________________________________________________________
01449 void TGListBox::Layout()
01450 {
01451    // Layout the listbox components.
01452 
01453    TGFrame *container;
01454    UInt_t   cw, ch, tch;
01455    Bool_t   need_vsb;
01456 
01457    need_vsb = kFALSE;
01458 
01459    container = fVport->GetContainer();
01460 
01461    // test whether we need vertical scrollbar or not
01462 
01463    cw = fWidth - (fBorderWidth << 1);
01464    ch = fHeight - (fBorderWidth << 1);
01465 
01466    container->SetWidth(cw);
01467    container->SetHeight(ch);
01468 
01469    if (container->GetDefaultHeight() > ch) {
01470       need_vsb = kTRUE;
01471       cw -= fVScrollbar->GetDefaultWidth();
01472       if ((Int_t) cw < 0) {
01473          Warning("Layout", "width would become too small, setting to 10");
01474          cw = 10;
01475       }
01476       container->SetWidth(cw);
01477    }
01478 
01479    fVport->MoveResize(fBorderWidth, fBorderWidth, cw, ch);
01480    container->Layout();
01481 
01482    tch = TMath::Max(container->GetDefaultHeight(), ch);
01483    container->SetHeight(0); // force a resize in TGFrame::Resize
01484    container->Resize(cw, tch);
01485    //fVport->SetPos(0, 0);
01486 
01487    if (need_vsb) {
01488       fVScrollbar->MoveResize(cw+fBorderWidth, fBorderWidth, fVScrollbar->GetDefaultWidth(), ch);
01489       fVScrollbar->MapWindow();
01490    } else {
01491       fVScrollbar->UnmapWindow();
01492       fVScrollbar->SetPosition(0);
01493    }
01494 
01495    fVScrollbar->SetRange(container->GetHeight()/fItemVsize, fVport->GetHeight()/fItemVsize);
01496    //fClient->NeedRedraw(container);
01497    ((TGContainer *)container)->ClearViewPort();
01498 }
01499 
01500 //______________________________________________________________________________
01501 void TGListBox::SortByName(Bool_t ascend)
01502 {
01503    // Sort entries by name
01504 
01505    fLbc->GetList()->Sort(ascend);
01506    Layout();
01507    fLbc->ClearViewPort();
01508 }
01509 
01510 //______________________________________________________________________________
01511 Int_t TGListBox::GetSelected() const
01512 {
01513    // Return id of selected listbox item.
01514 
01515    TGLBContainer *ct = (TGLBContainer *) fVport->GetContainer();
01516    return ct->GetSelected();
01517 }
01518 
01519 //______________________________________________________________________________
01520 void TGListBox::GetSelectedEntries(TList *selected)
01521 {
01522    // Adds all selected entries (TGLBEntry) of the list box into
01523    // the list selected.
01524 
01525    fLbc->GetSelectedEntries(selected);
01526 }
01527 
01528 //______________________________________________________________________________
01529 void TGListBox::ChangeBackground(Pixel_t back)
01530 {
01531    // Change background to all entries
01532 
01533    fBackground = back;
01534 
01535    TIter next(fLbc->GetList());
01536    TGFrameElement *el;
01537 
01538    while ((el = (TGFrameElement *)next())) {
01539       TGLBEntry *lbe = (TGLBEntry *)el->fFrame;
01540       lbe->SetBackgroundColor(back);
01541    }
01542    fLbc->ClearViewPort();
01543 }
01544 
01545 //______________________________________________________________________________
01546 Bool_t TGListBox::ProcessMessage(Long_t msg, Long_t parm1, Long_t)
01547 {
01548    // Process messages generated by the listbox container and forward
01549    // messages to the listbox message handling window.
01550 
01551    switch (GET_MSG(msg)) {
01552       case kC_VSCROLL:
01553          switch (GET_SUBMSG(msg)) {
01554             case kSB_SLIDERTRACK:
01555             case kSB_SLIDERPOS:
01556                fVport->SetVPos(Int_t(-parm1 * fItemVsize));
01557                break;
01558          }
01559          break;
01560 
01561       case kC_CONTAINER:
01562          switch (GET_SUBMSG(msg)) {
01563             case kCT_ITEMCLICK:
01564                {
01565                   SendMessage(fMsgWindow, MK_MSG(kC_COMMAND, kCM_LISTBOX),
01566                               fWidgetId, parm1);
01567                   if (GetMultipleSelections()) SelectionChanged();
01568                   TGLBEntry *entry = GetSelectedEntry();
01569                   if (entry) {
01570                      if (entry->InheritsFrom(TGTextLBEntry::Class())) {
01571                         const char *text;
01572                         text = ((TGTextLBEntry*)entry)->GetText()->GetString();
01573                         Selected(text);
01574                      }
01575                      Selected(fWidgetId, (Int_t) parm1);
01576                      Selected((Int_t) parm1);
01577                   }
01578                }
01579                break;
01580             case kCT_ITEMDBLCLICK:
01581                {
01582                   TGLBEntry *entry = GetSelectedEntry();
01583                   if (entry) {
01584                      if (entry->InheritsFrom(TGTextLBEntry::Class())) {
01585                         const char *text;
01586                         text = ((TGTextLBEntry*)entry)->GetText()->GetString();
01587                         DoubleClicked(text);
01588                      }
01589                      DoubleClicked(fWidgetId, (Int_t) parm1);
01590                      DoubleClicked((Int_t) parm1);
01591                   }
01592                }
01593                break;
01594          }
01595          break;
01596 
01597       default:
01598          break;
01599 
01600    }
01601    return kTRUE;
01602 }
01603 
01604 //______________________________________________________________________________
01605 void TGListBox::Selected(Int_t widgetId, Int_t id)
01606 {
01607    // Emit Selected signal with list box id and entry id.
01608 
01609    Long_t args[2];
01610 
01611    args[0] = widgetId;
01612    args[1] = id;
01613 
01614    Emit("Selected(Int_t,Int_t)", args);
01615 }
01616 
01617 //______________________________________________________________________________
01618 void TGListBox::DoubleClicked(Int_t widgetId, Int_t id)
01619 {
01620    // Emit DoubleClicked signal with list box id and entry id.
01621 
01622    Long_t args[2];
01623 
01624    args[0] = widgetId;
01625    args[1] = id;
01626 
01627    Emit("DoubleClicked(Int_t,Int_t)", args);
01628 }
01629 
01630 //______________________________________________________________________________
01631 TGLBEntry *TGListBox::FindEntry(const char *name) const
01632 {
01633    // Find entry by name.
01634 
01635    TList *list = fLbc->GetList();
01636    TGFrameElement *el = (TGFrameElement *)list->First();
01637    while (el) {
01638       if (el->fFrame->GetTitle() == TString(name))
01639          return (TGLBEntry *)el->fFrame;
01640       el = (TGFrameElement *)list->After(el);
01641    }
01642    return 0;
01643 }
01644 
01645 //______________________________________________________________________________
01646 void TGListBox::SavePrimitive(ostream &out, Option_t *option /*= ""*/)
01647 {
01648     // Save a list box widget as a C++ statement(s) on output stream out.
01649 
01650    if (fBackground != GetWhitePixel()) SaveUserColor(out, option);
01651 
01652    out << endl << "   // list box" << endl;
01653 
01654    out<<"   TGListBox *";
01655    out << GetName() << " = new TGListBox(" << fParent->GetName();
01656 
01657    if (fBackground == GetWhitePixel()) {
01658       if (GetOptions() == (kSunkenFrame | kDoubleBorder)) {
01659          if (fWidgetId == -1) {
01660             out <<");" << endl;
01661          } else {
01662             out << "," << fWidgetId << ");" << endl;
01663          }
01664       } else {
01665          out << "," << fWidgetId << "," << GetOptionString() <<");" << endl;
01666       }
01667    } else {
01668       out << "," << fWidgetId << "," << GetOptionString() << ",ucolor);" << endl;
01669    }
01670    if (option && strstr(option, "keep_names"))
01671       out << "   " << GetName() << "->SetName(\"" << GetName() << "\");" << endl;
01672 
01673    if (!fLbc->GetList()) return;
01674 
01675    TGFrameElement *el;
01676    TIter next(fLbc->GetList());
01677 
01678    while ((el = (TGFrameElement *) next())) {
01679       out << "   " << GetName() << "->AddEntry(";
01680       el->fFrame->SavePrimitive(out, option);
01681       out << ");"<< endl;
01682    }
01683    out << "   " << GetName() << "->Resize(" << GetWidth() << "," << GetHeight()
01684        << ");" << endl;
01685 }
01686 
01687 //______________________________________________________________________________
01688 void TGTextLBEntry::SavePrimitive(ostream &out, Option_t * /*= ""*/)
01689 {
01690    // Save a list box entry widget as a C++ statement(s) on output stream out.
01691 
01692    TString content = GetText()->GetString();
01693    content.ReplaceAll('\\', "\\\\");
01694    content.ReplaceAll("\"", "\\\"");
01695    char quote = '"';
01696    out << quote << content << quote << "," << EntryId();
01697 }

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