#include "TGCanvas.h"
#include "TGListView.h"
#include "TGScrollBar.h"
#include "TTimer.h"
#include "KeySymbols.h"
#include "TSystem.h"
#include "TGTextEditDialogs.h"
#include "TGMsgBox.h"
#include "TGResourcePool.h"
#include "TList.h"
#include "TClass.h"
#include "TGListView.h"
#include "TGMimeTypes.h"
#include "TKey.h"
#include "TKeyMapFile.h"
#include "TGDNDManager.h"
#include "Riostream.h"
TGGC *TGContainer::fgLineGC = 0;
const Int_t kAutoScrollFudge = 10;
const Int_t kAcceleration[kAutoScrollFudge+1] = {1,1,1,2,3,4,6,7,8,16,32};
const Int_t kKeyboardTime = 700;
ClassImp(TGCanvas)
ClassImp(TGViewPort)
ClassImp(TGContainer)
class TGContainerKeyboardTimer : public TTimer {
private:
   TGContainer   *fContainer;
public:
   TGContainerKeyboardTimer(TGContainer *t) : TTimer(kKeyboardTime) { fContainer = t; }
   Bool_t Notify();
};
Bool_t TGContainerKeyboardTimer::Notify()
{
   
   fContainer->SearchPattern();
   Reset();
   if (gSystem) gSystem->RemoveTimer(this);
   return kFALSE;
}
class TGContainerScrollTimer : public TTimer {
private:
   TGContainer   *fContainer;
public:
   TGContainerScrollTimer(TGContainer *t) : TTimer(50) { fContainer = t; }
   Bool_t Notify();
};
Bool_t TGContainerScrollTimer::Notify()
{
   
   fContainer->OnAutoScroll();
   Reset();
   return kFALSE;
}
TGViewPort::TGViewPort(const TGWindow *p, UInt_t w, UInt_t h,
                       UInt_t options, ULong_t back) :
    TGCompositeFrame(p, w, h, options, back)
{
   
   fContainer = 0;
   fX0 = fY0  = 0;
   AddInput(kStructureNotifyMask);
   SetWindowName();
   fEditDisabled = kEditDisable | kEditDisableGrab;
}
void TGViewPort::SetContainer(TGFrame *f)
{
   
   
   
   if (!f) {
      RemoveFrame(fContainer);
      fContainer = 0;
      return;
   }
   if (!fContainer) {
      fContainer = f;
      AddFrame(f, 0);
      fContainer->SetEditDisabled(fContainer->GetEditDisabled() | kEditDisableGrab);
      if (fContainer->InheritsFrom(TGContainer::Class())) {
         ((TGContainer*)fContainer)->fViewPort = this;
         if (fParent->InheritsFrom(TGCanvas::Class()))
            ((TGContainer*)fContainer)->fCanvas = (TGCanvas*)fParent;
      }
   }
}
void TGViewPort::SetHPos(Int_t xpos)
{
   
   Int_t diff;
   if (!fContainer) return;
   if (!fContainer->InheritsFrom(TGContainer::Class())) {
      fContainer->Move(fX0 = xpos, fY0);
      return;
   } else {
      if (((TGContainer*)fContainer)->fMapSubwindows) {
         fContainer->Move(fX0 = xpos, fY0);
         return;
      }
   }
   if (-xpos < 0) return;
   else diff = xpos - fX0;
   UInt_t adiff = TMath::Abs(diff);
   if (!diff) return;
   fX0 = xpos;
   if (adiff < fWidth) {
      if (diff < 0) {
         gVirtualX->CopyArea(fContainer->GetId(), fContainer->GetId(), GetWhiteGC()(),
                              adiff, 0, fWidth, fHeight, 0, 0);
         gVirtualX->ClearArea(fContainer->GetId(), fWidth - adiff, 0, adiff, fHeight);
         ((TGContainer*)fContainer)->DrawRegion(fWidth - adiff, 0, adiff, fHeight);
      } else {
         gVirtualX->CopyArea(fContainer->GetId(), fContainer->GetId(), GetWhiteGC()(),
                              0, 0, fWidth - adiff, fHeight, adiff, 0);
#ifndef WIN32
         adiff = adiff + 1;
#else
         adiff = adiff << 1;
#endif
         gVirtualX->ClearArea(fContainer->GetId(), 0, 0, adiff, fHeight);
         ((TGContainer*)fContainer)->DrawRegion(0, 0, adiff, fHeight);
      }
   } else {
      gVirtualX->ClearArea(fContainer->GetId(), 0, 0, fWidth, fHeight);
      ((TGContainer*)fContainer)->DrawRegion(0, 0, fWidth, fHeight);
   }
}
void TGViewPort::SetVPos(Int_t ypos)
{
   
   Int_t diff;
   if (!fContainer) return;
   
   if (!fContainer->InheritsFrom(TGContainer::Class())) {
      fContainer->Move(fX0, fY0 = ypos);
      return;
   } else {
      if (((TGContainer*)fContainer)->fMapSubwindows) {
         fContainer->Move(fX0, fY0 = ypos);
         return;
      }
   }
   if (-ypos < 0) return;
   else diff = ypos - fY0;
   UInt_t adiff = TMath::Abs(diff);
   if (!diff) return;
   fY0 = ypos;
   if (adiff < fHeight) {
      if (diff < 0) {
         gVirtualX->CopyArea(fContainer->GetId(), fContainer->GetId(), GetWhiteGC()(),
                              0, adiff, fWidth, fHeight, 0, 0);
         gVirtualX->ClearArea(fContainer->GetId(), 0, fHeight - adiff, fWidth, adiff);
         ((TGContainer*)fContainer)->DrawRegion(0, fHeight - adiff, fWidth, adiff);
      } else {
         gVirtualX->CopyArea(fContainer->GetId(), fContainer->GetId(), GetWhiteGC()(),
                              0, 0, fWidth, fHeight - adiff, 0, adiff);
#ifndef WIN32
         adiff = adiff + 1;
#else
         adiff = adiff << 1;
#endif
         gVirtualX->ClearArea(fContainer->GetId(), 0, 0, fWidth, adiff);
         ((TGContainer*)fContainer)->DrawRegion(0, 0, fWidth, adiff);
      }
   } else {
      gVirtualX->ClearArea(fContainer->GetId(), 0, 0, fWidth, fHeight);
      ((TGContainer*)fContainer)->DrawRegion(0, 0, fWidth, fHeight);
   }
}
void TGViewPort::SetPos(Int_t xpos, Int_t ypos)
{
   
   if (!fContainer) return;
   SetHPos(fX0 = xpos);
   SetVPos(fY0 = ypos);
}
Bool_t TGViewPort::HandleConfigureNotify(Event_t *event)
{
   
   if (!fContainer->InheritsFrom(TGContainer::Class())) {
      TGFrame::HandleConfigureNotify(event);
      return kTRUE;
   }
   TGContainer *cont = (TGContainer*)fContainer;
   cont->DrawRegion(event->fX, event->fY, event->fWidth, event->fHeight);
   return kTRUE;
}
TGContainer::TGContainer(const TGWindow *p, UInt_t w, UInt_t h,
                             UInt_t options, ULong_t back) :
   TGCompositeFrame(p, w, h, options, back)
{
   
   
   
   fBdown = kFALSE;
   fMsgWindow  = p;
   fDragging   = kFALSE;
   fTotal = fSelected = 0;
   fMapSubwindows = kFALSE;
   fOnMouseOver = kFALSE;
   fLastActiveEl = 0;
   fLastDir = kTRUE;
   fLastCase = kTRUE;
   fKeyTimer = new TGContainerKeyboardTimer(this);
   fScrollTimer = new TGContainerScrollTimer(this);
   fKeyTimerActive = kFALSE;
   fScrolling = kFALSE;
   fCanvas = 0;
   gVirtualX->GrabButton(fId, kAnyButton, kAnyModifier,
                         kButtonPressMask | kButtonReleaseMask |
                         kPointerMotionMask, kNone, kNone);
   AddInput(kKeyPressMask | kPointerMotionMask);
   SetWindowName();
   fEditDisabled = kEditDisableGrab | kEditDisableBtnEnable;
}
TGContainer::TGContainer(TGCanvas *p, UInt_t options, ULong_t back) :
   TGCompositeFrame(p->GetViewPort(), p->GetWidth(), p->GetHeight(), options, back)
{
   
   
   
   fBdown = kFALSE;
   fMsgWindow  = p->GetViewPort();
   fCanvas = p;
   fCanvas->GetViewPort()->SetContainer(this);
   p->GetViewPort()->SetBackgroundColor(back);
   fDragging = kFALSE;
   fTotal = fSelected = 0;
   fMapSubwindows = kFALSE;
   fOnMouseOver = kFALSE;
   fLastActiveEl = 0;
   fLastDir = kTRUE;
   fLastCase = kTRUE;
   fKeyTimer = new TGContainerKeyboardTimer(this);
   fScrollTimer = new TGContainerScrollTimer(this);
   fKeyTimerActive = kFALSE;
   fScrolling = kFALSE;
   gVirtualX->GrabButton(fId, kAnyButton, kAnyModifier,
                         kButtonPressMask | kButtonReleaseMask |
                         kPointerMotionMask, kNone, kNone);
   AddInput(kKeyPressMask | kPointerMotionMask);
   SetWindowName();
   fEditDisabled = kEditDisableGrab | kEditDisableBtnEnable;
}
TGContainer::~TGContainer()
{
   
   if (TGSearchDialog::SearchDialog()) {
      TQObject::Disconnect(TGSearchDialog::SearchDialog(), 0, this);
   }
   delete fScrollTimer;
   fScrollTimer = 0;
   delete fKeyTimer;
   fKeyTimer = 0;
}
void TGContainer::Layout()
{
   
   ClearViewPort();
   TGCompositeFrame::Layout();
}
void TGContainer::CurrentChanged(Int_t x, Int_t y)
{
   
   Long_t args[2];
   args[0] = x;
   args[1] = y;
   Emit("CurrentChanged(Int_t,Int_t)",args);
}
void TGContainer::CurrentChanged(TGFrame* f)
{
   
   Emit("CurrentChanged(TGFrame*)", (Long_t)f);
}
void TGContainer::KeyPressed(TGFrame *frame, UInt_t keysym, UInt_t mask)
{
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   Long_t args[3];
   args[0] = (Long_t)frame;
   args[1] = (Long_t)keysym;
   args[2] = (Long_t)mask;
   Emit("KeyPressed(TGFame*,ULong_t,ULong_t)", args);
   SendMessage(fMsgWindow, MK_MSG(kC_CONTAINER, kCT_KEY), keysym, mask);
}
void TGContainer::ReturnPressed(TGFrame* f)
{
   
   
   Emit("ReturnPressed(TGFrame*)", (Long_t)f);
}
void TGContainer::SpacePressed(TGFrame* f)
{
   
   
   Emit("SpacePressed(TGFrame*)", (Long_t)f);
}
void TGContainer::OnMouseOver(TGFrame* f)
{
   
   if (!fOnMouseOver) Emit("OnMouseOver(TGFrame*)", (Long_t)f);
   fOnMouseOver = kTRUE;
}
void TGContainer::Clicked(TGFrame *entry, Int_t btn)
{
   
   Long_t args[2];
   args[0] = (Long_t)entry;
   args[1] = btn;
   Emit("Clicked(TGFrame*,Int_t)", args);
}
void TGContainer::Clicked(TGFrame *entry, Int_t btn, Int_t x, Int_t y)
{
   
   Long_t args[4];
   args[0] = (Long_t)entry;
   args[1] = btn;
   args[2] = x;
   args[3] = y;
   Emit("Clicked(TGFrame*,Int_t,Int_t,Int_t)", args);
}
void TGContainer::DoubleClicked(TGFrame *entry, Int_t btn)
{
   
   Long_t args[2];
   args[0] = (Long_t)entry;
   args[1] = btn;
   Emit("DoubleClicked(TGFrame*,Int_t)", args);
}
void TGContainer::DoubleClicked(TGFrame *entry, Int_t btn, Int_t x, Int_t y)
{
   
   Long_t args[4];
   args[0] = (Long_t)entry;
   args[1] = btn;
   args[2] = x;
   args[3] = y;
   Emit("DoubleClicked(TGFrame*,Int_t,Int_t,Int_t)", args);
}
void TGContainer::SelectAll()
{
   
   
   TIter next(fList);
   TGFrameElement* el;
   while ((el = (TGFrameElement *) next())) {
      el->fFrame->Activate(kTRUE);
   }
   fSelected = fTotal;
   SendMessage(fMsgWindow, MK_MSG(kC_CONTAINER, kCT_SELCHANGED),
                  fTotal, fSelected);
   Emit("SelectAll()");
}
void TGContainer::UnSelectAll()
{
   
   TIter next(fList);
   TGFrameElement *el;
   while ((el = (TGFrameElement *) next())) {
      el->fFrame->Activate(kFALSE);
   }
   fLastActiveEl = 0;
   fSelected = 0;
   SendMessage(fMsgWindow, MK_MSG(kC_CONTAINER, kCT_SELCHANGED),
                  fTotal, fSelected);
   Emit("UnSelectAll()");
}
void TGContainer::InvertSelection()
{
   
   
   int selected = 0;
   TIter next(fList);
   TGFrameElement* el;
   while ((el = (TGFrameElement *) next())) {
      if (!el->fFrame->IsActive()) {
         el->fFrame->Activate(kTRUE);
         ++selected;
      } else {
         el->fFrame->Activate(kFALSE);
      }
   fSelected = selected;
   }
   SendMessage(fMsgWindow, MK_MSG(kC_CONTAINER, kCT_SELCHANGED),
                  fTotal, fSelected);
   Emit("InvertSelection()");
}
void TGContainer::RemoveAll()
{
   
   TGFrameElement *el;
   TIter next(fList);
   while ((el = (TGFrameElement *) next())) {
      el->fFrame->DestroyWindow();
      delete el->fFrame;
      fList->Remove(el);
      delete el;
   }
   fLastActiveEl = 0;
   fSelected = fTotal = 0;
}
void TGContainer::RemoveItem(TGFrame *item)
{
   
   TGFrameElement *el;
   TIter next(fList);
   while ((el = (TGFrameElement *) next())) {
      if (item == el->fFrame) {
         if (fLastActiveEl && item == fLastActiveEl->fFrame) fLastActiveEl = 0;
         item->DestroyWindow();
         delete item;
         fList->Remove(el);
         delete el;
         break;
      }
   }
}
const TGFrame *TGContainer::GetNextSelected(void **current)
{
   
   TGFrame *f;
   TObjLink *lnk = (TObjLink *) *current;
   lnk = (lnk == 0) ? fList->FirstLink() : lnk->Next();
   while (lnk) {
      f = (TGFrame *) ((TGFrameElement *) lnk->GetObject())->fFrame;
      if (f->IsActive()) {
         *current = (void *) lnk;
         return f;
      }
      lnk = lnk->Next();
   }
   return 0;
}
void TGContainer::ActivateItem(TGFrameElement* el)
{
   
   fLastActiveEl = el;
   el->fFrame->Activate(kTRUE);
   if (fLastActiveEl!=el) {
      CurrentChanged(fLastActiveEl->fFrame->GetX(), fLastActiveEl->fFrame->GetY());
      CurrentChanged(fLastActiveEl->fFrame);
      fSelected++;
   }
   if (!fSelected) fSelected = 1;
   SendMessage(fMsgWindow, MK_MSG(kC_CONTAINER, kCT_SELCHANGED), fTotal, fSelected);
   fClient->NeedRedraw(this);
}
void TGContainer::DeActivateItem(TGFrameElement* el)
{
   
   fLastActiveEl = el;
   el->fFrame->Activate(kFALSE);
   SendMessage(fMsgWindow, MK_MSG(kC_CONTAINER, kCT_SELCHANGED), fTotal, fSelected);
   fClient->NeedRedraw(this);
}
TGPosition TGContainer::GetPagePosition() const
{
   
   TGPosition ret;
   if (!fViewPort) return ret;
   ret.fX = -fViewPort->GetHPos();
   ret.fY = -fViewPort->GetVPos();
   return ret;
}
TGDimension TGContainer::GetPageDimension() const
{
   
   TGDimension ret;
   if (!fViewPort) return ret;
   ret.fWidth = fViewPort->GetWidth();
   ret.fHeight = fViewPort->GetHeight();
   return ret;
}
void TGContainer::SetPagePosition(const TGPosition& pos)
{
   
   fViewPort->SetPos(pos.fX, pos.fY);
}
void TGContainer::SetPagePosition(Int_t x, Int_t y)
{
   
   fViewPort->SetPos(x, y);
}
void TGContainer::SetPageDimension(const TGDimension& dim)
{
   
   fViewPort->Resize(dim);
}
void TGContainer::SetPageDimension(UInt_t w, UInt_t h)
{
   
   fViewPort->Resize(w, h);
}
void TGContainer::DoRedraw()
{
   
   DrawRegion(0, 0, fViewPort->GetWidth(), fViewPort->GetHeight());
}
void TGContainer::DrawRegion(Int_t x, Int_t y, UInt_t w, UInt_t h)
{
   
   TGFrameElement *el;
   Handle_t id = fId;
   TGPosition pos = GetPagePosition();
   Int_t xx = pos.fX + x; 
   Int_t yy = pos.fY + y;
   TIter next(fList);
   while ((el = (TGFrameElement *) next())) {
      if ((Int_t(el->fFrame->GetY()) > yy - (Int_t)el->fFrame->GetHeight()) &&
          (Int_t(el->fFrame->GetX()) > xx - (Int_t)el->fFrame->GetWidth()) &&
          (Int_t(el->fFrame->GetY()) < yy + Int_t(h + el->fFrame->GetHeight())) &&
          (Int_t(el->fFrame->GetX()) < xx + Int_t(w + el->fFrame->GetWidth()))) {
         
         if (!fMapSubwindows) {
            el->fFrame->DrawCopy(id, el->fFrame->GetX() - pos.fX, el->fFrame->GetY() - pos.fY);
         } else {
            fClient->NeedRedraw(el->fFrame);
         }
      }
   }
}
void TGContainer::ClearViewPort()
{
   
   gVirtualX->ClearArea(fId, 0, 0, fViewPort->GetWidth(), fViewPort->GetHeight());
}
Bool_t TGContainer::HandleExpose(Event_t *event)
{
   
   if (fMapSubwindows) return TGCompositeFrame::HandleExpose(event);
   if (event->fWindow == GetId()) {
      DrawRegion(event->fX, event->fY, event->fWidth, event->fHeight);
   } else {
      TGCompositeFrame::HandleExpose(event);
   }
   return kTRUE;
}
Bool_t TGContainer::HandleButton(Event_t *event)
{
   
   Int_t total, selected, page = 0;
   TGPosition pos = GetPagePosition();
   TGDimension dim = GetPageDimension();
   Int_t newpos;
   page = dim.fHeight/4;
   if (event->fCode == kButton4) {
      
      newpos = pos.fY - page;
      if (newpos < 0) newpos = 0;
      fCanvas->SetVsbPosition(newpos);
      return kTRUE;
   }
   if (event->fCode == kButton5) {
      
      newpos = fCanvas->GetVsbPosition() + page;
      fCanvas->SetVsbPosition(newpos);
      return kTRUE;
   }
   Int_t xx = pos.fX + event->fX; 
   Int_t yy = pos.fY + event->fY;
   if (event->fType == kButtonPress) {
      gVirtualX->SetInputFocus(fId);
      fXp = pos.fX + event->fX;
      fYp = pos.fY + event->fY;
      fXDND = event->fX;
      fYDND = event->fY;
      fBdown = kTRUE;
      UnSelectAll();
      total = selected = 0;
      TGFrameElement *el;
      TIter next(fList);
      Bool_t select_frame = kFALSE;
      while ((el = (TGFrameElement *) next())) {
         select_frame = kFALSE;
         if (!fMapSubwindows) {
            if ((Int_t(el->fFrame->GetY()) + (Int_t)el->fFrame->GetHeight() > yy ) &&
               (Int_t(el->fFrame->GetX()) + (Int_t)el->fFrame->GetWidth() > xx ) &&
               (Int_t(el->fFrame->GetY()) < yy) &&
               (Int_t(el->fFrame->GetX()) < xx))  {
               select_frame = kTRUE;
            }
         } else {
            if (el->fFrame->GetId() == (Window_t)event->fUser[0]) {
               select_frame = kTRUE;
            }
         }
         if (select_frame) {
            selected++;
            ActivateItem(el);
            Clicked(el->fFrame, event->fCode);
            Clicked(el->fFrame, event->fCode, event->fXRoot, event->fYRoot);
         }
         total++;
      }
      if (fTotal != total || fSelected != selected) {
         fTotal = total;
         fSelected = selected;
         SendMessage(fMsgWindow, MK_MSG(kC_CONTAINER, kCT_SELCHANGED),
                     fTotal, fSelected);
      }
      if ( selected == 0 ) {
         fDragging = kTRUE;
         fX0 = fXf = fXp;
         fY0 = fYf = fYp;
         if (fMapSubwindows) gVirtualX->DrawRectangle(fId, GetLineGC()(), fX0, fY0, fXf-fX0, fYf-fY0);
      }
   }
   if (event->fType == kButtonRelease) {
      gVirtualX->SetInputFocus(fId);
      fBdown = kFALSE;
      if (fDragging) {
         fDragging = kFALSE;
         fScrolling = kFALSE;
         if (gSystem) gSystem->RemoveTimer(fScrollTimer);
         if (fMapSubwindows) gVirtualX->DrawRectangle(fId, GetLineGC()(), fX0, fY0, fXf-fX0, fYf-fY0);
      } else {
         SendMessage(fMsgWindow, MK_MSG(kC_CONTAINER, kCT_ITEMCLICK),
                     event->fCode, (event->fYRoot << 16) | event->fXRoot);
      }
   }
   fClient->NeedRedraw(this);
   return kTRUE;
}
const TGPicture *TGContainer::GetObjPicture(TGFrame *f)
{
   
   
   TObject *obj = 0;
   TClass *cl;
   const TGPicture *pic=0;
   const char *iconname = 0;
   if (f->InheritsFrom("TGLVEntry")) {
      obj = (TObject *)((TGLVEntry *)f)->GetUserData();
      if (obj) {
         if (obj->IsA() == TKey::Class()) {
            cl = TClass::GetClass(((TKey *)obj)->GetClassName());
         } else if (obj->IsA() == TKeyMapFile::Class()) {
            cl = TClass::GetClass(((TKeyMapFile *)obj)->GetTitle());
         } else {
            cl = obj->IsA();
         }
         const char *name = obj->GetIconName() ? obj->GetIconName() : cl->GetName();
         iconname = (strlen(name) > 0) ? name : obj->GetName();
         if (obj->IsA()->InheritsFrom("TGeoVolume")) {
            iconname = obj->GetIconName() ? obj->GetIconName() : obj->IsA()->GetName();
         }
         pic = fClient->GetMimeTypeList()->GetIcon(iconname, kFALSE);
      }
   }
   if (pic == 0) {
      if (obj->IsFolder()) {
         pic = fClient->GetPicture("folder_s.xpm");
      } else {
         pic = fClient->GetPicture("doc_s.xpm");
      }
   }
   return pic;
}
void TGContainer::SetDragPixmap(const TGPicture *p)
{
   
   
   Pixmap_t pic, mask;
   TGPicture *selpic = new TGSelectedPicture(gClient, p);
   pic  = selpic->GetPicture();
   mask = selpic->GetMask();
   if (gDNDManager) {
      gDNDManager->SetDragPixmap(pic, mask, p->GetWidth()/2, 2+p->GetHeight()/2);
   } else {
      gVirtualX->DeletePixmap(pic);
      gVirtualX->DeletePixmap(mask);
   }
}
Bool_t TGContainer::HandleDoubleClick(Event_t *event)
{
   
   TGFrameElement *el;
   TIter next(fList);
   TGPosition pos = GetPagePosition();
   Int_t xx = pos.fX + event->fX; 
   Int_t yy = pos.fY + event->fY;
   Bool_t select_frame = kFALSE;
   while ((el = (TGFrameElement *) next())) {
      select_frame = kFALSE;
      if (!fMapSubwindows) {
         if ((Int_t(el->fFrame->GetY()) + (Int_t)el->fFrame->GetHeight() > yy) &&
            (Int_t(el->fFrame->GetX()) + (Int_t)el->fFrame->GetWidth() > xx) &&
            (Int_t(el->fFrame->GetY()) < yy) &&
            (Int_t(el->fFrame->GetX()) < xx))  {
            select_frame = kTRUE;
         }
      } else {
         if (el->fFrame->GetId() == (Window_t)event->fUser[0]) {
            select_frame = kTRUE;
         }
      }
      if (select_frame) {
         SendMessage(fMsgWindow, MK_MSG(kC_CONTAINER, kCT_ITEMDBLCLICK),
                     event->fCode, (event->fYRoot << 16) | event->fXRoot);
         DoubleClicked(el->fFrame, event->fCode);
         DoubleClicked(el->fFrame, event->fCode, event->fXRoot, event->fYRoot);
         return kTRUE;
      }
   }
   return kTRUE;
}
Bool_t TGContainer::HandleMotion(Event_t *event)
{
   
   int xf0, yf0, xff, yff, total, selected;
   TGPosition pos = GetPagePosition();
   TGDimension dim = GetPageDimension();
   Int_t x = pos.fX + event->fX;
   Int_t y = pos.fY + event->fY;
   TGFrameElement* el = 0;
   TGFrame* f = 0;
   fOnMouseOver = kFALSE;
   if (gDNDManager->IsDragging()) {
      gDNDManager->Drag(event->fXRoot, event->fYRoot,
                        TGDNDManager::GetDNDactionCopy(), event->fTime);
   }
   else if (fDragging) {
      if (fMapSubwindows) gVirtualX->DrawRectangle(fId, GetLineGC()(), fX0, fY0, fXf-fX0, fYf-fY0);
      fX0 =  TMath::Min(fXp,x);
      fY0 =  TMath::Min(fYp,y);
      fXf =  TMath::Max(fXp,x);
      fYf =  TMath::Max(fYp,y);
      total = selected = 0;
      if (event->fX > Int_t(dim.fWidth) - kAutoScrollFudge) {
         fCanvas->SetHsbPosition(x - dim.fWidth);
         fScrolling = kTRUE;
      } else if (event->fX < kAutoScrollFudge) {
         fCanvas->SetHsbPosition(x);
         fScrolling = kTRUE;
      } else if (event->fY > Int_t(dim.fHeight) - kAutoScrollFudge) {
         fCanvas->SetVsbPosition(y - dim.fHeight);
         fScrolling = kTRUE;
      } else if (event->fY < kAutoScrollFudge) {
         fCanvas->SetVsbPosition(y);
         fScrolling = kTRUE;
      }
      TIter next(fList);
      while ((el = (TGFrameElement *) next())) {
         f = el->fFrame;
         ++total;
         xf0 = f->GetX() + (f->GetWidth() >> 3);
         yf0 = f->GetY() + (f->GetHeight() >> 3);
         xff = xf0 + f->GetWidth() - (f->GetWidth() >> 2);
         yff = yf0 + f->GetHeight() - (f->GetHeight() >> 2);
         if (((xf0 > fX0 && xf0 < fXf) ||
              (xff > fX0 && xff < fXf)) &&
             ((yf0 > fY0 && yf0 < fYf) ||
              (yff > fY0 && yff < fYf))) {
            f->Activate(kTRUE);
            gVirtualX->SetCursor(fId, gVirtualX->CreateCursor(kHand));
            OnMouseOver(f);
            ++selected;
         } else {
            f->Activate(kFALSE);
         }
      }
      if (fMapSubwindows) gVirtualX->DrawRectangle(fId, GetLineGC()(), fX0, fY0, fXf-fX0, fYf-fY0);
      if (fTotal != total || fSelected != selected) {
         fTotal = total;
         fSelected = selected;
         SendMessage(fMsgWindow, MK_MSG(kC_CONTAINER, kCT_SELCHANGED),
                     fTotal, fSelected);
      }
      fClient->NeedRedraw(this);
   } else {
      TGFrame *over_frame = 0;
      TIter next(fList);
      while ((el = (TGFrameElement *) next())) {
         if (!fMapSubwindows) {
            if ((Int_t(el->fFrame->GetY()) + (Int_t)el->fFrame->GetHeight() > y) &&
               (Int_t(el->fFrame->GetX()) + (Int_t)el->fFrame->GetWidth() > x) &&
               (Int_t(el->fFrame->GetY()) < y) &&
               (Int_t(el->fFrame->GetX()) < x))  {
               over_frame = el->fFrame;
               break;
            }
         } else {
            if (el->fFrame->GetId() == (Window_t)event->fUser[0]) {
               over_frame = el->fFrame;
               break;
            }
         }
      }
      if (over_frame) {
         if (!gDNDManager->IsDragging()) {
            if (fBdown && ((abs(event->fX - fXDND) > 2) || (abs(event->fY - fYDND) > 2))) {
               if (gDNDManager && over_frame->IsDNDSource()) {
                  SetDragPixmap(GetObjPicture(over_frame));
                  gDNDManager->StartDrag(over_frame, event->fXRoot, event->fYRoot);
               }
            }
         }
         if (gDNDManager->IsDragging()) {
            gDNDManager->Drag(event->fXRoot, event->fYRoot,
                              TGDNDManager::GetDNDactionCopy(), event->fTime);
         }
         else {
            OnMouseOver(over_frame);
            gVirtualX->SetCursor(fId, gVirtualX->CreateCursor(kHand));
         }
      } else {
         gVirtualX->SetCursor(fId, gVirtualX->CreateCursor(kPointer));
      }
   }
   if (fScrolling) {
      if (gSystem) {
         fScrollTimer->Reset();
         gSystem->AddTimer(fScrollTimer);
      }
   }
   return kTRUE;
}
Bool_t TGContainer::HandleKey(Event_t *event)
{
   
   
   char   input[10];
   Int_t  n;
   UInt_t keysym;
   if (event->fType == kGKeyPress) {
      gVirtualX->LookupString(event, input, sizeof(input), keysym);
      n = strlen(input);
      KeyPressed(fLastActiveEl?fLastActiveEl->fFrame:0, keysym, event->fState);
      switch ((EKeySym)keysym) {
         case kKey_Enter:
         case kKey_Return:
            
            SendMessage(GetMessageWindow(), MK_MSG(kC_CONTAINER, kCT_ITEMDBLCLICK),
                              kButton1, (event->fYRoot << 16) | event->fXRoot);
            if (fLastActiveEl) ReturnPressed(fLastActiveEl->fFrame);
            break;
         case kKey_Shift:
         case kKey_Control:
         case kKey_Meta:
         case kKey_Alt:
         case kKey_CapsLock:
         case kKey_NumLock:
         case kKey_ScrollLock:
            return kTRUE;
         case kKey_Space:
            if (fLastActiveEl) {
               fLastActiveEl->fFrame->Activate(!fLastActiveEl->fFrame->IsActive());
               SpacePressed(fLastActiveEl->fFrame);
            }
            break;
         default:
         break;
      }
      if (event->fState & kKeyControlMask) {   
         switch((EKeySym)keysym & ~0x20) {   
            case kKey_A:
               SelectAll();
               break;
            case kKey_B:
               LineLeft();
               break;
            case kKey_C:
               return kTRUE;
            case kKey_D:
               break;
            case kKey_E:
               End();
               break;
            case kKey_F:
               Search();
               break;
            case kKey_G:
               RepeatSearch();
               break;
            case kKey_H:
               LineLeft();
               break;
            case kKey_K:
               End();
               break;
            case kKey_U:
               Home();
               break;
            case kKey_V:
            case kKey_Y:
               return kTRUE;
            case kKey_X:
               return kTRUE;
            default:
               return kTRUE;
         }
      }
      if (n && keysym >= 32 && keysym < 127 &&     
         !(event->fState & kKeyControlMask) &&
          (EKeySym)keysym != kKey_Delete &&
          (EKeySym)keysym != kKey_Backspace) {
         if (fKeyTimerActive) {
            fKeyInput += input;
         } else {
            fKeyInput = input;
            fKeyTimerActive = kTRUE;
            fKeyTimer->Reset();
            if (gSystem) gSystem->AddTimer(fKeyTimer);
         }
      } else {
         switch ((EKeySym)keysym) {
            case kKey_F3:
               RepeatSearch();
               break;
            case kKey_F5:
               Layout();
               break;
            case kKey_F7:
               Search();
               break;
            case kKey_Left:
               LineLeft(event->fState & kKeyShiftMask);
               break;
            case kKey_Right:
               LineRight(event->fState & kKeyShiftMask);
               break;
            case kKey_Up:
               LineUp(event->fState & kKeyShiftMask);
               break;
            case kKey_Down:
               LineDown(event->fState & kKeyShiftMask);
               break;
            case kKey_PageUp:
               PageUp(event->fState & kKeyShiftMask);
               break;
            case kKey_PageDown:
               PageDown(event->fState & kKeyShiftMask);
               break;
            case kKey_Home:
               Home(event->fState & kKeyShiftMask);
               break;
            case kKey_End:
               End(event->fState & kKeyShiftMask);
               break;
            default:
               break;
         }
      }
   }
   fClient->NeedRedraw(this);
   return kTRUE;
}
TGFrame *TGContainer::FindFrameByName(const char *name)
{
   
   if (!IsMapped()) return 0;
   Bool_t direction = kTRUE;
   Bool_t caseSensitive = kFALSE;
   if (gTQSender && (gTQSender == TGSearchDialog::SearchDialog())) {
      caseSensitive = TGSearchDialog::SearchDialog()->GetType()->fCaseSensitive;
      direction = TGSearchDialog::SearchDialog()->GetType()->fDirection;
   }
   char msg[256];
   TGFrameElement *fe = (TGFrameElement*)FindItem(name, direction, caseSensitive);
   if (!fe) {  
      if (fLastActiveEl) fLastActiveEl->fFrame->Activate(kFALSE);
      fLastActiveEl = 0;
      fe = (TGFrameElement*)FindItem(fLastName, fLastDir, fLastCase);
      if (!fe) {
         if (gTQSender && (gTQSender == TGSearchDialog::SearchDialog())) {
            sprintf(msg, "Couldn't find \"%s\"", fLastName.Data());
            gVirtualX->Bell(20);
            new TGMsgBox(fClient->GetDefaultRoot(), fCanvas, "Container", msg,
                          kMBIconExclamation, kMBOk, 0);
         }
         return 0;
      } else {
         if (fLastActiveEl) fLastActiveEl->fFrame->Activate(kFALSE);
         ActivateItem(fe);
         AdjustPosition();
         return fe->fFrame;
      }
   } else {
      if (fLastActiveEl) fLastActiveEl->fFrame->Activate(kFALSE);
      ActivateItem(fe);
      AdjustPosition();
      return fe->fFrame;
   }
   return 0;
}
void TGContainer::Search(Bool_t close)
{
   
   Int_t ret = 0;
   TGSearchType *srch = new TGSearchType;
   srch->fClose = close;
   if (!close) {
      if (!TGSearchDialog::SearchDialog()) {
         TGSearchDialog::SearchDialog() = new TGSearchDialog(fClient->GetDefaultRoot(), fCanvas, 400, 150, srch, &ret);
      }
      TGSearchDialog::SearchDialog()->Connect("TextEntered(char *)", "TGContainer", this, "FindFrameByName(char *)");
      TGSearchDialog::SearchDialog()->MapRaised();
   } else {
      new TGSearchDialog(fClient->GetDefaultRoot(), fCanvas, 400, 150, srch, &ret);
      if (ret) {
         FindFrameByName(srch->fBuffer);
      }
      delete srch;
   }
}
void TGContainer::OnAutoScroll()
{
   
   TGFrameElement* el = 0;
   TGFrame* f = 0;
   int xf0, yf0, xff, yff, total, selected;
   TGDimension dim = GetPageDimension();
   TGPosition pos = GetPagePosition();
   Window_t  dum1, dum2;
   Event_t   ev;
   ev.fType    = kButtonPress;
   Int_t x,y;
   
   Int_t dx = 0;
   Int_t dy = 0;
   
   gVirtualX->QueryPointer(fId,dum1,dum2,ev.fXRoot,ev.fYRoot,x,y,ev.fState);
   
   if (x < kAutoScrollFudge)
      dx = kAutoScrollFudge - x;
   else if ((Int_t)dim.fWidth-kAutoScrollFudge <= x)
      dx = dim.fWidth - kAutoScrollFudge - x;
   
   if (y < kAutoScrollFudge)
      dy = kAutoScrollFudge - y;
   else if ((Int_t)dim.fHeight - kAutoScrollFudge <= y)
      dy = dim.fHeight - kAutoScrollFudge - y;
   if (dx || dy) {
      Int_t adx = TMath::Abs(dx);
      Int_t ady = TMath::Abs(dy);
      if (adx > kAutoScrollFudge) adx = kAutoScrollFudge;
      if (ady > kAutoScrollFudge) ady = kAutoScrollFudge;
      dx *= kAcceleration[adx];
      dy *= kAcceleration[ady];
      fCanvas->SetHsbPosition(pos.fX-dx);
      fCanvas->SetVsbPosition(pos.fY-dy);
      
      x += pos.fX;
      y += pos.fY;
      fX0 =  TMath::Min(fXp,x);
      fY0 =  TMath::Min(fYp,y);
      fXf =  TMath::Max(fXp,x);
      fYf =  TMath::Max(fYp,y);
      total = selected = 0;
      TIter next(fList);
      while ((el = (TGFrameElement *) next())) {
         f = el->fFrame;
         ++total;
         xf0 = f->GetX() + (f->GetWidth() >> 3);
         yf0 = f->GetY() + (f->GetHeight() >> 3);
         xff = xf0 + f->GetWidth() - (f->GetWidth() >> 2);
         yff = yf0 + f->GetHeight() - (f->GetHeight() >> 2);
         if (((xf0 > fX0 && xf0 < fXf) ||
            (xff > fX0 && xff < fXf)) &&
            ((yf0 > fY0 && yf0 < fYf) ||
            (yff > fY0 && yff < fYf))) {
            f->Activate(kTRUE);
            ++selected;
         } else {
            f->Activate(kFALSE);
         }
      }
      if (fMapSubwindows) gVirtualX->DrawRectangle(fId, GetLineGC()(), fX0, fY0, fXf-fX0, fYf-fY0);
      if (fTotal != total || fSelected != selected) {
         fTotal = total;
         fSelected = selected;
         SendMessage(fMsgWindow, MK_MSG(kC_CONTAINER, kCT_SELCHANGED),
                     fTotal, fSelected);
      }
      fClient->NeedRedraw(this);
   }
}
void TGContainer::SearchPattern()
{
   
   TGFrameElement* fe = 0;
   TIter next(fList);
   TString str;
   while ((fe=( TGFrameElement*)next())) {
      str = fe->fFrame->GetTitle();
      if (str.BeginsWith(fKeyInput,TString::kIgnoreCase)) {
         if (fLastActiveEl && (fLastActiveEl!=fe) )
            fLastActiveEl->fFrame->Activate(kFALSE);
         ActivateItem(fe);
         AdjustPosition();
         break;
      }
   }
   fKeyInput = "";   
   fKeyTimerActive = kFALSE;
}
void TGContainer::RepeatSearch()
{
   
   char msg[256];
   TGFrameElement* fe = 0;
   fe = (TGFrameElement*)FindItem(fLastName, fLastDir, fLastCase);
   if (!fe) {
      if (fLastActiveEl) fLastActiveEl->fFrame->Activate(kFALSE);
      fLastActiveEl = 0;
      fe = (TGFrameElement*)FindItem(fLastName, fLastDir, fLastCase);
      if (!fe) {
         sprintf(msg, "Couldn't find \"%s\"", fLastName.Data());
         gVirtualX->Bell(50);
         new TGMsgBox(fClient->GetDefaultRoot(), fCanvas, "Container", msg,
                        kMBIconExclamation, kMBOk, 0);
      } else {
         if (fLastActiveEl) fLastActiveEl->fFrame->Activate(kFALSE);
         ActivateItem(fe);
         AdjustPosition();
      }
   } else {
      if (fLastActiveEl) fLastActiveEl->fFrame->Activate(kFALSE);
      ActivateItem(fe);
      AdjustPosition();
   }
}
TGFrameElement *TGContainer::FindFrame(Int_t x,Int_t y,Bool_t exclude)
{
   
   TIter next(fList);
   TGFrameElement* el;
   TGFrameElement* ret = 0;
   Int_t dx = 0;
   Int_t dy = 0;
   Int_t d = 0;
   Int_t dd;
   el = (TGFrameElement *) next();
   if (!el) return 0;
   dx = TMath::Abs(el->fFrame->GetX()-x);
   dy = TMath::Abs(el->fFrame->GetY()-y);
   d = dx + dy;
   while ((el = (TGFrameElement *) next())) {
      if (exclude && (el==fLastActiveEl) ) continue;
      dx = TMath::Abs(el->fFrame->GetX()-x);
      dy = TMath::Abs(el->fFrame->GetY()-y);
      dd = dx+dy;
      if (dd<d) {
         d = dd;
         ret = el;
      }
   }
   return ret;
}
void *TGContainer::FindItem(const TString& name, Bool_t direction,
                            Bool_t caseSensitive, Bool_t beginWith)
{
   
   
   if (name.IsNull()) return 0;
   int idx = kNPOS;
   TGFrameElement *el = 0;
   TString str;
   TString::ECaseCompare cmp = caseSensitive ? TString::kExact : TString::kIgnoreCase;
   fLastDir = direction;
   fLastCase = caseSensitive;
   fLastName = name;
   if (fLastActiveEl) {
      el = fLastActiveEl;
      if (direction) {
         el = (TGFrameElement *)fList->After(el);
      } else {
         el = (TGFrameElement *)fList->Before(el);
      }
   } else {
      if (direction) el = (TGFrameElement *)fList->First();
      else el  = (TGFrameElement *)fList->Last();
   }
   while (el) {
      str = el->fFrame->GetTitle();
      idx = str.Index(name, 0, cmp);
      if (idx != kNPOS) {
         if (beginWith) {
            if (idx == 0) return el;
         } else {
            if (str.Length() == name.Length()) return el;
         }
      }
      if (direction) {
         el = (TGFrameElement *)fList->After(el);
      } else {
         el = (TGFrameElement *)fList->Before(el);
      }
   }
   return 0;
}
TGHScrollBar *TGContainer::GetHScrollbar() const
{
   
   return fCanvas ? fCanvas->GetHScrollbar() : 0;
}
TGVScrollBar *TGContainer::GetVScrollbar() const
{
   
   return fCanvas ? fCanvas->GetVScrollbar() : 0;
}
void TGContainer::SetVsbPosition(Int_t newPos)
{
   
   TGVScrollBar *vb = GetVScrollbar();
   if (vb && vb->IsMapped()) {
      vb->SetRange((Int_t)GetHeight(), (Int_t)fViewPort->GetHeight());
      vb->SetPosition(newPos);
   } else {
      fViewPort->SetVPos(0);
   }
}
void TGContainer::SetHsbPosition(Int_t newPos)
{
   
   TGHScrollBar *hb = GetHScrollbar();
   if (hb && hb->IsMapped()) {
      hb->SetRange((Int_t)GetWidth(), (Int_t)fViewPort->GetWidth());
      hb->SetPosition(newPos);
   } else {
      fViewPort->SetHPos(0);
   }
}
void TGContainer::AdjustPosition()
{
   
   if (!fLastActiveEl) return;
   TGFrame *f = fLastActiveEl->fFrame;
   Int_t vh = 0;
   Int_t v = 0;
   TGHScrollBar *hb = GetHScrollbar();
   TGVScrollBar *vb = GetVScrollbar();
   Int_t pos = 0;
   Int_t pg;
   if (vb && vb->IsMapped()) {
      pg = (vb->GetPageSize()*GetHeight())/fViewPort->GetHeight();
      pos = vb->GetPosition()*pg;
      vh =  pos + (Int_t)fViewPort->GetHeight();
      if (f->GetY() < pos) {
         v = TMath::Max(0, f->GetY() - (Int_t)fViewPort->GetHeight()/2);
         v = (v*pg)/GetHeight();
         SetVsbPosition(v);
      } else if (f->GetY() + (Int_t)f->GetHeight() > vh) {
         v = TMath::Min((Int_t)GetHeight() - (Int_t)fViewPort->GetHeight(),
                        f->GetY() + (Int_t)f->GetHeight() - (Int_t)fViewPort->GetHeight()/2);
         v = (v*pg)/GetHeight();
         SetVsbPosition(v);
      }
   }
   Int_t hw = 0;
   Int_t h = 0;
   if (hb && hb->IsMapped() && (!vb || (vb && !vb->IsMapped()))) {
      pg = (hb->GetPageSize()*GetWidth())/fViewPort->GetWidth();
      pos = hb->GetPosition()*pg;
      hw = pos + (Int_t)fViewPort->GetWidth();
      if (f->GetX() < pos) {
         h = TMath::Max(0, f->GetX() - (Int_t)fViewPort->GetWidth()/2);
         h = (h*pg)/GetWidth();
         SetHsbPosition(h);
      } else if (f->GetX() + (Int_t)f->GetWidth() > hw) {
         h = TMath::Min((Int_t)GetWidth() - (Int_t)fViewPort->GetWidth(),
                        f->GetX() + (Int_t)f->GetWidth() - (Int_t)fViewPort->GetWidth()/2);
         h = (h*pg)/GetWidth();
         SetHsbPosition(h);
      }
   }
}
void TGContainer::LineLeft(Bool_t select)
{
   
   TGPosition pos = GetPagePosition();
   TGDimension dim = GetPageDimension();
   TGFrameElement* fe = (TGFrameElement*)fList->First();
   if (!fe) return; 
   TGFrameElement* old = fLastActiveEl;
   if (old) old->fFrame->Activate(kFALSE);   
   else fLastActiveEl = fe;
   TGFrameElement* la = fLastActiveEl;
   Int_t y = la->fFrame->GetY();
   Int_t x = la->fFrame->GetX() - la->fFrame->GetWidth() - la->fLayout->GetPadLeft();
   Int_t hw = pos.fX + dim.fWidth;
   TGHScrollBar *hb =  GetHScrollbar();
   if (x<=0 && (hb && !hb->IsMapped())) { 
      x = hw;
      y = y - la->fFrame->GetHeight() - la->fLayout->GetPadTop();
   }
   fe = FindFrame(x,y);
   if (!fe) fe = (TGFrameElement*)fList->First();
   if (!select) fSelected=1;
   ActivateItem(fe);
   AdjustPosition();
}
void TGContainer::LineRight(Bool_t select)
{
   
   TGPosition pos = GetPagePosition();
   TGDimension dim = GetPageDimension();
   TGFrameElement* fe = (TGFrameElement*)fList->Last();
   if (!fe) return;
   TGFrameElement* old = fLastActiveEl;
   if (old) old->fFrame->Activate(kFALSE);
   else fLastActiveEl = (TGFrameElement*)fList->First();
   Int_t y = fLastActiveEl->fFrame->GetY();
   Int_t x = fLastActiveEl->fFrame->GetX()+
             fLastActiveEl->fFrame->GetWidth()+
             fLastActiveEl->fLayout->GetPadRight();
   Int_t hw = pos.fX + dim.fWidth -
             fLastActiveEl->fFrame->GetWidth()-
             fLastActiveEl->fLayout->GetPadRight();
   TGHScrollBar *hb =  GetHScrollbar();
   if (x >= hw && (hb && !hb->IsMapped())) { 
      x = 0;
      y = y + fLastActiveEl->fFrame->GetHeight() + fLastActiveEl->fLayout->GetPadBottom();
   }
   fe = FindFrame(x,y);
   if (!fe) fe = (TGFrameElement*)fList->Last();
   if (!select) fSelected=1;
   ActivateItem(fe);
   AdjustPosition();
}
void TGContainer::LineUp(Bool_t select)
{
   
   TGFrameElement* fe = (TGFrameElement*)fList->First();
   if (!fe) return;
   TGFrameElement* old = fLastActiveEl;
   if (old)
      old->fFrame->Activate(kFALSE);
   else
      fLastActiveEl = (TGFrameElement*)fList->First();
   Int_t y = fLastActiveEl->fFrame->GetY()-
             fLastActiveEl->fFrame->GetHeight()-
             fLastActiveEl->fLayout->GetPadTop();
   Int_t x = fLastActiveEl->fFrame->GetX();
   fe = FindFrame(x,y);
   if (!fe) fe = (TGFrameElement*)fList->First();
   if (fe->fFrame->GetY()>fLastActiveEl->fFrame->GetY()) fe = fLastActiveEl;
   if (!select) fSelected=1;
   ActivateItem(fe);
   AdjustPosition();
}
void TGContainer::LineDown(Bool_t select)
{
   
   TGFrameElement* fe = (TGFrameElement*)fList->Last();
   if (!fe) return;
   TGFrameElement* old = fLastActiveEl;
   if (old) old->fFrame->Activate(kFALSE);
   else fLastActiveEl = (TGFrameElement*)fList->First();
   Int_t y = fLastActiveEl->fFrame->GetY()+
             fLastActiveEl->fFrame->GetHeight()+
             fLastActiveEl->fLayout->GetPadBottom();
   Int_t x = fLastActiveEl->fFrame->GetX();
   fe = FindFrame(x,y);
   if (!fe) fe = (TGFrameElement*)fList->Last();
   if (fe->fFrame->GetY()<fLastActiveEl->fFrame->GetY()) fe = fLastActiveEl;
   if (!select) fSelected=1;
   ActivateItem(fe);
   AdjustPosition();
}
void TGContainer::PageUp(Bool_t select)
{
   
   TGDimension dim = GetPageDimension();
   TGFrameElement* fe = (TGFrameElement*)fList->First();
   if (!fe) return;
   TGFrameElement* old = fLastActiveEl;
   if (old) old->fFrame->Activate(kFALSE);
   else fLastActiveEl = (TGFrameElement*)fList->First();
   Int_t y = fLastActiveEl->fFrame->GetY();
   Int_t x = fLastActiveEl->fFrame->GetX();
   TGVScrollBar *vb =  GetVScrollbar();
   TGHScrollBar *hb =  GetHScrollbar();
   if (vb && vb->IsMapped()) {
      y -= dim.fHeight;
   } else {
      if (hb && hb->IsMapped()) {
         x -= dim.fWidth;
      } else {
         Home();
         return;
      }
   }
   fe = FindFrame(x, y);
   if (!fe || fe->fFrame->GetY()>fLastActiveEl->fFrame->GetY())
      fe = (TGFrameElement*)fList->First();
   if (!select) fSelected = 1;
   ActivateItem(fe);
   AdjustPosition();
}
void TGContainer::PageDown(Bool_t select)
{
   
   TGDimension dim = GetPageDimension();
   TList* li = GetList();
   TGFrameElement* fe = (TGFrameElement*)fList->Last();
   if (!fe) return;
   TGFrameElement* old = fLastActiveEl;
   if (old) old->fFrame->Activate(kFALSE);
   else fLastActiveEl = (TGFrameElement*)fList->First();
   Int_t y = fLastActiveEl->fFrame->GetY();
   Int_t x = fLastActiveEl->fFrame->GetX();
   TGVScrollBar *vb =  GetVScrollbar();
   TGHScrollBar *hb =  GetHScrollbar();
   if (vb && vb->IsMapped()) {
      y +=  dim.fHeight;
   } else {
      if (hb && hb->IsMapped()) {
         x += dim.fWidth;
      } else {
         End();
         return;
      }
   }
   fe = FindFrame(x, y);
   if (!fe || fe->fFrame->GetY()<fLastActiveEl->fFrame->GetY() )
      fe = (TGFrameElement*)li->Last();
   if (!select) fSelected = 1;
   ActivateItem(fe);
   AdjustPosition();
}
void TGContainer::Home(Bool_t select)
{
   
   TGFrameElement* fe = (TGFrameElement*)fList->First();
   if (!fe) return;
   TGFrameElement* old = fLastActiveEl;
   if (old) old->fFrame->Activate(kFALSE);
   if (!select) fSelected = 1;
   ActivateItem(fe);
   AdjustPosition();
}
void TGContainer::End(Bool_t select)
{
   
   TGFrameElement* fe = (TGFrameElement*)fList->Last();
   if (!fe) return;
   TGFrameElement* old = fLastActiveEl;
   if (old) old->fFrame->Activate(kFALSE);
   if (!select) fSelected = 1;
   ActivateItem(fe);
   AdjustPosition();
}
const TGGC &TGContainer::GetLineGC()
{
   
   if (!fgLineGC) {
      GCValues_t gval;
      gval.fMask = kGCForeground | kGCBackground | kGCFunction | kGCFillStyle |
                   kGCLineWidth  | kGCLineStyle  | kGCSubwindowMode |
                   kGCGraphicsExposures;
      gval.fForeground = fgWhitePixel ^ fgBlackPixel;
      gval.fBackground = fgWhitePixel;
      gval.fFunction   = kGXxor;
      gval.fLineWidth  = 0;
      gval.fLineStyle  = kLineOnOffDash;
      gval.fFillStyle  = kFillSolid;
      gval.fSubwindowMode = kIncludeInferiors;
      gval.fGraphicsExposures = kFALSE;
      fgLineGC = gClient->GetGC(&gval, kTRUE);
      fgLineGC->SetDashOffset(0);
      fgLineGC->SetDashList("\x1\x1", 2);
   }
   return *fgLineGC;
}
TGCanvas::TGCanvas(const TGWindow *p, UInt_t w, UInt_t h,
                   UInt_t options, ULong_t back) :
    TGFrame(p, w, h, options, back)
{
   
   fVport      = new TGViewPort(this, w-4, h-4, kChildFrame | kOwnBackground,
                                fgWhitePixel);
   fHScrollbar = new TGHScrollBar(this, w-4, kDefaultScrollBarWidth);
   fVScrollbar = new TGVScrollBar(this, kDefaultScrollBarWidth, h-4);
   fScrolling  = kCanvasScrollBoth;
   fHScrollbar->Associate(this);
   fVScrollbar->Associate(this);
   SetWindowName();
   fVScrollbar->SetEditDisabled(kEditDisable | kEditDisableGrab | kEditDisableBtnEnable);
   fHScrollbar->SetEditDisabled(kEditDisable | kEditDisableGrab | kEditDisableBtnEnable);
   
}
TGCanvas::~TGCanvas()
{
   
   delete fHScrollbar;
   delete fVScrollbar;
   delete fVport;
}
void TGCanvas::MapSubwindows()
{
   
   if (fHScrollbar) fHScrollbar->MapSubwindows();
   if (fVScrollbar) fVScrollbar->MapSubwindows();
   if (fVport) {
   TGFrame *container = fVport->GetContainer();
   if (!container) {
      Error("MapSubwindows", "no canvas container set yet");
      return;
   }
      container->MapSubwindows();
      fVport->MapSubwindows();
      fVport->MapWindow();
   }
   Layout();
}
void TGCanvas::AddFrame(TGFrame *f, TGLayoutHints *l)
{
   
   
   
   TGFrame *container = fVport->GetContainer();
   if (!container) {
      Error("AddFrame", "no canvas container set yet");
      return;
   }
   if (container->InheritsFrom(TGCompositeFrame::Class()))
      ((TGCompositeFrame*)container)->AddFrame(f, l);
   else
      Error("AddFrame", "canvas container must inherit from TGCompositeFrame");
}
void TGCanvas::DrawBorder()
{
   
   switch (fOptions & (kSunkenFrame | kRaisedFrame | kDoubleBorder)) {
      case kSunkenFrame | kDoubleBorder:
         gVirtualX->DrawLine(fId, GetShadowGC()(), 0, 0, fWidth-2, 0);
         gVirtualX->DrawLine(fId, GetShadowGC()(), 0, 0, 0, fHeight-2);
         gVirtualX->DrawLine(fId, GetBlackGC()(), 1, 1, fWidth-3, 1);
         gVirtualX->DrawLine(fId, GetBlackGC()(), 1, 1, 1, fHeight-3);
         gVirtualX->DrawLine(fId, GetHilightGC()(), 0, fHeight-1, fWidth-1, fHeight-1);
         gVirtualX->DrawLine(fId, GetHilightGC()(), fWidth-1, fHeight-1, fWidth-1, 0);
         gVirtualX->DrawLine(fId, GetBckgndGC()(),  1, fHeight-2, fWidth-2, fHeight-2);
         gVirtualX->DrawLine(fId, GetBckgndGC()(),  fWidth-2, 1, fWidth-2, fHeight-2);
         break;
      default:
         TGFrame::DrawBorder();
         break;
   }
}
void TGCanvas::Layout()
{
   
   
   Bool_t   need_vsb, need_hsb;
   UInt_t   cw, ch, tcw, tch;
   need_vsb = need_hsb = kFALSE;
   TGFrame *container = fVport->GetContainer();
   if (!container) {
      Error("Layout", "no canvas container set yet");
      return;
   }
   Bool_t fixedw = container->IsLayoutBroken() || (container->GetOptions() & kFixedWidth) ?
                   kTRUE : kFALSE;
   Bool_t fixedh = container->IsLayoutBroken() || (container->GetOptions() & kFixedHeight) ?
                   kTRUE : kFALSE;
   
   cw = fWidth  - UInt_t(fBorderWidth << 1);
   ch = fHeight - UInt_t(fBorderWidth << 1);
   if (!fixedw) container->SetWidth(cw);
   if (!fixedh) container->SetHeight(ch);
   if (container->GetDefaultWidth() > cw) {
      if ((fScrolling & kCanvasScrollHorizontal) && fHScrollbar) {
         need_hsb = kTRUE;
         ch -= fHScrollbar->GetDefaultHeight();
         if ((Int_t) ch < 0) {
            
            ch = 10;
         }
         if (!fixedh) container->SetHeight(ch);
      }
   }
   if (container->GetDefaultHeight() > ch) {
      if ((fScrolling & kCanvasScrollVertical) && fVScrollbar) {
         need_vsb = kTRUE;
         cw -= fVScrollbar->GetDefaultWidth();
         if ((Int_t) cw < 0) {
            
            cw = 10;
         }
         if (!fixedw) container->SetWidth(cw);
      }
   }
   
   if (container->GetDefaultWidth() > cw) {
      if (!need_hsb) {
         if ((fScrolling & kCanvasScrollHorizontal) && fHScrollbar) {
            need_hsb = kTRUE;
            ch -= fHScrollbar->GetDefaultHeight();
            if ((Int_t) ch < 0) {
               
               ch = 10;
            }
            if (!fixedh) container->SetHeight(ch);
         }
      }
   }
   fVport->MoveResize(fBorderWidth, fBorderWidth, cw, ch);
   tcw = TMath::Max(container->GetDefaultWidth(), cw);
   tch = TMath::Max(container->GetDefaultHeight(), ch);
   UInt_t curw = container->GetDefaultWidth();
   container->SetWidth(0); 
   if (fixedw && fixedh) {
      container->Resize(curw, container->GetDefaultHeight());
   } else if (fixedw) {
      container->Resize(curw, tch);
   } else if (fixedh) {
      container->Resize(tcw, container->GetDefaultHeight());
   } else {
      container->Resize(tcw, tch);
   }
   if (fHScrollbar) {
      if (need_hsb) {
         fHScrollbar->MoveResize(fBorderWidth, ch+fBorderWidth, cw, fHScrollbar->GetDefaultHeight());
         fHScrollbar->SetRange((Int_t)container->GetWidth(), (Int_t)fVport->GetWidth());
         fHScrollbar->MapWindow();
      } else {
         fHScrollbar->UnmapWindow();
         fHScrollbar->SetPosition(0);
         if (container->IsLayoutBroken()) {
            container->Resize(fVport->GetWidth(), container->GetHeight());
         }
      }
   }
   if (fVScrollbar) {
      if (need_vsb) {
         fVScrollbar->MoveResize(cw+fBorderWidth, fBorderWidth, fVScrollbar->GetDefaultWidth(), ch);
         fVScrollbar->SetRange((Int_t)container->GetHeight(), (Int_t)fVport->GetHeight());
         fVScrollbar->MapWindow();
      } else {
         fVScrollbar->UnmapWindow();
         fVScrollbar->SetPosition(0);
         if (container->IsLayoutBroken()) {
            container->Resize(container->GetWidth(), fVport->GetHeight());
         }
      }
   }
}
Bool_t TGCanvas::ProcessMessage(Long_t msg, Long_t parm1, Long_t)
{
   
   switch (GET_MSG(msg)) {
      case kC_HSCROLL:
         switch (GET_SUBMSG(msg)) {
            case kSB_SLIDERTRACK:
            case kSB_SLIDERPOS:
               fVport->SetHPos((Int_t)-parm1);
               break;
         }
         break;
      case kC_VSCROLL:
         switch (GET_SUBMSG(msg)) {
            case kSB_SLIDERTRACK:
            case kSB_SLIDERPOS:
               fVport->SetVPos((Int_t)-parm1);
               break;
         }
         break;
      default:
         break;
   }
   return kTRUE;
}
Int_t TGCanvas::GetHsbPosition() const
{
   
   if (fHScrollbar && fHScrollbar->IsMapped())
      return fHScrollbar->GetPosition();
   return 0;
}
Int_t TGCanvas::GetVsbPosition() const
{
   
   if (fVScrollbar && fVScrollbar->IsMapped())
      return fVScrollbar->GetPosition();
   return 0;
}
void TGCanvas::SetHsbPosition(Int_t newPos)
{
   
   if (fHScrollbar && fHScrollbar->IsMapped()) {
      TGFrame *container = fVport->GetContainer();
      fHScrollbar->SetRange((Int_t)container->GetWidth(), (Int_t)fVport->GetWidth());
      fHScrollbar->SetPosition(newPos);
   } else {
      fVport->SetHPos(0);
   }
}
void TGCanvas::SetVsbPosition(Int_t newPos)
{
   
   if (fVScrollbar && fVScrollbar->IsMapped()) {
      TGFrame *container = fVport->GetContainer();
      fVScrollbar->SetRange((Int_t)container->GetHeight(), (Int_t)fVport->GetHeight());
      fVScrollbar->SetPosition(newPos);
   } else {
      fVport->SetVPos(0);
   }
}
void TGCanvas::SetScrolling(Int_t scrolling)
{
   
   
   if (scrolling != fScrolling) {
      fScrolling = scrolling;
      Layout();
   }
}
void TGCanvas::SavePrimitive(ostream &out, Option_t *option )
{
   
   if (fBackground != GetDefaultFrameBackground()) SaveUserColor(out, option);
   out << endl << "   // canvas widget" << endl;
   out << "   TGCanvas *";
   out << GetName() << " = new TGCanvas("<< fParent->GetName()
       << "," << GetWidth() << "," << GetHeight();
   if (fBackground == GetDefaultFrameBackground()) {
      if (GetOptions() == (kSunkenFrame | kDoubleBorder)) {
         out << ");" << endl;
      } else {
         out << "," << GetOptionString() << ");" << endl;
      }
   } else {
      out << "," << GetOptionString() << ",ucolor);" << endl;
   }
   TGViewPort *vp = GetViewPort();
   out << endl << "   // canvas viewport" << endl;
   out << "   TGViewPort *" << vp->GetName() << " = " << GetName()
       << "->GetViewPort();" << endl;
   TGContainer *cont = (TGContainer*)GetContainer();
   cont->SavePrimitive(out, option);
   out << "   " << vp->GetName() << "->AddFrame(" << cont->GetName()
       << ");" << endl;
   out << "   " << cont->GetName() << "->SetLayoutManager(";
   cont->GetLayoutManager()->SavePrimitive(out, option);
   out << ");"<< endl;
   out << "   " << cont->GetName() << "->MapSubwindows();" << endl;
   out << "   " << GetName() << "->SetContainer(" << cont->GetName()
       << ");" << endl;
   out << "   " << GetName() << "->MapSubwindows();" << endl;
   if (fHScrollbar && fHScrollbar->IsMapped())
      out << "   " << GetName() << "->SetHsbPosition(" << GetHsbPosition()
          << ");" << endl;
   if (fVScrollbar && fVScrollbar->IsMapped())
      out << "   " << GetName() << "->SetVsbPosition(" << GetVsbPosition()
          << ");" << endl;
}
void TGContainer::SavePrimitive(ostream &out, Option_t *option )
{
   
   if (fBackground != GetDefaultFrameBackground()) SaveUserColor(out, option);
   out << endl << "   // canvas container" << endl;
   if ((fParent->GetParent())->InheritsFrom(TGCanvas::Class())) {
      out << GetName() << " = new TGContainer(" << GetCanvas()->GetName();
   } else {
      out << GetName() << " = new TGContainer(" << fParent->GetName();
      out << "," << GetWidth() << "," << GetHeight();
   }
   if (fBackground == GetDefaultFrameBackground()) {
      if (GetOptions() == (kSunkenFrame | kDoubleBorder)) {
         out <<");" << endl;
      } else {
         out << "," << GetOptionString() <<");" << endl;
      }
   } else {
      out << "," << GetOptionString() << ",ucolor);" << endl;
   }
}
This page has been automatically generated. If you have any comments or suggestions about the page layout send a mail to ROOT support, or contact the developers with any questions or problems regarding ROOT.