TGCanvas.cxx

Go to the documentation of this file.
00001 // @(#)root/gui:$Id: TGCanvas.cxx 35582 2010-09-22 13:38:27Z bellenot $
00002 // Author: Fons Rademakers   11/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 // TGCanvas and TGViewPort and TGContainer                              //
00026 //                                                                      //
00027 // A TGCanvas is a frame containing two scrollbars (a horizontal and    //
00028 // a vertical) and a viewport. The viewport acts as the window through  //
00029 // which we look at the contents of the container frame.                //
00030 //                                                                      //
00031 // A TGContainer frame manages a content area. It can display and       //
00032 // control a hierarchy of multi-column items, and provides the ability  //
00033 // to add new items at any time. By default it doesn't map subwindows   //
00034 // which are items of the container. In this case subwindow must        //
00035 // provide DrawCopy method, see for example TGLVEntry class.            //
00036 // It is also possible to use option which allow to map subwindows.     //
00037 // This option has much slower drawing speed in case of more than 1000  //
00038 // items placed in container. To activate this option the fMapSubwindows//
00039 // data member must be set to kTRUE (for example TTVLVContainer class)  //
00040 //                                                                      //
00041 //   The TGContainer class can handle the keys:                         //
00042 //                                                                      //
00043 //    o  F7, Ctnrl-F - activate search dialog                           //
00044 //    o  F3, Ctnrl-G - continue search                                  //
00045 //    o  End - go to the last item in container                         //
00046 //    o  Home - go to the first item in container                       //
00047 //    o  PageUp,PageDown,arrow keys - navigate inside container         //
00048 //    o  Return/Enter - equivalent to double click of the mouse button  //
00049 //    o  Contrl-A - select/activate all items.                          //
00050 //    o  Space - invert selection.                                      //
00051 //                                                                      //
00052 //////////////////////////////////////////////////////////////////////////
00053 
00054 #include "TGCanvas.h"
00055 #include "TGListView.h"
00056 #include "TGScrollBar.h"
00057 #include "TTimer.h"
00058 #include "KeySymbols.h"
00059 #include "TSystem.h"
00060 #include "TGTextEditDialogs.h"
00061 #include "TGMsgBox.h"
00062 #include "TGResourcePool.h"
00063 #include "TList.h"
00064 #include "TClass.h"
00065 #include "TGListView.h"
00066 #include "TGMimeTypes.h"
00067 #include "TKey.h"
00068 #include "TKeyMapFile.h"
00069 #include "TGDNDManager.h"
00070 #include "Riostream.h"
00071 #include <stdlib.h>
00072 
00073 
00074 TGGC *TGContainer::fgLineGC = 0;
00075 
00076 const Int_t kAutoScrollFudge = 10;
00077 const Int_t kAcceleration[kAutoScrollFudge+1] = {1,1,1,2,3,4,6,7,8,16,32};
00078 const Int_t kKeyboardTime = 700;
00079 
00080 ClassImp(TGCanvas)
00081 ClassImp(TGViewPort)
00082 ClassImp(TGContainer)
00083 
00084 
00085 //______________________________________________________________________________
00086 class TGContainerKeyboardTimer : public TTimer {
00087 
00088 private:
00089    TGContainer   *fContainer;
00090 public:
00091    TGContainerKeyboardTimer(TGContainer *t) : TTimer(kKeyboardTime) { fContainer = t; }
00092    Bool_t Notify();
00093 };
00094 
00095 //______________________________________________________________________________
00096 Bool_t TGContainerKeyboardTimer::Notify()
00097 {
00098    // single shot timer
00099 
00100    fContainer->SearchPattern();
00101    Reset();
00102    if (gSystem) gSystem->RemoveTimer(this);
00103    return kFALSE;
00104 }
00105 
00106 //______________________________________________________________________________
00107 class TGContainerScrollTimer : public TTimer {
00108 
00109 private:
00110    TGContainer   *fContainer;
00111 public:
00112    TGContainerScrollTimer(TGContainer *t) : TTimer(50) { fContainer = t; }
00113    Bool_t Notify();
00114 };
00115 
00116 //______________________________________________________________________________
00117 Bool_t TGContainerScrollTimer::Notify()
00118 {
00119    // on-timeout
00120 
00121    fContainer->OnAutoScroll();
00122    Reset();
00123    return kFALSE;
00124 }
00125 
00126 
00127 //______________________________________________________________________________
00128 TGViewPort::TGViewPort(const TGWindow *p, UInt_t w, UInt_t h,
00129                        UInt_t options, ULong_t back) :
00130     TGCompositeFrame(p, w, h, options, back)
00131 {
00132    // Create a viewport object.
00133 
00134    fContainer = 0;
00135    fX0 = fY0  = 0;
00136 
00137    AddInput(kStructureNotifyMask);
00138    SetWindowName();
00139    fEditDisabled = kEditDisable | kEditDisableGrab;
00140 }
00141 
00142 //______________________________________________________________________________
00143 void TGViewPort::SetContainer(TGFrame *f)
00144 {
00145    // Add container frame to the viewport. We must make sure that the added
00146    // container is at least a TGCompositeFrame (TGCanvas::AddFrame depends
00147    // on it).
00148 
00149    if (!f) {
00150       RemoveFrame(fContainer);
00151       fContainer = 0;
00152       return;
00153    }
00154 
00155    if (!fContainer) {
00156       fContainer = f;
00157       AddFrame(f, 0);
00158       fContainer->SetEditDisabled(fContainer->GetEditDisabled() | kEditDisableGrab);
00159 
00160       if (fContainer->InheritsFrom(TGContainer::Class())) {
00161          ((TGContainer*)fContainer)->fViewPort = this;
00162          if (fParent->InheritsFrom(TGCanvas::Class())) {
00163             ((TGContainer*)fContainer)->fCanvas = (TGCanvas*)fParent;
00164          }
00165       }
00166    }
00167 }
00168 
00169 //______________________________________________________________________________
00170 void TGViewPort::SetHPos(Int_t xpos)
00171 {
00172    // Moves content of container frame in horizontal direction.
00173 
00174    Int_t diff;
00175 
00176    if (!fContainer) return;
00177 
00178    if (!fContainer->InheritsFrom(TGContainer::Class())) {
00179       fContainer->Move(fX0 = xpos, fY0);
00180       return;
00181    } else {
00182       if (((TGContainer*)fContainer)->fMapSubwindows) {
00183          fContainer->Move(fX0 = xpos, fY0);
00184          return;
00185       }
00186    }
00187 
00188    if (-xpos < 0) return;
00189    else diff = xpos - fX0;
00190    UInt_t adiff = TMath::Abs(diff);
00191 
00192    if (!diff) return;
00193 
00194    fX0 = xpos;
00195 
00196    if (adiff < fWidth) {
00197       if (diff < 0) {
00198          gVirtualX->CopyArea(fContainer->GetId(), fContainer->GetId(), GetWhiteGC()(),
00199                               adiff, 0, fWidth - adiff, fHeight, 0, 0);
00200          adiff += 20;   // draw larger region
00201          ((TGContainer*)fContainer)->DrawRegion(fWidth - adiff, 0, adiff, fHeight);
00202       } else {
00203          gVirtualX->CopyArea(fContainer->GetId(), fContainer->GetId(), GetWhiteGC()(),
00204                               0, 0, fWidth - adiff, fHeight, adiff, 0);
00205          adiff += 20;   // draw larger region
00206          ((TGContainer*)fContainer)->DrawRegion(0, 0, adiff, fHeight);
00207       }
00208    } else {
00209       ((TGContainer*)fContainer)->DrawRegion(0, 0, fWidth, fHeight);
00210    }
00211 }
00212 
00213 //______________________________________________________________________________
00214 void TGViewPort::SetVPos(Int_t ypos)
00215 {
00216    // Moves content of container frame in vertical direction.
00217 
00218    Int_t diff;
00219 
00220    if (!fContainer) return;
00221 
00222    // for backward comatibility
00223    if (!fContainer->InheritsFrom(TGContainer::Class())) {
00224       fContainer->Move(fX0, fY0 = ypos);
00225       return;
00226    } else {
00227       if (((TGContainer*)fContainer)->fMapSubwindows) {
00228          fContainer->Move(fX0, fY0 = ypos);
00229          return;
00230       }
00231    }
00232 
00233    if (-ypos < 0) return;
00234    else diff = ypos - fY0;
00235    UInt_t adiff = TMath::Abs(diff);
00236 
00237    if (!diff) return;
00238 
00239    fY0 = ypos;
00240 
00241    if (adiff < fHeight) {
00242       if (diff < 0) {
00243          gVirtualX->CopyArea(fContainer->GetId(), fContainer->GetId(), GetWhiteGC()(),
00244                               0, adiff, fWidth, fHeight - adiff, 0, 0);
00245          adiff += 20;   // draw larger region
00246          ((TGContainer*)fContainer)->DrawRegion(0, fHeight - adiff, fWidth, adiff);
00247       } else {
00248          gVirtualX->CopyArea(fContainer->GetId(), fContainer->GetId(), GetWhiteGC()(),
00249                               0, 0, fWidth, fHeight - adiff, 0, adiff);
00250          adiff += 20;   // draw larger region
00251          ((TGContainer*)fContainer)->DrawRegion(0, 0, fWidth, adiff);
00252       }
00253    } else {
00254       ((TGContainer*)fContainer)->DrawRegion(0, 0, fWidth, fHeight);
00255    }
00256 }
00257 
00258 //______________________________________________________________________________
00259 void TGViewPort::SetPos(Int_t xpos, Int_t ypos)
00260 {
00261    // Goto new position.
00262 
00263    if (!fContainer) return;
00264 
00265    SetHPos(fX0 = xpos);
00266    SetVPos(fY0 = ypos);
00267 }
00268 
00269 //______________________________________________________________________________
00270 Bool_t TGViewPort::HandleConfigureNotify(Event_t *event)
00271 {
00272    // Handle resize events.
00273 
00274    if (!fContainer->InheritsFrom(TGContainer::Class())) {
00275       TGFrame::HandleConfigureNotify(event);
00276       return kTRUE;
00277    }
00278 
00279    TGContainer *cont = (TGContainer*)fContainer;
00280 
00281    // protection 
00282    if ((event->fWidth > 32768) || (event->fHeight  > 32768)) {
00283       return kFALSE;
00284    }
00285 
00286    cont->DrawRegion(event->fX, event->fY, event->fWidth, event->fHeight);
00287 
00288    return kTRUE;
00289 }
00290 
00291 //______________________________________________________________________________
00292 TGContainer::TGContainer(const TGWindow *p, UInt_t w, UInt_t h,
00293                              UInt_t options, ULong_t back) :
00294    TGCompositeFrame(p, w, h, options, back)
00295 {
00296    // Create a canvas container. This is the (large) frame that contains
00297    // all the list items. It will be shown through a TGViewPort (which is
00298    // created by the TGCanvas).
00299 
00300    fViewPort = 0;
00301    fBdown = kFALSE;
00302    fMsgWindow  = p;
00303    fDragging   = kFALSE;
00304    fTotal = fSelected = 0;
00305    fMapSubwindows = kFALSE;
00306    fOnMouseOver = kFALSE;
00307    fLastActiveEl = 0;
00308    fLastDir = kTRUE;
00309    fLastCase = kTRUE;
00310    fLastSubstring = kFALSE;
00311    fLastName = "";
00312    fKeyTimer = new TGContainerKeyboardTimer(this);
00313    fScrollTimer = new TGContainerScrollTimer(this);
00314    fKeyTimerActive = kFALSE;
00315    fScrolling = kFALSE;
00316    fCanvas = 0;
00317    fExposedRegion.Empty();
00318 
00319    gVirtualX->GrabButton(fId, kAnyButton, kAnyModifier,
00320                          kButtonPressMask | kButtonReleaseMask |
00321                          kPointerMotionMask, kNone, kNone);
00322 
00323    AddInput(kKeyPressMask | kPointerMotionMask);
00324    SetWindowName();
00325 
00326    SetWindowAttributes_t wattr;
00327    wattr.fMask = kWAWinGravity | kWABitGravity;
00328    wattr.fBitGravity = 1; // NorthWestGravity
00329    wattr.fWinGravity = 1;
00330    gVirtualX->ChangeWindowAttributes(fId, &wattr);
00331 
00332    fEditDisabled = kEditDisableGrab | kEditDisableBtnEnable;
00333 }
00334 
00335 //______________________________________________________________________________
00336 TGContainer::TGContainer(TGCanvas *p, UInt_t options, ULong_t back) :
00337    TGCompositeFrame(p->GetViewPort(), p->GetWidth(), p->GetHeight(), options, back)
00338 {
00339    // Create a canvas container. This is the (large) frame that contains
00340    // all the list items. It will be shown through a TGViewPort (which is
00341    // created by the TGCanvas).
00342 
00343    fViewPort = 0;
00344    fBdown = kFALSE;
00345    fMsgWindow  = p->GetViewPort();
00346    fCanvas = p;
00347    fCanvas->GetViewPort()->SetContainer(this);
00348    p->GetViewPort()->SetBackgroundColor(back);
00349 
00350    fDragging = kFALSE;
00351    fTotal = fSelected = 0;
00352    fMapSubwindows = kFALSE;
00353    fOnMouseOver = kFALSE;
00354    fLastActiveEl = 0;
00355    fLastDir = kTRUE;
00356    fLastCase = kTRUE;
00357    fLastSubstring = kFALSE;
00358    fLastName = "";
00359    fKeyTimer = new TGContainerKeyboardTimer(this);
00360    fScrollTimer = new TGContainerScrollTimer(this);
00361    fKeyTimerActive = kFALSE;
00362    fScrolling = kFALSE;
00363    fExposedRegion.Empty();
00364 
00365    gVirtualX->GrabButton(fId, kAnyButton, kAnyModifier,
00366                          kButtonPressMask | kButtonReleaseMask |
00367                          kPointerMotionMask, kNone, kNone);
00368 
00369    AddInput(kKeyPressMask | kPointerMotionMask);
00370    SetWindowName();
00371 
00372    SetWindowAttributes_t wattr;
00373    wattr.fMask = kWAWinGravity | kWABitGravity;
00374    wattr.fBitGravity = 1; // NorthWestGravity
00375    wattr.fWinGravity = 1;
00376    gVirtualX->ChangeWindowAttributes(fId, &wattr);
00377 
00378    fEditDisabled = kEditDisableGrab | kEditDisableBtnEnable;
00379 }
00380 
00381 //______________________________________________________________________________
00382 TGContainer::~TGContainer()
00383 {
00384    // Delete canvas container.
00385 
00386    if (TGSearchDialog::SearchDialog()) {
00387       TQObject::Disconnect(TGSearchDialog::SearchDialog(), 0, this);
00388    }
00389 
00390    delete fScrollTimer;
00391    fScrollTimer = 0;
00392 
00393    delete fKeyTimer;
00394    fKeyTimer = 0;
00395 }
00396 
00397 //______________________________________________________________________________
00398 void TGContainer::Layout()
00399 {
00400    // Layout container entries.
00401 
00402    TGCompositeFrame::Layout();
00403    TGLayoutManager *lm = GetLayoutManager();
00404 
00405    // clear content if positions of subframes changed after layout
00406    if (lm->IsModified()) ClearViewPort();
00407 }
00408 
00409 //______________________________________________________________________________
00410 void TGContainer::CurrentChanged(Int_t x, Int_t y)
00411 {
00412    // Emit signal when current position changed.
00413 
00414    Long_t args[2];
00415 
00416    args[0] = x;
00417    args[1] = y;
00418 
00419    Emit("CurrentChanged(Int_t,Int_t)",args);
00420 }
00421 
00422 //______________________________________________________________________________
00423 void TGContainer::CurrentChanged(TGFrame* f)
00424 {
00425    // Emit signal when current selected frame changed.
00426 
00427    Emit("CurrentChanged(TGFrame*)", (Long_t)f);
00428 }
00429 
00430 //______________________________________________________________________________
00431 void TGContainer::KeyPressed(TGFrame *frame, UInt_t keysym, UInt_t mask)
00432 {
00433    // Signal emitted when keyboard key pressed
00434    //
00435    // frame - activated frame
00436    // keysym - defined in "KeySymbols.h"
00437    // mask - modifier key mask, defined in "GuiTypes.h"
00438    //
00439    // const Mask_t kKeyShiftMask   = BIT(0);
00440    // const Mask_t kKeyLockMask    = BIT(1);
00441    // const Mask_t kKeyControlMask = BIT(2);
00442    // const Mask_t kKeyMod1Mask    = BIT(3);   // typically the Alt key
00443    // const Mask_t kButton1Mask    = BIT(8);
00444    // const Mask_t kButton2Mask    = BIT(9);
00445    // const Mask_t kButton3Mask    = BIT(10);
00446    // const Mask_t kButton4Mask    = BIT(11);
00447    // const Mask_t kButton5Mask    = BIT(12);
00448    // const Mask_t kAnyModifier    = BIT(15);
00449 
00450    Long_t args[3];
00451    args[0] = (Long_t)frame;
00452    args[1] = (Long_t)keysym;
00453    args[2] = (Long_t)mask;
00454    Emit("KeyPressed(TGFrame*,UInt_t,UInt_t)", args);
00455    SendMessage(fMsgWindow, MK_MSG(kC_CONTAINER, kCT_KEY), keysym, mask);
00456 }
00457 
00458 //______________________________________________________________________________
00459 void TGContainer::ReturnPressed(TGFrame* f)
00460 {
00461    // Signal emitted when Return/Enter key pressed.
00462    // It's equivalent to "double click" of mouse button.
00463 
00464    Emit("ReturnPressed(TGFrame*)", (Long_t)f);
00465 }
00466 
00467 //______________________________________________________________________________
00468 void TGContainer::SpacePressed(TGFrame* f)
00469 {
00470    // Signal emitted when space key pressed.
00471    // Pressing space key inverts selection.
00472 
00473    Emit("SpacePressed(TGFrame*)", (Long_t)f);
00474 }
00475 
00476 //______________________________________________________________________________
00477 void TGContainer::OnMouseOver(TGFrame* f)
00478 {
00479    // Signal emitted when pointer is over entry.
00480 
00481    if (!fOnMouseOver) Emit("OnMouseOver(TGFrame*)", (Long_t)f);
00482    fOnMouseOver = kTRUE;
00483 }
00484 
00485 //______________________________________________________________________________
00486 void TGContainer::Clicked(TGFrame *entry, Int_t btn)
00487 {
00488    // Emit Clicked() signal.
00489 
00490    Long_t args[2];
00491 
00492    args[0] = (Long_t)entry;
00493    args[1] = btn;
00494 
00495    Emit("Clicked(TGFrame*,Int_t)", args);
00496 }
00497 
00498 //______________________________________________________________________________
00499 void TGContainer::Clicked(TGFrame *entry, Int_t btn, Int_t x, Int_t y)
00500 {
00501    // Emit Clicked() signal.
00502 
00503    Long_t args[4];
00504 
00505    args[0] = (Long_t)entry;
00506    args[1] = btn;
00507    args[2] = x;
00508    args[3] = y;
00509 
00510    Emit("Clicked(TGFrame*,Int_t,Int_t,Int_t)", args);
00511 }
00512 
00513 //______________________________________________________________________________
00514 void TGContainer::DoubleClicked(TGFrame *entry, Int_t btn)
00515 {
00516    // Emit DoubleClicked() signal.
00517 
00518    Long_t args[2];
00519 
00520    args[0] = (Long_t)entry;
00521    args[1] = btn;
00522 
00523    Emit("DoubleClicked(TGFrame*,Int_t)", args);
00524 }
00525 
00526 //______________________________________________________________________________
00527 void TGContainer::DoubleClicked(TGFrame *entry, Int_t btn, Int_t x, Int_t y)
00528 {
00529    // Emit DoubleClicked() signal.
00530 
00531    Long_t args[4];
00532 
00533    args[0] = (Long_t)entry;
00534    args[1] = btn;
00535    args[2] = x;
00536    args[3] = y;
00537 
00538    Emit("DoubleClicked(TGFrame*,Int_t,Int_t,Int_t)", args);
00539 }
00540 
00541 //______________________________________________________________________________
00542 void TGContainer::SelectAll()
00543 {
00544    // Select all items in the container.
00545    // SelectAll() signal emitted.
00546 
00547    TIter next(fList);
00548    TGFrameElement *el;
00549    TGFrame *fr;
00550    TGPosition pos = GetPagePosition();
00551 
00552    while ((el = (TGFrameElement *) next())) {
00553       fr = el->fFrame;
00554       if (!fr->IsActive()) {
00555          ActivateItem(el);
00556       }
00557    }
00558    fSelected = fTotal;
00559    SendMessage(fMsgWindow, MK_MSG(kC_CONTAINER, kCT_SELCHANGED),
00560                   fTotal, fSelected);
00561 
00562    Emit("SelectAll()");
00563 }
00564 
00565 //______________________________________________________________________________
00566 void TGContainer::UnSelectAll()
00567 {
00568    // Unselect all items in the container.
00569 
00570    TIter next(fList);
00571    TGFrameElement *el;
00572    TGPosition pos = GetPagePosition();
00573    TGFrame *fr;
00574 
00575    while ((el = (TGFrameElement *) next())) {
00576       fr = el->fFrame;
00577       if (fr->IsActive()) {
00578          DeActivateItem(el);
00579       }
00580    }
00581    fLastActiveEl = 0;
00582    fSelected = 0;
00583 
00584    SendMessage(fMsgWindow, MK_MSG(kC_CONTAINER, kCT_SELCHANGED),
00585                   fTotal, fSelected);
00586 
00587    Emit("UnSelectAll()");
00588 }
00589 
00590 //______________________________________________________________________________
00591 void TGContainer::InvertSelection()
00592 {
00593    // Invert the selection, all selected items become unselected and
00594    // vice versa.
00595 
00596    int selected = 0;
00597 
00598    TIter next(fList);
00599    TGFrameElement *el;
00600 
00601    while ((el = (TGFrameElement *) next())) {
00602       if (!el->fFrame->IsActive()) {
00603          ActivateItem(el);
00604          ++selected;
00605       } else {
00606          DeActivateItem(el);
00607       }
00608    }
00609    ClearViewPort();  // full redraw
00610    fSelected = selected;
00611 
00612    SendMessage(fMsgWindow, MK_MSG(kC_CONTAINER, kCT_SELCHANGED),
00613                   fTotal, fSelected);
00614 
00615    Emit("InvertSelection()");
00616 }
00617 
00618 //______________________________________________________________________________
00619 void TGContainer::RemoveAll()
00620 {
00621    // Remove all items from the container.
00622 
00623    TGFrameElement *el;
00624    TIter next(fList);
00625 
00626    while ((el = (TGFrameElement *) next())) {
00627       el->fFrame->DestroyWindow();
00628       delete el->fFrame;
00629       fList->Remove(el);
00630       delete el;
00631    }
00632    fLastActiveEl = 0;
00633    fSelected = fTotal = 0;
00634    ClearViewPort();  // full redraw
00635 }
00636 
00637 //______________________________________________________________________________
00638 void TGContainer::RemoveItem(TGFrame *item)
00639 {
00640    // Remove item from container.
00641 
00642    TGFrameElement *el;
00643    TIter next(fList);
00644    while ((el = (TGFrameElement *) next())) {
00645       if (item == el->fFrame) {
00646          if (fLastActiveEl && item == fLastActiveEl->fFrame) fLastActiveEl = 0;
00647          item->DestroyWindow();
00648          delete item;
00649          fList->Remove(el);
00650          delete el;
00651          break;
00652       }
00653    }
00654    ClearViewPort();  // fill redraw
00655 }
00656 
00657 //______________________________________________________________________________
00658 const TGFrame *TGContainer::GetNextSelected(void **current)
00659 {
00660    // Return next selected item.
00661 
00662    TGFrame *f;
00663    TObjLink *lnk = (TObjLink *) *current;
00664 
00665    lnk = (lnk == 0) ? fList->FirstLink() : lnk->Next();
00666    while (lnk) {
00667       f = (TGFrame *) ((TGFrameElement *) lnk->GetObject())->fFrame;
00668       if (f->IsActive()) {
00669          *current = (void *) lnk;
00670          return f;
00671       }
00672       lnk = lnk->Next();
00673    }
00674    return 0;
00675 }
00676 
00677 //______________________________________________________________________________
00678 void TGContainer::ActivateItem(TGFrameElement *el)
00679 {
00680    // Activate item.
00681 
00682    TGFrame *fr = el->fFrame;
00683    fr->Activate(kTRUE);
00684 
00685    if (fLastActiveEl != el) {
00686       fLastActiveEl = el;
00687       CurrentChanged(fLastActiveEl->fFrame->GetX(), fLastActiveEl->fFrame->GetY());
00688       CurrentChanged(fLastActiveEl->fFrame);
00689       fSelected++;
00690    }
00691 
00692    if (!fSelected) fSelected = 1;
00693 
00694    SendMessage(fMsgWindow, MK_MSG(kC_CONTAINER, kCT_SELCHANGED), fTotal, fSelected);
00695 
00696    TGPosition pos = GetPagePosition();
00697    DrawRegion(fr->GetX() - pos.fX, fr->GetY() - pos.fY, fr->GetWidth(), fr->GetHeight());
00698 }
00699 
00700 //______________________________________________________________________________
00701 void TGContainer::DeActivateItem(TGFrameElement *el)
00702 {
00703    // DeActivate item.
00704 
00705    TGFrame *fr = el->fFrame;
00706    fr->Activate(kFALSE);
00707    SendMessage(fMsgWindow, MK_MSG(kC_CONTAINER, kCT_SELCHANGED), fTotal, fSelected);
00708 
00709    TGPosition pos = GetPagePosition();
00710    DrawRegion(fr->GetX() - pos.fX, fr->GetY() - pos.fY, fr->GetWidth(), fr->GetHeight());
00711 }
00712 
00713 //______________________________________________________________________________
00714 TGPosition TGContainer::GetPagePosition() const
00715 {
00716    // Returns page position.
00717 
00718    TGPosition ret;
00719    if (!fViewPort) return ret;
00720 
00721    ret.fX = -fViewPort->GetHPos();
00722    ret.fY = -fViewPort->GetVPos();
00723 
00724    return ret;
00725 }
00726 
00727 //______________________________________________________________________________
00728 TGDimension TGContainer::GetPageDimension() const
00729 {
00730    // Returns page dimension.
00731 
00732    TGDimension ret;
00733    if (!fViewPort) return ret;
00734 
00735    ret.fWidth = fViewPort->GetWidth();
00736    ret.fHeight = fViewPort->GetHeight();
00737    return ret;
00738 }
00739 
00740 //______________________________________________________________________________
00741 void TGContainer::SetPagePosition(const TGPosition& pos)
00742 {
00743    // Set page position.
00744 
00745    if (!fViewPort) return;
00746    fViewPort->SetPos(pos.fX, pos.fY);
00747 }
00748 
00749 //______________________________________________________________________________
00750 void TGContainer::SetPagePosition(Int_t x, Int_t y)
00751 {
00752    // Set page position.
00753 
00754    if (!fViewPort) return;
00755    fViewPort->SetPos(x, y);
00756 }
00757 
00758 //______________________________________________________________________________
00759 void TGContainer::SetPageDimension(const TGDimension& dim)
00760 {
00761    // Set page dimension.
00762 
00763    if (!fViewPort) return;
00764    fViewPort->Resize(dim);
00765 }
00766 
00767 //______________________________________________________________________________
00768 void TGContainer::SetPageDimension(UInt_t w, UInt_t h)
00769 {
00770    // Set page dimension.
00771 
00772    if (!fViewPort) return;
00773    fViewPort->Resize(w, h);
00774 }
00775 
00776 //______________________________________________________________________________
00777 void TGContainer::DoRedraw()
00778 {
00779    // Redraw content of container in the viewport region.
00780 
00781    if (!fExposedRegion.IsEmpty()) {
00782       DrawRegion(fExposedRegion.fX, fExposedRegion.fY, 
00783                  fExposedRegion.fW, fExposedRegion.fH);
00784       
00785       fExposedRegion.Empty();
00786    }
00787 }
00788 
00789 //______________________________________________________________________________
00790 void TGContainer::DrawRegion(Int_t x, Int_t y, UInt_t w, UInt_t h)
00791 {
00792    // Draw a region of container in viewport.
00793    // x, y, w, h are position and dimension of area to be 
00794    // redrawn in viewport coordinates.
00795 
00796    static GContext_t gcBg = 0;
00797    Pixmap_t pixmap = 0;
00798 
00799    if (!fViewPort) return;
00800    // sanity checks
00801    if ((x > (Int_t)fViewPort->GetWidth()) || (y > (Int_t)fViewPort->GetHeight())) {
00802       return;
00803    }
00804    x = x < 0 ? 0 : x;
00805    y = y < 0 ? 0 : y;
00806 
00807    w = x + w > fViewPort->GetWidth() ? fViewPort->GetWidth() - x : w;
00808    h = y + h > fViewPort->GetHeight() ? fViewPort->GetHeight() - y :  h;
00809 
00810    if (((Int_t)w < 1) || ((Int_t)h < 1)) {
00811       return;
00812    }
00813 
00814    if (!fMapSubwindows) {
00815       pixmap = gVirtualX->CreatePixmap(fId, w, h);
00816 
00817       if (!gcBg) {
00818          GCValues_t gcValues;
00819          gcValues.fForeground = fBackground;
00820          gcValues.fBackground = fBackground;
00821          gcValues.fGraphicsExposures = kTRUE;
00822          gcValues.fMask = kGCForeground | kGCBackground | kGCGraphicsExposures;
00823          gcBg = gVirtualX->CreateGC(fId, &gcValues);
00824       }
00825 
00826       gVirtualX->SetForeground(gcBg, fBackground);
00827       gVirtualX->FillRectangle(pixmap, gcBg, 0, 0, w, h);
00828    }
00829 
00830    TGPosition pos = GetPagePosition();
00831 
00832    // translate coordinates in viewport into coordinates in container 
00833    Int_t xx = pos.fX + x;
00834    Int_t yy = pos.fY + y;
00835 
00836    TIter next(fList);
00837    TGFrameElement *el;
00838 
00839    while ((el = (TGFrameElement *) next())) {
00840       if ((Int_t(el->fFrame->GetY()) > yy - (Int_t)el->fFrame->GetHeight()) &&
00841           (Int_t(el->fFrame->GetX()) > xx - (Int_t)el->fFrame->GetWidth()) &&
00842           (Int_t(el->fFrame->GetY()) < yy + Int_t(h + el->fFrame->GetHeight())) &&
00843           (Int_t(el->fFrame->GetX()) < xx + Int_t(w + el->fFrame->GetWidth()))) {
00844 
00845          // draw either in container window or in double-buffer
00846          if (!fMapSubwindows) {
00847             Int_t fx = el->fFrame->GetX() - xx;
00848             Int_t fy = el->fFrame->GetY() - yy;
00849             el->fFrame->DrawCopy(pixmap, fx, fy);
00850          } else {
00851             fClient->NeedRedraw(el->fFrame);
00852          }
00853       }
00854    }
00855 
00856    if (fMapSubwindows) return;
00857 
00858    gVirtualX->CopyArea(pixmap, fId, gcBg, 0, 0, w, h, x, y);
00859    gVirtualX->DeletePixmap(pixmap);
00860    gVirtualX->Update(kFALSE);
00861 }
00862 
00863 //______________________________________________________________________________
00864 void TGContainer::ClearViewPort()
00865 {
00866    // Clear view port and redraw full content
00867 
00868    if (!fViewPort) return;
00869    fExposedRegion.fW = fViewPort->GetWidth();
00870    fExposedRegion.fH = fViewPort->GetHeight();
00871    fExposedRegion.fX = fExposedRegion.fY = 0;
00872    fClient->NeedRedraw(this);
00873 }
00874 
00875 //______________________________________________________________________________
00876 Bool_t TGContainer::HandleExpose(Event_t *event)
00877 {
00878    // Handle expose events. Do not use double buffer.
00879 
00880    if (fMapSubwindows) return TGCompositeFrame::HandleExpose(event);
00881 
00882    if (event->fWindow == GetId()) {
00883       TGPosition pos(event->fX, event->fY);
00884       TGDimension dim(event->fWidth, event->fHeight);
00885       TGRectangle rect(pos, dim);
00886 
00887       if (fExposedRegion.IsEmpty()) {
00888          fExposedRegion = rect;
00889       } else {
00890          fExposedRegion.Merge(rect);
00891       }
00892 
00893       fClient->NeedRedraw(this);
00894    } else {
00895       TGCompositeFrame::HandleExpose(event);
00896    }
00897 
00898    return kTRUE;
00899 }
00900 
00901 //______________________________________________________________________________
00902 Bool_t TGContainer::HandleButton(Event_t *event)
00903 {
00904    // Handle mouse button event in container.
00905 
00906    Int_t total, selected, page = 0;
00907 
00908    TGPosition pos = GetPagePosition();
00909    TGDimension dim = GetPageDimension();
00910    Int_t newpos;
00911    page = dim.fHeight/4;
00912 
00913    if (event->fCode == kButton4) {
00914       //scroll up
00915       newpos = pos.fY - page;
00916       if (newpos < 0) newpos = 0;
00917       fCanvas->SetVsbPosition(newpos);
00918       return kTRUE;
00919    }
00920    if (event->fCode == kButton5) {
00921       // scroll down
00922       newpos = fCanvas->GetVsbPosition() + page;
00923       fCanvas->SetVsbPosition(newpos);
00924       return kTRUE;
00925    }
00926 
00927    Int_t xx = pos.fX + event->fX; // translate coordinates
00928    Int_t yy = pos.fY + event->fY;
00929 
00930    if (event->fType == kButtonPress) {
00931       gVirtualX->SetInputFocus(fId);
00932 
00933       fXp = pos.fX + event->fX;
00934       fYp = pos.fY + event->fY;
00935 
00936       fXDND = event->fX;
00937       fYDND = event->fY;
00938       fBdown = kTRUE;
00939 
00940       UnSelectAll();
00941       total = selected = 0;
00942 
00943       TGFrameElement *el;
00944       TIter next(fList);
00945       Bool_t select_frame = kFALSE;
00946 
00947       while ((el = (TGFrameElement *) next())) {
00948          select_frame = kFALSE;
00949 
00950          if (!fMapSubwindows) {
00951             if ((Int_t(el->fFrame->GetY()) + (Int_t)el->fFrame->GetHeight() > yy ) &&
00952                (Int_t(el->fFrame->GetX()) + (Int_t)el->fFrame->GetWidth() > xx ) &&
00953                (Int_t(el->fFrame->GetY()) < yy) &&
00954                (Int_t(el->fFrame->GetX()) < xx))  {
00955                select_frame = kTRUE;
00956             }
00957          } else {
00958             if (el->fFrame->GetId() == (Window_t)event->fUser[0]) {
00959                select_frame = kTRUE;
00960             }
00961          }
00962 
00963          if (select_frame) {
00964             selected++;
00965             ActivateItem(el);
00966             Clicked(el->fFrame, event->fCode);
00967             Clicked(el->fFrame, event->fCode, event->fXRoot, event->fYRoot);
00968          }
00969          total++;
00970       }
00971 
00972       if (fTotal != total || fSelected != selected) {
00973          fTotal = total;
00974          fSelected = selected;
00975          SendMessage(fMsgWindow, MK_MSG(kC_CONTAINER, kCT_SELCHANGED),
00976                      fTotal, fSelected);
00977       }
00978 
00979       if ( selected == 0 ) {
00980          fDragging = kTRUE;
00981          fX0 = fXf = fXp;
00982          fY0 = fYf = fYp;
00983          gVirtualX->DrawRectangle(fId, GetLineGC()(), fX0-pos.fX, fY0-pos.fY, 
00984                                   fXf-fX0, fYf-fY0);
00985       }
00986    }
00987 
00988    if (event->fType == kButtonRelease) {
00989       gVirtualX->SetInputFocus(fId);
00990 
00991       fBdown = kFALSE;
00992       if (fDragging) {
00993          fDragging = kFALSE;
00994          fScrolling = kFALSE;
00995 
00996          if (gSystem) gSystem->RemoveTimer(fScrollTimer);
00997          gVirtualX->DrawRectangle(fId, GetLineGC()(), fX0-pos.fX, fY0-pos.fY,
00998                                   fXf-fX0, fYf-fY0);
00999          ClearViewPort();
01000 
01001       } else {
01002          SendMessage(fMsgWindow, MK_MSG(kC_CONTAINER, kCT_ITEMCLICK),
01003                      event->fCode, (event->fYRoot << 16) | event->fXRoot);
01004       }
01005    }
01006    DoRedraw();
01007    return kTRUE;
01008 }
01009 
01010 //______________________________________________________________________________
01011 const TGPicture *TGContainer::GetObjPicture(TGFrame *f)
01012 {
01013    // Retrieve icons associated with class "name". Association is made
01014    // via the user's ~/.root.mimes file or via $ROOTSYS/etc/root.mimes.
01015 
01016    TObject *obj = 0;
01017    TClass *cl;
01018    const TGPicture *pic=0;
01019    const char *iconname = 0;
01020 
01021    if (f->InheritsFrom("TGLVEntry")) {
01022       obj = (TObject *)((TGLVEntry *)f)->GetUserData();
01023       if (obj) {
01024          if (obj->IsA() == TKey::Class()) {
01025             cl = TClass::GetClass(((TKey *)obj)->GetClassName());
01026          } else if (obj->IsA() == TKeyMapFile::Class()) {
01027             cl = TClass::GetClass(((TKeyMapFile *)obj)->GetTitle());
01028          } else {
01029             cl = obj->IsA();
01030          }
01031          const char *name = obj->GetIconName() ? obj->GetIconName() : cl->GetName();
01032          iconname = (strlen(name) > 0) ? name : obj->GetName();
01033 
01034          if (obj->IsA()->InheritsFrom("TGeoVolume")) {
01035             iconname = obj->GetIconName() ? obj->GetIconName() : obj->IsA()->GetName();
01036          }
01037          pic = fClient->GetMimeTypeList()->GetIcon(iconname, kFALSE);
01038       }
01039    }
01040    if (pic == 0) {
01041       if (obj && obj->IsFolder()) {
01042          pic = fClient->GetPicture("folder_s.xpm");
01043       } else {
01044          pic = fClient->GetPicture("doc_s.xpm");
01045       }
01046    }
01047    return pic;
01048 }
01049 
01050 //______________________________________________________________________________
01051 void TGContainer::SetDragPixmap(const TGPicture *p)
01052 {
01053    // Set drag window pixmaps and hotpoint.
01054    
01055    Pixmap_t pic, mask;
01056    TGPicture *selpic = new TGSelectedPicture(gClient, p);
01057    pic  = selpic->GetPicture();
01058    mask = selpic->GetMask();
01059 
01060    if (gDNDManager) {
01061       gDNDManager->SetDragPixmap(pic, mask, p->GetWidth()/2, 2+p->GetHeight()/2);
01062    } else {
01063       gVirtualX->DeletePixmap(pic);
01064       gVirtualX->DeletePixmap(mask);
01065    }
01066 }
01067 
01068 //______________________________________________________________________________
01069 Bool_t TGContainer::HandleDoubleClick(Event_t *event)
01070 {
01071    // Handle double click mouse event.
01072 
01073    TGFrameElement *el;
01074    TIter next(fList);
01075 
01076    TGPosition pos = GetPagePosition();
01077 
01078    Int_t xx = pos.fX + event->fX; // translate coordinates
01079    Int_t yy = pos.fY + event->fY;
01080 
01081    Bool_t select_frame = kFALSE;
01082 
01083    while ((el = (TGFrameElement *) next())) {
01084       select_frame = kFALSE;
01085 
01086       if (!fMapSubwindows) {
01087          if ((Int_t(el->fFrame->GetY()) + (Int_t)el->fFrame->GetHeight() > yy) &&
01088             (Int_t(el->fFrame->GetX()) + (Int_t)el->fFrame->GetWidth() > xx) &&
01089             (Int_t(el->fFrame->GetY()) < yy) &&
01090             (Int_t(el->fFrame->GetX()) < xx))  {
01091             select_frame = kTRUE;
01092          }
01093       } else {
01094          if (el->fFrame->GetId() == (Window_t)event->fUser[0]) {
01095             select_frame = kTRUE;
01096          }
01097       }
01098 
01099       if (select_frame) {
01100          SendMessage(fMsgWindow, MK_MSG(kC_CONTAINER, kCT_ITEMDBLCLICK),
01101                      event->fCode, (event->fYRoot << 16) | event->fXRoot);
01102 
01103          DoubleClicked(el->fFrame, event->fCode);
01104          DoubleClicked(el->fFrame, event->fCode, event->fXRoot, event->fYRoot);
01105          return kTRUE;
01106       }
01107    }
01108    return kTRUE;
01109 }
01110 
01111 //______________________________________________________________________________
01112 Bool_t TGContainer::HandleMotion(Event_t *event)
01113 {
01114    // Handle mouse motion events.
01115 
01116    int xf0, yf0, xff, yff, total, selected;
01117 
01118    TGPosition pos = GetPagePosition();
01119    TGDimension dim = GetPageDimension();
01120    Int_t x = pos.fX + event->fX;
01121    Int_t y = pos.fY + event->fY;
01122    TGFrameElement *el = 0;
01123    TGFrame *f = 0;
01124    fOnMouseOver = kFALSE;
01125 
01126    Bool_t wasScrolling = fScrolling;
01127 
01128    if (gDNDManager->IsDragging()) {
01129       gDNDManager->Drag(event->fXRoot, event->fYRoot,
01130                         TGDNDManager::GetDNDActionCopy(), event->fTime);
01131    } 
01132    else if (fDragging) {
01133 
01134       gVirtualX->DrawRectangle(fId, GetLineGC()(), fX0-pos.fX, fY0-pos.fY,
01135                                fXf-fX0, fYf-fY0);
01136       fX0 =  TMath::Min(fXp,x);
01137       fY0 =  TMath::Min(fYp,y);
01138       fXf =  TMath::Max(fXp,x);
01139       fYf =  TMath::Max(fYp,y);
01140 
01141       total = selected = 0;
01142 
01143       if (event->fX > Int_t(dim.fWidth) - kAutoScrollFudge) {
01144          //fCanvas->SetHsbPosition(x - dim.fWidth);
01145          fScrolling = kTRUE;
01146       } else if (event->fX < kAutoScrollFudge) {
01147          //fCanvas->SetHsbPosition(x);
01148          fScrolling = kTRUE;
01149       } else if (event->fY > Int_t(dim.fHeight) - kAutoScrollFudge) {
01150          //fCanvas->SetVsbPosition(y - dim.fHeight);
01151          fScrolling = kTRUE;
01152       } else if (event->fY < kAutoScrollFudge) {
01153          //fCanvas->SetVsbPosition(y);
01154          fScrolling = kTRUE;
01155       }
01156       else {
01157          fScrolling = kFALSE;
01158       }
01159 
01160       TIter next(fList);
01161 
01162       while ((el = (TGFrameElement *) next())) {
01163          f = el->fFrame;
01164          ++total;
01165          xf0 = f->GetX() + (f->GetWidth() >> 3);
01166          yf0 = f->GetY() + (f->GetHeight() >> 3);
01167          xff = xf0 + f->GetWidth() - (f->GetWidth() >> 2);
01168          yff = yf0 + f->GetHeight() - (f->GetHeight() >> 2);
01169 
01170          if (((xf0 > fX0 && xf0 < fXf) ||
01171               (xff > fX0 && xff < fXf)) &&
01172              ((yf0 > fY0 && yf0 < fYf) ||
01173               (yff > fY0 && yff < fYf))) {
01174             if (!el->fFrame->IsActive())
01175                ActivateItem(el);
01176             gVirtualX->SetCursor(fId, gVirtualX->CreateCursor(kHand));
01177             OnMouseOver(f);
01178             ++selected;
01179          } else {
01180             if (el->fFrame->IsActive())
01181                DeActivateItem(el);
01182          }
01183       }
01184 
01185       if (fTotal != total || fSelected != selected) {
01186          fTotal = total;
01187          fSelected = selected;
01188          SendMessage(fMsgWindow, MK_MSG(kC_CONTAINER, kCT_SELCHANGED),
01189                      fTotal, fSelected);
01190       }
01191       gVirtualX->DrawRectangle(fId, GetLineGC()(), fX0-pos.fX, fY0-pos.fY,
01192                                fXf-fX0, fYf-fY0);
01193    } 
01194    else {
01195       TGFrame *over_frame = 0;
01196 
01197       TIter next(fList);
01198 
01199       while ((el = (TGFrameElement *) next())) {
01200          if (!fMapSubwindows) {
01201             if ((Int_t(el->fFrame->GetY()) + (Int_t)el->fFrame->GetHeight() > y) &&
01202                (Int_t(el->fFrame->GetX()) + (Int_t)el->fFrame->GetWidth() > x) &&
01203                (Int_t(el->fFrame->GetY()) < y) &&
01204                (Int_t(el->fFrame->GetX()) < x))  {
01205                over_frame = el->fFrame;
01206                break;
01207             }
01208          } else {
01209             if (el->fFrame->GetId() == (Window_t)event->fUser[0]) {
01210                over_frame = el->fFrame;
01211                break;
01212             }
01213          }
01214       }
01215       if (over_frame) {
01216          if (!gDNDManager->IsDragging()) {
01217             if (fBdown && ((abs(event->fX - fXDND) > 2) || (abs(event->fY - fYDND) > 2))) {
01218                if (gDNDManager && over_frame->IsDNDSource()) {
01219                   SetDragPixmap(GetObjPicture(over_frame));
01220                   gDNDManager->StartDrag(over_frame, event->fXRoot, event->fYRoot);
01221                }
01222             }
01223          }
01224          if (gDNDManager->IsDragging()) {
01225             gDNDManager->Drag(event->fXRoot, event->fYRoot,
01226                               TGDNDManager::GetDNDActionCopy(), event->fTime);
01227          } else {
01228             OnMouseOver(over_frame);
01229             gVirtualX->SetCursor(fId, gVirtualX->CreateCursor(kHand));
01230          }
01231       } else {
01232          gVirtualX->SetCursor(fId, gVirtualX->CreateCursor(kPointer));
01233       }
01234    }
01235 
01236    if (!wasScrolling && fScrolling) {
01237       if (gSystem) {
01238          fScrollTimer->Reset();
01239          gSystem->AddTimer(fScrollTimer);
01240       }
01241    }
01242 
01243    return kTRUE;
01244 }
01245 
01246 //______________________________________________________________________________
01247 Bool_t TGContainer::HandleKey(Event_t *event)
01248 {
01249    // The key press event handler converts a key press to some line editor
01250    // action.
01251 
01252    char   input[10];
01253    Int_t  n;
01254    UInt_t keysym;
01255 
01256    if (event->fType == kGKeyPress) {
01257       gVirtualX->LookupString(event, input, sizeof(input), keysym);
01258       n = strlen(input);
01259 
01260       KeyPressed(fLastActiveEl?fLastActiveEl->fFrame:0, keysym, event->fState);
01261 
01262       switch ((EKeySym)keysym) {
01263          case kKey_Enter:
01264          case kKey_Return:
01265             // treat 'Enter' and 'Return' as a double click
01266             SendMessage(GetMessageWindow(), MK_MSG(kC_CONTAINER, kCT_ITEMDBLCLICK),
01267                               kButton1, (event->fYRoot << 16) | event->fXRoot);
01268             if (fLastActiveEl) ReturnPressed(fLastActiveEl->fFrame);
01269             break;
01270          case kKey_Shift:
01271          case kKey_Control:
01272          case kKey_Meta:
01273          case kKey_Alt:
01274          case kKey_CapsLock:
01275          case kKey_NumLock:
01276          case kKey_ScrollLock:
01277             return kTRUE;
01278          case kKey_Space:
01279             if (fLastActiveEl) {
01280                fLastActiveEl->fFrame->Activate(!fLastActiveEl->fFrame->IsActive());
01281                SpacePressed(fLastActiveEl->fFrame);
01282             }
01283             break;
01284          default:
01285          break;
01286       }
01287 
01288       if (event->fState & kKeyControlMask) {   // Cntrl key modifier pressed
01289          switch((EKeySym)keysym & ~0x20) {   // treat upper and lower the same
01290             case kKey_A:
01291                SelectAll();
01292                break;
01293             case kKey_B:
01294                LineLeft();
01295                break;
01296             case kKey_C:
01297                return kTRUE;
01298             case kKey_D:
01299                break;
01300             case kKey_E:
01301                End();
01302                break;
01303             case kKey_F:
01304                Search();
01305                break;
01306             case kKey_G:
01307                RepeatSearch();
01308                break;
01309             case kKey_H:
01310                LineLeft();
01311                break;
01312             case kKey_K:
01313                End();
01314                break;
01315             case kKey_U:
01316                Home();
01317                break;
01318             case kKey_V:
01319             case kKey_Y:
01320                return kTRUE;
01321             case kKey_X:
01322                return kTRUE;
01323             default:
01324                return kTRUE;
01325          }
01326       }
01327       if (n && keysym >= 32 && keysym < 127 &&     // printable keys
01328          !(event->fState & kKeyControlMask) &&
01329           (EKeySym)keysym != kKey_Delete &&
01330           (EKeySym)keysym != kKey_Backspace) {
01331 
01332          if (fKeyTimerActive) {
01333             fKeyInput += input;
01334          } else {
01335             fKeyInput = input;
01336             fKeyTimerActive = kTRUE;
01337             fKeyTimer->Reset();
01338             if (gSystem) gSystem->AddTimer(fKeyTimer);
01339          }
01340       } else {
01341 
01342          switch ((EKeySym)keysym) {
01343             case kKey_F3:
01344                RepeatSearch();
01345                break;
01346             case kKey_F5:
01347                Layout();
01348                break;
01349             case kKey_F7:
01350                Search();
01351                break;
01352             case kKey_Left:
01353                LineLeft(event->fState & kKeyShiftMask);
01354                break;
01355             case kKey_Right:
01356                LineRight(event->fState & kKeyShiftMask);
01357                break;
01358             case kKey_Up:
01359                LineUp(event->fState & kKeyShiftMask);
01360                break;
01361             case kKey_Down:
01362                LineDown(event->fState & kKeyShiftMask);
01363                break;
01364             case kKey_PageUp:
01365                PageUp(event->fState & kKeyShiftMask);
01366                break;
01367             case kKey_PageDown:
01368                PageDown(event->fState & kKeyShiftMask);
01369                break;
01370             case kKey_Home:
01371                Home(event->fState & kKeyShiftMask);
01372                break;
01373             case kKey_End:
01374                End(event->fState & kKeyShiftMask);
01375                break;
01376             default:
01377                break;
01378          }
01379       }
01380    }
01381    DoRedraw();
01382    return kTRUE;
01383 }
01384 
01385 //______________________________________________________________________________
01386 TGFrame *TGContainer::FindFrameByName(const char *name)
01387 {
01388    // Find frame by name.
01389 
01390    if (!IsMapped()) return 0;
01391 
01392    Bool_t direction = kTRUE;
01393    Bool_t caseSensitive = kFALSE;
01394    Bool_t subString = kFALSE;
01395 
01396    if (gTQSender && (gTQSender == TGSearchDialog::SearchDialog())) {
01397       caseSensitive = TGSearchDialog::SearchDialog()->GetType()->fCaseSensitive;
01398       direction = TGSearchDialog::SearchDialog()->GetType()->fDirection;
01399    }
01400    TString sname(name);
01401    if (sname.Contains("*")) {
01402       subString = kTRUE;
01403       sname.ReplaceAll("*", "");
01404    }
01405 
01406    TGFrameElement *fe = (TGFrameElement*)FindItem(sname.Data(), direction, 
01407                                                   caseSensitive, subString);
01408    if (!fe) {  // find again
01409       if (fLastActiveEl) DeActivateItem(fLastActiveEl);
01410       fLastActiveEl = 0;
01411       fe = (TGFrameElement*)FindItem(fLastName, fLastDir, fLastCase, fLastSubstring);
01412 
01413       if (!fe) {
01414          if (gTQSender && (gTQSender == TGSearchDialog::SearchDialog())) {
01415             TString msg = "Couldn't find \"" + fLastName + '\"';
01416             gVirtualX->Bell(20);
01417             new TGMsgBox(fClient->GetDefaultRoot(), fCanvas, "Container", msg.Data(),
01418                           kMBIconExclamation, kMBOk, 0);
01419          }
01420          return 0;
01421       } else {
01422          if (fLastActiveEl) DeActivateItem(fLastActiveEl);
01423          ActivateItem(fe);
01424          AdjustPosition();
01425          return fe->fFrame;
01426       }
01427    } else {
01428       if (fLastActiveEl) DeActivateItem(fLastActiveEl);
01429       ActivateItem(fe);
01430       AdjustPosition();
01431       return fe->fFrame;
01432    }
01433    return 0;
01434 }
01435 
01436 //______________________________________________________________________________
01437 void TGContainer::Search(Bool_t close)
01438 {
01439    // Invokes search dialog. Looks for item with the entered name.
01440 
01441    static TGSearchType *srch = 0;
01442    Int_t ret = 0;
01443 
01444    if (!srch) srch = new TGSearchType;
01445    srch->fClose = close;
01446    srch->fBuffer = 0;
01447 
01448    if (!close) {
01449       if (!TGSearchDialog::SearchDialog()) {
01450          TGSearchDialog::SearchDialog() = new TGSearchDialog(fClient->GetDefaultRoot(), 
01451                                                              fCanvas, 400, 150, srch, &ret);
01452       }
01453       TGSearchDialog::SearchDialog()->Connect("TextEntered(char *)", "TGContainer", this,
01454                                               "FindFrameByName(char *)");
01455       TGSearchDialog::SearchDialog()->MapRaised();
01456    } else {
01457       new TGSearchDialog(fClient->GetDefaultRoot(), fCanvas, 400, 150, srch, &ret);
01458       if (ret) {
01459          FindFrameByName(srch->fBuffer);
01460       }
01461    }
01462 }
01463 
01464 //______________________________________________________________________________
01465 void TGContainer::OnAutoScroll()
01466 {
01467    // Autoscroll while close to & beyond  The Wall
01468 
01469    TGFrameElement *el = 0;
01470    TGFrame *f = 0;
01471    int xf0, yf0, xff, yff, total, selected;
01472 
01473    TGDimension dim = GetPageDimension();
01474    TGPosition pos = GetPagePosition();
01475 
01476    Window_t  dum1, dum2;
01477    Event_t   ev;
01478    ev.fType    = kButtonPress;
01479    Int_t x,y;
01480 
01481    // Autoscroll while close to the wall
01482    Int_t dx = 0;
01483    Int_t dy = 0;
01484 
01485    // Where's the cursor?
01486    gVirtualX->QueryPointer(fId,dum1,dum2,ev.fXRoot,ev.fYRoot,x,y,ev.fState);
01487 
01488    // Figure scroll amount x
01489    if (x < kAutoScrollFudge)
01490       dx = kAutoScrollFudge - x;
01491    else if ((Int_t)dim.fWidth-kAutoScrollFudge <= x)
01492       dx = dim.fWidth - kAutoScrollFudge - x;
01493 
01494    // Figure scroll amount y
01495    if (y < kAutoScrollFudge)
01496       dy = kAutoScrollFudge - y;
01497    else if ((Int_t)dim.fHeight - kAutoScrollFudge <= y)
01498       dy = dim.fHeight - kAutoScrollFudge - y;
01499 
01500    if (dx || dy) {
01501       if (dx) dx /= 5;
01502       if (dy) dy /= 5;
01503       Int_t adx = TMath::Abs(dx);
01504       Int_t ady = TMath::Abs(dy);
01505       if (adx > kAutoScrollFudge) adx = kAutoScrollFudge;
01506       if (ady > kAutoScrollFudge) ady = kAutoScrollFudge;
01507 
01508       dx *= kAcceleration[adx];
01509       dy *= kAcceleration[ady];
01510 
01511       Int_t nx = pos.fX-dx;
01512       Int_t ny = pos.fY-dy;
01513 
01514       fCanvas->SetHsbPosition(nx);
01515       fCanvas->SetVsbPosition(ny);
01516 
01517       // position inside container
01518       x += pos.fX;
01519       y += pos.fY;
01520 
01521       fX0 =  TMath::Min(fXp, x);
01522       fY0 =  TMath::Min(fYp, y);
01523       fXf =  TMath::Max(fXp, x);
01524       fYf =  TMath::Max(fYp ,y);
01525 
01526       total = selected = 0;
01527 
01528       TIter next(fList);
01529 
01530       while ((el = (TGFrameElement *) next())) {
01531          f = el->fFrame;
01532          ++total;
01533          xf0 = f->GetX() + (f->GetWidth() >> 3);
01534          yf0 = f->GetY() + (f->GetHeight() >> 3);
01535          xff = xf0 + f->GetWidth() - (f->GetWidth() >> 2);
01536          yff = yf0 + f->GetHeight() - (f->GetHeight() >> 2);
01537 
01538          if (((xf0 > fX0 && xf0 < fXf) ||
01539             (xff > fX0 && xff < fXf)) &&
01540             ((yf0 > fY0 && yf0 < fYf) ||
01541             (yff > fY0 && yff < fYf))) {
01542             if (!el->fFrame->IsActive())
01543                ActivateItem(el);
01544             ++selected;
01545          } else {
01546             if (el->fFrame->IsActive())
01547                DeActivateItem(el);
01548          }
01549       }
01550       gVirtualX->DrawRectangle(fId, GetLineGC()(), fX0-pos.fX, fY0-pos.fY,
01551                                fXf-fX0, fYf-fY0);
01552 
01553       if (fTotal != total || fSelected != selected) {
01554          fTotal = total;
01555          fSelected = selected;
01556          SendMessage(fMsgWindow, MK_MSG(kC_CONTAINER, kCT_SELCHANGED),
01557                      fTotal, fSelected);
01558       }
01559       ClearViewPort();
01560       DoRedraw();
01561       gVirtualX->DrawRectangle(fId, GetLineGC()(), fX0-pos.fX, fY0-pos.fY,
01562                                fXf-fX0, fYf-fY0);
01563    }
01564 }
01565 
01566 //______________________________________________________________________________
01567 void TGContainer::SearchPattern()
01568 {
01569    // Search for entry which name begins with pattern.
01570 
01571    TGFrameElement *fe = 0;
01572    TIter next(fList);
01573    TString str;
01574 
01575    while ((fe=( TGFrameElement*)next())) {
01576       str = fe->fFrame->GetTitle();
01577 
01578       if (str.BeginsWith(fKeyInput,TString::kIgnoreCase)) {
01579          if (fLastActiveEl && (fLastActiveEl!=fe) ) {
01580             fLastActiveEl->fFrame->Activate(kFALSE);
01581          }
01582          ActivateItem(fe);
01583          AdjustPosition();
01584          break;
01585       }
01586    }
01587 
01588    fKeyInput = "";   //clear
01589    fKeyTimerActive = kFALSE;
01590 }
01591 
01592 //______________________________________________________________________________
01593 void TGContainer::RepeatSearch()
01594 {
01595    // Repeats search.
01596 
01597    TGFrameElement *fe = 0;
01598 
01599    if (fLastName == "")
01600       return Search();
01601 
01602    fe = (TGFrameElement*)FindItem(fLastName, fLastDir, fLastCase, fLastSubstring);
01603 
01604    if (!fe) {
01605       if (fLastActiveEl) DeActivateItem(fLastActiveEl);
01606       fLastActiveEl = 0;
01607       fe = (TGFrameElement*)FindItem(fLastName, fLastDir, fLastCase, fLastSubstring);
01608 
01609       if (!fe) {
01610          TString msg = "Couldn't find \"" + fLastName + '\"';
01611          gVirtualX->Bell(50);
01612          new TGMsgBox(fClient->GetDefaultRoot(), fCanvas, "Container", msg.Data(),
01613                         kMBIconExclamation, kMBOk, 0);
01614       } else {
01615          if (fLastActiveEl) DeActivateItem(fLastActiveEl);
01616          ActivateItem(fe);
01617          AdjustPosition();
01618       }
01619    } else {
01620       if (fLastActiveEl) DeActivateItem(fLastActiveEl);
01621       ActivateItem(fe);
01622       AdjustPosition();
01623    }
01624 }
01625 
01626 //______________________________________________________________________________
01627 TGFrameElement *TGContainer::FindFrame(Int_t x, Int_t y, Bool_t exclude)
01628 {
01629    // Find frame located int container at position x,y.
01630 
01631    TIter next(fList);
01632    TGFrameElement *el;
01633    TGFrameElement *ret = 0;
01634    Int_t dx = 0;
01635    Int_t dy = 0;
01636    Int_t d = 0;
01637    Int_t dd;
01638 
01639    el = (TGFrameElement *) next();
01640    if (!el) return 0;
01641 
01642    dx = TMath::Abs(el->fFrame->GetX()-x);
01643    dy = TMath::Abs(el->fFrame->GetY()-y);
01644    d = dx + dy;
01645 
01646    while ((el = (TGFrameElement *) next())) {
01647       if (exclude && (el==fLastActiveEl) ) continue;
01648       dx = TMath::Abs(el->fFrame->GetX()-x);
01649       dy = TMath::Abs(el->fFrame->GetY()-y);
01650       dd = dx+dy;
01651 
01652       if (dd<d) {
01653          d = dd;
01654          ret = el;
01655       }
01656    }
01657    return ret;
01658 }
01659 
01660 //______________________________________________________________________________
01661 void *TGContainer::FindItem(const TString& name, Bool_t direction,
01662                             Bool_t caseSensitive, Bool_t subString)
01663 {
01664 
01665    // Find a frame which assosiated object has a name containing a "name"
01666    // string.
01667 
01668    if (name.IsNull()) return 0;
01669    int idx = kNPOS;
01670 
01671    TGFrameElement *el = 0;
01672    TString str;
01673    TString::ECaseCompare cmp = caseSensitive ? TString::kExact : TString::kIgnoreCase;
01674 
01675    fLastDir = direction;
01676    fLastCase = caseSensitive;
01677    fLastName = name;
01678    fLastSubstring = subString;
01679 
01680    if (fLastActiveEl) {
01681       el = fLastActiveEl;
01682 
01683       if (direction) {
01684          el = (TGFrameElement *)fList->After(el);
01685       } else {
01686          el = (TGFrameElement *)fList->Before(el);
01687       }
01688    } else {
01689       if (direction) el = (TGFrameElement *)fList->First();
01690       else el  = (TGFrameElement *)fList->Last();
01691    }
01692 
01693    while (el) {
01694       str = el->fFrame->GetTitle();
01695       idx = str.Index(name, 0, cmp);
01696 
01697       if (idx != kNPOS) {
01698          if (subString) {
01699             return el;
01700          } else {
01701             if (str.Length() == name.Length()) return el;
01702          }
01703       }
01704 
01705       if (direction) {
01706          el = (TGFrameElement *)fList->After(el);
01707       } else {
01708          el = (TGFrameElement *)fList->Before(el);
01709       }
01710    }
01711    return 0;
01712 }
01713 
01714 //______________________________________________________________________________
01715 TGHScrollBar *TGContainer::GetHScrollbar() const
01716 {
01717    // returns pointer to hor. scroll bar
01718 
01719    return fCanvas ? fCanvas->GetHScrollbar() : 0;
01720 }
01721 
01722 //______________________________________________________________________________
01723 TGVScrollBar *TGContainer::GetVScrollbar() const
01724 {
01725    // returns pointer to vert. scroll bar
01726 
01727    return fCanvas ? fCanvas->GetVScrollbar() : 0;
01728 }
01729 
01730 //______________________________________________________________________________
01731 void TGContainer::SetVsbPosition(Int_t newPos)
01732 {
01733    // Set position of vertical scrollbar.
01734 
01735    if (!fViewPort) return;
01736    TGVScrollBar *vb = GetVScrollbar();
01737 
01738    if (vb && vb->IsMapped()) {
01739       vb->SetRange((Int_t)GetHeight(), (Int_t)fViewPort->GetHeight());
01740       vb->SetPosition(newPos);
01741    } else {
01742       fViewPort->SetVPos(0);
01743    }
01744 }
01745 
01746 //______________________________________________________________________________
01747 void TGContainer::SetHsbPosition(Int_t newPos)
01748 {
01749    // set new hor. position
01750 
01751    if (!fViewPort) return;
01752    TGHScrollBar *hb = GetHScrollbar();
01753 
01754    if (hb && hb->IsMapped()) {
01755       hb->SetRange((Int_t)GetWidth(), (Int_t)fViewPort->GetWidth());
01756       hb->SetPosition(newPos);
01757    } else {
01758       fViewPort->SetHPos(0);
01759    }
01760 }
01761 
01762 //______________________________________________________________________________
01763 void TGContainer::AdjustPosition()
01764 {
01765    // Move content to position of highlighted/activated frame.
01766 
01767    if (!fViewPort) return;
01768    if (!fLastActiveEl) return;
01769    TGFrame *f = fLastActiveEl->fFrame;
01770 
01771    Int_t vh = 0;
01772    Int_t v = 0;
01773 
01774    TGHScrollBar *hb = GetHScrollbar();
01775    TGVScrollBar *vb = GetVScrollbar();
01776    Int_t pos = GetPagePosition().fY;
01777    Int_t pg;
01778 
01779 
01780    if (vb && vb->IsMapped()) {
01781       pg = (vb->GetPageSize()*GetHeight())/fViewPort->GetHeight();
01782       vh =  pos + (Int_t)fViewPort->GetHeight();
01783 
01784       if (f->GetY() < pos) {
01785          v = TMath::Max(0, f->GetY() - (Int_t)fViewPort->GetHeight()/2);
01786          v = (v*pg)/GetHeight();
01787 
01788          SetVsbPosition(v);
01789       } else if (f->GetY() + (Int_t)f->GetHeight() > vh) {
01790          v = TMath::Min((Int_t)GetHeight() - (Int_t)fViewPort->GetHeight(),
01791                         f->GetY() + (Int_t)f->GetHeight() - (Int_t)fViewPort->GetHeight()/2);
01792          v = (v*pg)/GetHeight();
01793          SetVsbPosition(v);
01794       }
01795    }
01796 
01797    Int_t hw = 0;
01798    Int_t h = 0;
01799 
01800    if (hb && hb->IsMapped() && (!vb || (vb && !vb->IsMapped()))) {
01801       pg = (hb->GetPageSize()*GetWidth())/fViewPort->GetWidth();
01802       pos =GetPagePosition().fX;
01803       hw = pos + (Int_t)fViewPort->GetWidth();
01804 
01805       if (f->GetX() < pos) {
01806          h = TMath::Max(0, f->GetX() - (Int_t)fViewPort->GetWidth()/2);
01807          h = (h*pg)/GetWidth();
01808 
01809          SetHsbPosition(h);
01810       } else if (f->GetX() + (Int_t)f->GetWidth() > hw) {
01811          h = TMath::Min((Int_t)GetWidth() - (Int_t)fViewPort->GetWidth(),
01812                         f->GetX() + (Int_t)f->GetWidth() - (Int_t)fViewPort->GetWidth()/2);
01813          h = (h*pg)/GetWidth();
01814 
01815          SetHsbPosition(h);
01816       }
01817    }
01818 }
01819 
01820 //______________________________________________________________________________
01821 void TGContainer::LineLeft(Bool_t select)
01822 {
01823    // Move current position one column left.
01824 
01825    TGPosition pos = GetPagePosition();
01826    TGDimension dim = GetPageDimension();
01827 
01828    TGFrameElement *fe = (TGFrameElement*)fList->First();
01829    if (!fe) return; // empty list
01830 
01831    TGFrameElement *old = fLastActiveEl;
01832 
01833    if (old) DeActivateItem(old);   //
01834    else fLastActiveEl = fe;
01835 
01836    TGFrameElement *la = fLastActiveEl;
01837    Int_t dx = la->fLayout->GetPadLeft() + la->fLayout->GetPadRight();
01838    Int_t dy = la->fLayout->GetPadTop() + la->fLayout->GetPadBottom();
01839    Int_t y = la->fFrame->GetY();
01840    Int_t x = la->fFrame->GetX() - dx;
01841 
01842    Int_t hw = pos.fX + dim.fWidth;
01843 
01844    TGHScrollBar *hb = GetHScrollbar();
01845    if (x<=0 && (hb && !hb->IsMapped())) { // move to previous line
01846       x = hw;
01847       y = y - la->fFrame->GetDefaultHeight() - dy;
01848    }
01849 
01850    fe = FindFrame(x, y);
01851    if (!fe) fe = (TGFrameElement*)fList->First();
01852 
01853    if (!select) fSelected=1;
01854 
01855    ActivateItem(fe);
01856    AdjustPosition();
01857 }
01858 
01859 //______________________________________________________________________________
01860 void TGContainer::LineRight(Bool_t select)
01861 {
01862    // Move current position one column right.
01863 
01864    TGPosition pos = GetPagePosition();
01865    TGDimension dim = GetPageDimension();
01866 
01867    TGFrameElement *fe = (TGFrameElement*)fList->Last();
01868    if (!fe) return;
01869 
01870    TGFrameElement *old = fLastActiveEl;
01871 
01872    if (old) DeActivateItem(old);
01873    else fLastActiveEl = (TGFrameElement*)fList->First();
01874 
01875    Int_t dx = fLastActiveEl->fLayout->GetPadLeft() + fLastActiveEl->fLayout->GetPadRight();
01876    Int_t dy = fLastActiveEl->fLayout->GetPadTop() + fLastActiveEl->fLayout->GetPadBottom();
01877    Int_t y = fLastActiveEl->fFrame->GetY();
01878    Int_t x = fLastActiveEl->fFrame->GetX() + fLastActiveEl->fFrame->GetDefaultWidth() + dx;
01879 
01880    Int_t hw = pos.fX + dim.fWidth - dx;
01881 
01882    TGHScrollBar *hb =  GetHScrollbar();
01883    if (x >= hw && (hb && !hb->IsMapped())) { // move one line down
01884       x = 0;
01885       y = y + fLastActiveEl->fFrame->GetDefaultHeight() + dy;
01886    }
01887 
01888    fe = FindFrame(x, y);
01889    if (!fe) fe = (TGFrameElement*)fList->Last();
01890    if (!select) fSelected = 1;
01891 
01892    ActivateItem(fe);
01893    AdjustPosition();
01894 }
01895 
01896 //______________________________________________________________________________
01897 void TGContainer::LineUp(Bool_t select)
01898 {
01899    // Make current position first line in window by scrolling up.
01900 
01901    TGFrameElement *fe = (TGFrameElement*)fList->First();
01902    if (!fe) return;
01903 
01904    TGFrameElement *old = fLastActiveEl;
01905 
01906    if (old) {
01907       DeActivateItem(old);
01908    } else {
01909       fLastActiveEl = (TGFrameElement*)fList->First();
01910    }
01911 
01912    Int_t dy = fLastActiveEl->fLayout->GetPadTop() + fLastActiveEl->fLayout->GetPadBottom();
01913    Int_t y = fLastActiveEl->fFrame->GetY() - dy;
01914    Int_t x = fLastActiveEl->fFrame->GetX();
01915 
01916    fe = FindFrame(x, y);
01917    if (!fe) fe = (TGFrameElement*)fList->First();
01918    if (fe->fFrame->GetY() > fLastActiveEl->fFrame->GetY()) fe = fLastActiveEl;
01919    if (!select) fSelected = 1;
01920 
01921    ActivateItem(fe);
01922    AdjustPosition();
01923 }
01924 
01925 //______________________________________________________________________________
01926 void TGContainer::LineDown(Bool_t select)
01927 {
01928    // Move one line down.
01929 
01930    TGFrameElement *fe = (TGFrameElement*)fList->Last();
01931    if (!fe) return;
01932 
01933    TGFrameElement* old = fLastActiveEl;
01934 
01935    if (old) DeActivateItem(old);
01936    else fLastActiveEl = (TGFrameElement*)fList->First();
01937 
01938    Int_t dy = fLastActiveEl->fLayout->GetPadTop() + fLastActiveEl->fLayout->GetPadBottom();
01939    Int_t y = fLastActiveEl->fFrame->GetY() +
01940              fLastActiveEl->fFrame->GetHeight() + dy;
01941    Int_t x = fLastActiveEl->fFrame->GetX();
01942 
01943    fe = FindFrame(x, y);
01944    if (!fe) fe = (TGFrameElement*)fList->Last();
01945    if (fe->fFrame->GetY() < fLastActiveEl->fFrame->GetY()) fe = fLastActiveEl;
01946    if (!select) fSelected = 1;
01947 
01948    ActivateItem(fe);
01949    AdjustPosition();
01950 }
01951 
01952 //______________________________________________________________________________
01953 void TGContainer::PageUp(Bool_t select)
01954 {
01955    // Move  position one page up.
01956 
01957    TGDimension dim = GetPageDimension();
01958 
01959    TGFrameElement *fe = (TGFrameElement*)fList->First();
01960    if (!fe) return;
01961 
01962    TGFrameElement* old = fLastActiveEl;
01963 
01964    if (old) DeActivateItem(old);
01965    else fLastActiveEl = (TGFrameElement*)fList->First();
01966 
01967    Int_t y = fLastActiveEl->fFrame->GetY();
01968    Int_t x = fLastActiveEl->fFrame->GetX();
01969 
01970    TGVScrollBar *vb =  GetVScrollbar();
01971    TGHScrollBar *hb =  GetHScrollbar();
01972 
01973    if (vb && vb->IsMapped()) {
01974       y -= dim.fHeight;
01975    } else {
01976       if (hb && hb->IsMapped()) {
01977          x -= dim.fWidth;
01978       } else {
01979          Home();
01980          return;
01981       }
01982    }
01983 
01984    fe = FindFrame(x, y);
01985 
01986    if (!fe || fe->fFrame->GetY()>fLastActiveEl->fFrame->GetY()) {
01987       fe = (TGFrameElement*)fList->First();
01988    }
01989 
01990    if (!select) fSelected = 1;
01991 
01992    ActivateItem(fe);
01993    AdjustPosition();
01994 }
01995 
01996 //______________________________________________________________________________
01997 void TGContainer::PageDown(Bool_t select)
01998 {
01999    // Move position one page down.
02000 
02001    TGDimension dim = GetPageDimension();
02002 
02003    TList *li = GetList();
02004    TGFrameElement *fe = (TGFrameElement*)fList->Last();
02005    if (!fe) return;
02006 
02007    TGFrameElement *old = fLastActiveEl;
02008 
02009    if (old) DeActivateItem(old);
02010    else fLastActiveEl = (TGFrameElement*)fList->First();
02011 
02012    Int_t y = fLastActiveEl->fFrame->GetY();
02013    Int_t x = fLastActiveEl->fFrame->GetX();
02014 
02015    TGVScrollBar *vb = GetVScrollbar();
02016    TGHScrollBar *hb = GetHScrollbar();
02017 
02018    if (vb && vb->IsMapped()) {
02019       y += dim.fHeight;
02020    } else {
02021       if (hb && hb->IsMapped()) {
02022          x += dim.fWidth;
02023       } else {
02024          End();
02025          return;
02026       }
02027    }
02028 
02029    fe = FindFrame(x, y);
02030    if (!fe || fe->fFrame->GetY()<fLastActiveEl->fFrame->GetY() ) {
02031       fe = (TGFrameElement*)li->Last();
02032    }
02033 
02034    if (!select) fSelected = 1;
02035 
02036    ActivateItem(fe);
02037    AdjustPosition();
02038 }
02039 
02040 //______________________________________________________________________________
02041 void TGContainer::Home(Bool_t select)
02042 {
02043    // Move to upper-left corner of container.
02044 
02045    TGFrameElement *fe = (TGFrameElement*)fList->First();
02046    if (!fe) return;
02047 
02048    TGFrameElement *old = fLastActiveEl;
02049    if (old) DeActivateItem(old);
02050 
02051    if (!select) fSelected = 1;
02052 
02053    ActivateItem(fe);
02054    AdjustPosition();
02055 }
02056 
02057 //______________________________________________________________________________
02058 void TGContainer::End(Bool_t select)
02059 {
02060    // Move to the bottom-right corner of container.
02061 
02062    TGFrameElement *fe = (TGFrameElement*)fList->Last();
02063    if (!fe) return;
02064 
02065    TGFrameElement *old = fLastActiveEl;
02066    if (old) DeActivateItem(old);
02067 
02068    if (!select) fSelected = 1;
02069 
02070    ActivateItem(fe);
02071    AdjustPosition();
02072 }
02073 
02074 //______________________________________________________________________________
02075 const TGGC &TGContainer::GetLineGC()
02076 {
02077    // Get graphics context for line drawing.
02078 
02079    if (!fgLineGC) {
02080       GCValues_t gval;
02081       gval.fMask = kGCForeground | kGCBackground | kGCFunction | kGCFillStyle |
02082                    kGCLineWidth  | kGCLineStyle  | kGCSubwindowMode |
02083                    kGCGraphicsExposures;
02084       gval.fForeground = fgWhitePixel ^ fgBlackPixel;
02085       gval.fBackground = fgWhitePixel;
02086       gval.fFunction   = kGXxor;
02087       gval.fLineWidth  = 0;
02088       gval.fLineStyle  = kLineOnOffDash;
02089       gval.fFillStyle  = kFillSolid;
02090       gval.fSubwindowMode = kIncludeInferiors;
02091       gval.fGraphicsExposures = kFALSE;
02092       fgLineGC = gClient->GetGC(&gval, kTRUE);
02093       fgLineGC->SetDashOffset(0);
02094       fgLineGC->SetDashList("\x1\x1", 2);
02095    }
02096    return *fgLineGC;
02097 }
02098 
02099 //______________________________________________________________________________
02100 TGCanvas::TGCanvas(const TGWindow *p, UInt_t w, UInt_t h,
02101                    UInt_t options, ULong_t back) :
02102     TGFrame(p, w, h, options, back)
02103 {
02104    // Create a canvas object.
02105 
02106    fVport      = new TGViewPort(this, w-4, h-4, kChildFrame | kOwnBackground,
02107                                 fgWhitePixel);
02108    fHScrollbar = new TGHScrollBar(this, w-4, kDefaultScrollBarWidth);
02109    fVScrollbar = new TGVScrollBar(this, kDefaultScrollBarWidth, h-4);
02110 
02111    fScrolling  = kCanvasScrollBoth;
02112 
02113    fHScrollbar->Associate(this);
02114    fVScrollbar->Associate(this);
02115 
02116    fVport->Move(fBorderWidth, fBorderWidth);
02117 
02118    SetWindowName();
02119 
02120    fVScrollbar->SetEditDisabled(kEditDisable | kEditDisableGrab | kEditDisableBtnEnable);
02121    fHScrollbar->SetEditDisabled(kEditDisable | kEditDisableGrab | kEditDisableBtnEnable);
02122 }
02123 
02124 //______________________________________________________________________________
02125 TGCanvas::~TGCanvas()
02126 {
02127    // Delete canvas.
02128 
02129    delete fHScrollbar;
02130    delete fVScrollbar;
02131    delete fVport;
02132 }
02133 
02134 //______________________________________________________________________________
02135 void TGCanvas::MapSubwindows()
02136 {
02137    // Map all canvas sub windows.
02138 
02139    if (fHScrollbar) fHScrollbar->MapSubwindows();
02140    if (fVScrollbar) fVScrollbar->MapSubwindows();
02141 
02142    if (fVport) {
02143       TGFrame *container = fVport->GetContainer();
02144       if (!container) {
02145          Error("MapSubwindows", "no canvas container set yet");
02146          return;
02147       }
02148       container->MapSubwindows();
02149       fVport->MapSubwindows();
02150       fVport->MapWindow();
02151    }
02152    Layout();
02153 }
02154 
02155 //______________________________________________________________________________
02156 void TGCanvas::AddFrame(TGFrame *f, TGLayoutHints *l)
02157 {
02158    // Adding a frame to a canvas is actually adding the frame to the
02159    // viewport container. The viewport container must be at least a
02160    // TGCompositeFrame for this method to succeed.
02161 
02162    TGFrame *container = fVport->GetContainer();
02163    if (!container) {
02164       Error("AddFrame", "no canvas container set yet");
02165       return;
02166    }
02167    if (container->InheritsFrom(TGCompositeFrame::Class()))
02168       ((TGCompositeFrame*)container)->AddFrame(f, l);
02169    else
02170       Error("AddFrame", "canvas container must inherit from TGCompositeFrame");
02171 }
02172 
02173 //______________________________________________________________________________
02174 void TGCanvas::DrawBorder()
02175 {
02176    // Draw canvas border.
02177 
02178    switch (fOptions & (kSunkenFrame | kRaisedFrame | kDoubleBorder)) {
02179       case kSunkenFrame | kDoubleBorder:
02180          gVirtualX->DrawLine(fId, GetShadowGC()(), 0, 0, fWidth-2, 0);
02181          gVirtualX->DrawLine(fId, GetShadowGC()(), 0, 0, 0, fHeight-2);
02182          gVirtualX->DrawLine(fId, GetBlackGC()(), 1, 1, fWidth-3, 1);
02183          gVirtualX->DrawLine(fId, GetBlackGC()(), 1, 1, 1, fHeight-3);
02184 
02185          gVirtualX->DrawLine(fId, GetHilightGC()(), 0, fHeight-1, fWidth-1, fHeight-1);
02186          gVirtualX->DrawLine(fId, GetHilightGC()(), fWidth-1, fHeight-1, fWidth-1, 0);
02187          gVirtualX->DrawLine(fId, GetBckgndGC()(),  1, fHeight-2, fWidth-2, fHeight-2);
02188          gVirtualX->DrawLine(fId, GetBckgndGC()(),  fWidth-2, 1, fWidth-2, fHeight-2);
02189          break;
02190 
02191       default:
02192          TGFrame::DrawBorder();
02193          break;
02194    }
02195 }
02196 
02197 //______________________________________________________________________________
02198 void TGCanvas::Layout()
02199 {
02200    // Create layout for canvas. Depending on the size of the container
02201    // we need to add the scrollbars.
02202 
02203    Bool_t   need_vsb, need_hsb;
02204    UInt_t   cw, ch, tcw, tch;
02205 
02206    need_vsb = need_hsb = kFALSE;
02207 
02208    TGFrame *container = fVport->GetContainer();
02209    if (!container) {
02210       Error("Layout", "no canvas container set yet");
02211       return;
02212    }
02213 
02214    Bool_t fixedw = container->IsLayoutBroken() || (container->GetOptions() & kFixedWidth) ?
02215                    kTRUE : kFALSE;
02216    Bool_t fixedh = container->IsLayoutBroken() || (container->GetOptions() & kFixedHeight) ?
02217                    kTRUE : kFALSE;
02218 
02219    // test whether we need scrollbars
02220    cw = fWidth  - UInt_t(fBorderWidth << 1);
02221    ch = fHeight - UInt_t(fBorderWidth << 1);
02222 
02223    if (!fixedw) container->SetWidth(cw);
02224    if (!fixedh) container->SetHeight(ch);
02225 
02226    if (container->GetDefaultWidth() > cw) {
02227       if ((fScrolling & kCanvasScrollHorizontal) && fHScrollbar) {
02228          need_hsb = kTRUE;
02229          ch -= fHScrollbar->GetDefaultHeight();
02230          if ((Int_t) ch < 0) {
02231             //Warning("Layout", "height would become too small, setting to 10");
02232             ch = 10;
02233          }
02234          if (!fixedh) container->SetHeight(ch);
02235       }
02236    }
02237 
02238    if (container->GetDefaultHeight() > ch) {
02239       if ((fScrolling & kCanvasScrollVertical) && fVScrollbar) {
02240          need_vsb = kTRUE;
02241          cw -= fVScrollbar->GetDefaultWidth();
02242          if ((Int_t) cw < 0) {
02243             //Warning("Layout", "width would become too small, setting to 10");
02244             cw = 10;
02245          }
02246          if (!fixedw) container->SetWidth(cw);
02247       }
02248    }
02249 
02250    // re-check again (putting the vertical scrollbar could have changed things)
02251 
02252    if (container->GetDefaultWidth() > cw) {
02253       if (!need_hsb) {
02254          if ((fScrolling & kCanvasScrollHorizontal) && fHScrollbar) {
02255             need_hsb = kTRUE;
02256             ch -= fHScrollbar->GetDefaultHeight();
02257             if ((Int_t) ch < 0) {
02258                //Warning("Layout", "height would become too small, setting to 10");
02259                ch = 10;
02260             }
02261             if (!fixedh) container->SetHeight(ch);
02262          }
02263       }
02264    }
02265 
02266    fVport->MoveResize(fBorderWidth, fBorderWidth, cw, ch);
02267 
02268    tcw = TMath::Max(container->GetDefaultWidth(), cw);
02269    tch = TMath::Max(container->GetDefaultHeight(), ch);
02270    UInt_t curw = container->GetDefaultWidth();
02271 
02272    container->SetWidth(0); // force a resize in TGFrame::Resize
02273 
02274    if (fixedw && fixedh) {
02275       container->Resize(curw, container->GetDefaultHeight());
02276    } else if (fixedw) {
02277       container->Resize(curw, tch);
02278    } else if (fixedh) {
02279       container->Resize(tcw, container->GetDefaultHeight());
02280    } else {
02281       container->Resize(tcw, tch);
02282    }
02283 
02284    if (fHScrollbar) {
02285       if (need_hsb) {
02286          fHScrollbar->MoveResize(fBorderWidth, ch+fBorderWidth, cw, fHScrollbar->GetDefaultHeight());
02287          fHScrollbar->SetRange((Int_t)container->GetWidth(), (Int_t)fVport->GetWidth());
02288          fHScrollbar->MapWindow();
02289       } else {
02290          fHScrollbar->UnmapWindow();
02291          fHScrollbar->SetPosition(0);
02292          if (container->IsLayoutBroken()) {
02293             container->Resize(fVport->GetWidth(), container->GetHeight());
02294          }
02295       }
02296    }
02297 
02298    if (fVScrollbar) {
02299       if (need_vsb) {
02300          fVScrollbar->MoveResize(cw+fBorderWidth, fBorderWidth, fVScrollbar->GetDefaultWidth(), ch);
02301          fVScrollbar->SetRange((Int_t)container->GetHeight(), (Int_t)fVport->GetHeight());
02302          fVScrollbar->MapWindow();
02303       } else {
02304          fVScrollbar->UnmapWindow();
02305          fVScrollbar->SetPosition(0);
02306          if (container->IsLayoutBroken()) {
02307             container->Resize(container->GetWidth(), fVport->GetHeight());
02308          }
02309       }
02310    }
02311 }
02312 
02313 //______________________________________________________________________________
02314 Bool_t TGCanvas::ProcessMessage(Long_t msg, Long_t parm1, Long_t)
02315 {
02316    // Handle message generated by the canvas scrollbars.
02317 
02318    switch (GET_MSG(msg)) {
02319       case kC_HSCROLL:
02320          switch (GET_SUBMSG(msg)) {
02321             case kSB_SLIDERTRACK:
02322             case kSB_SLIDERPOS:
02323                fVport->SetHPos((Int_t)-parm1);
02324                break;
02325          }
02326          break;
02327 
02328       case kC_VSCROLL:
02329          switch (GET_SUBMSG(msg)) {
02330             case kSB_SLIDERTRACK:
02331             case kSB_SLIDERPOS:
02332                fVport->SetVPos((Int_t)-parm1);
02333                break;
02334          }
02335          break;
02336 
02337       default:
02338          break;
02339    }
02340    return kTRUE;
02341 }
02342 
02343 //______________________________________________________________________________
02344 Int_t TGCanvas::GetHsbPosition() const
02345 {
02346    // Get position of horizontal scrollbar.
02347 
02348    if (fHScrollbar && fHScrollbar->IsMapped())
02349       return fHScrollbar->GetPosition();
02350    return 0;
02351 }
02352 
02353 //______________________________________________________________________________
02354 Int_t TGCanvas::GetVsbPosition() const
02355 {
02356    // Get position of vertical scrollbar.
02357 
02358    if (fVScrollbar && fVScrollbar->IsMapped())
02359       return fVScrollbar->GetPosition();
02360    return 0;
02361 }
02362 
02363 //______________________________________________________________________________
02364 void TGCanvas::SetHsbPosition(Int_t newPos)
02365 {
02366    // Set position of horizontal scrollbar.
02367 
02368    if (fHScrollbar && fHScrollbar->IsMapped()) {
02369       TGFrame *container = fVport->GetContainer();
02370       fHScrollbar->SetRange((Int_t)container->GetWidth(), (Int_t)fVport->GetWidth());
02371       fHScrollbar->SetPosition(newPos);
02372    } else {
02373       fVport->SetHPos(0);
02374    }
02375 }
02376 
02377 //______________________________________________________________________________
02378 void TGCanvas::SetVsbPosition(Int_t newPos)
02379 {
02380    // Set position of vertical scrollbar.
02381 
02382    if (fVScrollbar && fVScrollbar->IsMapped()) {
02383       TGFrame *container = fVport->GetContainer();
02384       fVScrollbar->SetRange((Int_t)container->GetHeight(), (Int_t)fVport->GetHeight());
02385       fVScrollbar->SetPosition(newPos);
02386    } else {
02387       fVport->SetVPos(0);
02388    }
02389 }
02390 
02391 //______________________________________________________________________________
02392 void TGCanvas::SetScrolling(Int_t scrolling)
02393 {
02394    // Set scrolling policy. Use values defined by the enum: kCanvasNoScroll,
02395    // kCanvasScrollHorizontal, kCanvasScrollVertical, kCanvasScrollBoth.
02396 
02397    if (scrolling != fScrolling) {
02398       fScrolling = scrolling;
02399       Layout();
02400    }
02401 }
02402 
02403 //______________________________________________________________________________
02404 void TGCanvas::ClearViewPort()
02405 {
02406    // Clear view port and redraw content.
02407 
02408    TGFrame *cont = GetContainer();
02409    if (!cont) return;
02410 
02411    gVirtualX->ClearArea(cont->GetId(), 0, 0, fVport->GetWidth(), fVport->GetHeight());
02412    fClient->NeedRedraw(cont);
02413 }
02414 
02415 //______________________________________________________________________________
02416 void TGCanvas::SavePrimitive(ostream &out, Option_t *option /*= ""*/)
02417 {
02418    // Save a canvas widget as a C++ statement(s) on output stream out.
02419 
02420    if (fBackground != GetDefaultFrameBackground()) SaveUserColor(out, option);
02421 
02422    out << endl << "   // canvas widget" << endl;
02423 
02424    out << "   TGCanvas *";
02425    out << GetName() << " = new TGCanvas("<< fParent->GetName()
02426        << "," << GetWidth() << "," << GetHeight();
02427 
02428    if (fBackground == GetDefaultFrameBackground()) {
02429       if (GetOptions() == (kSunkenFrame | kDoubleBorder)) {
02430          out << ");" << endl;
02431       } else {
02432          out << "," << GetOptionString() << ");" << endl;
02433       }
02434    } else {
02435       out << "," << GetOptionString() << ",ucolor);" << endl;
02436    }
02437    if (option && strstr(option, "keep_names"))
02438       out << "   " << GetName() << "->SetName(\"" << GetName() << "\");" << endl;
02439 
02440    TGViewPort *vp = GetViewPort();
02441    out << endl << "   // canvas viewport" << endl;
02442    out << "   TGViewPort *" << vp->GetName() << " = " << GetName()
02443        << "->GetViewPort();" << endl;
02444 
02445    TGContainer *cont = (TGContainer*)GetContainer();
02446    cont->SavePrimitive(out, option);
02447 
02448    out << "   " << vp->GetName() << "->AddFrame(" << cont->GetName()
02449        << ");" << endl;
02450 
02451    out << "   " << cont->GetName() << "->SetLayoutManager(";
02452    cont->GetLayoutManager()->SavePrimitive(out, option);
02453    out << ");"<< endl;
02454 
02455    out << "   " << cont->GetName() << "->MapSubwindows();" << endl;
02456 
02457    out << "   " << GetName() << "->SetContainer(" << cont->GetName()
02458        << ");" << endl;
02459 
02460    out << "   " << GetName() << "->MapSubwindows();" << endl;
02461 
02462    if (fHScrollbar && fHScrollbar->IsMapped())
02463       out << "   " << GetName() << "->SetHsbPosition(" << GetHsbPosition()
02464           << ");" << endl;
02465 
02466 
02467    if (fVScrollbar && fVScrollbar->IsMapped())
02468       out << "   " << GetName() << "->SetVsbPosition(" << GetVsbPosition()
02469           << ");" << endl;
02470 
02471 }
02472 
02473 //______________________________________________________________________________
02474 void TGContainer::SavePrimitive(ostream &out, Option_t *option /*= ""*/)
02475 {
02476    // Save a canvas container as a C++ statement(s) on output stream out.
02477 
02478    if (fBackground != GetDefaultFrameBackground()) SaveUserColor(out, option);
02479 
02480    out << endl << "   // canvas container" << endl;
02481 
02482    if ((fParent->GetParent())->InheritsFrom(TGCanvas::Class())) {
02483       out << GetName() << " = new TGContainer(" << GetCanvas()->GetName();
02484    } else {
02485       out << GetName() << " = new TGContainer(" << fParent->GetName();
02486       out << "," << GetWidth() << "," << GetHeight();
02487    }
02488 
02489    if (fBackground == GetDefaultFrameBackground()) {
02490       if (GetOptions() == (kSunkenFrame | kDoubleBorder)) {
02491          out <<");" << endl;
02492       } else {
02493          out << "," << GetOptionString() <<");" << endl;
02494       }
02495    } else {
02496       out << "," << GetOptionString() << ",ucolor);" << endl;
02497    }
02498    if (option && strstr(option, "keep_names"))
02499       out << "   " << GetName() << "->SetName(\"" << GetName() << "\");" << endl;
02500 }

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