27 ClassImp(TGSplitTool);
 
   28 ClassImp(TGSplitFrame);
 
   34 TGSplitTool::TGSplitTool(
const TGWindow *p, 
const TGFrame *f)
 
   35    : TGCompositeFrame(p, 10, 10, kHorizontalFrame | kRaisedFrame | kFixedSize)
 
   37    SetWindowAttributes_t attr;
 
   38    attr.fMask             = kWAOverrideRedirect | kWASaveUnder;
 
   39    attr.fOverrideRedirect = kTRUE;
 
   40    attr.fSaveUnder        = kTRUE;
 
   42    gVirtualX->ChangeWindowAttributes(fId, &attr);
 
   43    SetBackgroundColor(fClient->GetResourcePool()->GetTipBgndColor());
 
   45    fRectGC.SetFillStyle(kFillSolid);
 
   46    fRectGC.SetForeground(0x99ff99);
 
   48    TClass *cl = TClass::GetClass(
"TGSplitFrame");
 
   49    cl->MakeCustomMenuList();
 
   50    TList *ml = cl->GetMenuList();
 
   51    ((TClassMenuItem *)ml->At(1))->SetTitle(
"Cleanup Frame");
 
   52    ((TClassMenuItem *)ml->At(2))->SetTitle(
"Close and Collapse");
 
   53    ((TClassMenuItem *)ml->At(3))->SetTitle(
"Undock Frame");
 
   54    ((TClassMenuItem *)ml->At(4))->SetTitle(
"Dock Frame Back");
 
   55    ((TClassMenuItem *)ml->At(5))->SetTitle(
"Switch to Main");
 
   56    ((TClassMenuItem *)ml->At(6))->SetTitle(
"Horizontally Split...");
 
   57    ((TClassMenuItem *)ml->At(7))->SetTitle(
"Vertically Split...");
 
   58    fContextMenu = 
new TContextMenu(
"SplitFrameContextMenu", 
"Actions");
 
   60    fMap.SetOwnerValue(kFALSE);
 
   62    if (f) Resize(f->GetWidth()/10, f->GetHeight()/10);
 
   63    AddInput(kButtonPressMask | kButtonReleaseMask | kPointerMotionMask);
 
   72 TGSplitTool::~TGSplitTool()
 
   81 void TGSplitTool::AddRectangle(TGFrame *frame, Int_t x, Int_t y, Int_t w, Int_t h)
 
   83    TGRectMap *rect = 
new TGRectMap(x, y, w, h);
 
   84    fMap.Add(rect, frame);
 
   90 void TGSplitTool::DoRedraw()
 
   94    while ((rect = (TGRectMap*)next())) {
 
   95       gVirtualX->FillRectangle(fId, GetBckgndGC()(), rect->fX,
 
   96                                rect->fY, rect->fW, rect->fH);
 
   97       gVirtualX->DrawRectangle(fId, GetBlackGC()(), rect->fX, rect->fY,
 
  106 void TGSplitTool::DrawBorder()
 
  108    gVirtualX->DrawLine(fId, GetShadowGC()(), 0, 0, fWidth-2, 0);
 
  109    gVirtualX->DrawLine(fId, GetShadowGC()(), 0, 0, 0, fHeight-2);
 
  110    gVirtualX->DrawLine(fId, GetBlackGC()(),  0, fHeight-1, fWidth-1, fHeight-1);
 
  111    gVirtualX->DrawLine(fId, GetBlackGC()(),  fWidth-1, fHeight-1, fWidth-1, 0);
 
  117 Bool_t TGSplitTool::HandleButton(Event_t *event)
 
  119    if (event->fType != kButtonPress)
 
  121    Int_t px = 0, py = 0;
 
  124    TGSplitFrame *frm = 0;
 
  125    TMapIter next(&fMap);
 
  126    while ((rect = (TGRectMap*)next())) {
 
  127       if (rect->Contains(event->fX, event->fY)) {
 
  128          frm = (TGSplitFrame *)fMap.GetValue((
const TObject *)rect);
 
  129          gVirtualX->TranslateCoordinates(event->fWindow,
 
  130                                          gClient->GetDefaultRoot()->GetId(),
 
  131                                          event->fX, 
event->fY, px, py, wtarget);
 
  132          fContextMenu->Popup(px, py, frm);
 
  135          TRootContextMenu *menu = ((TRootContextMenu *)fContextMenu->GetContextMenuImp());
 
  136          ((TGPopupMenu *)menu)->Connect(
"PoppedDown()", 
"TGSplitTool", 
this, 
"Hide()");
 
  147 Bool_t TGSplitTool::HandleMotion(Event_t *event)
 
  149    static TGRectMap *rect = 0, *oldrect = 0;
 
  150    TMapIter next(&fMap);
 
  151    while ((rect = (TGRectMap*)next())) {
 
  152       if (rect->Contains(event->fX, event->fY)) {
 
  154          if (rect != oldrect) {
 
  156                gVirtualX->FillRectangle(fId, GetBckgndGC()(), oldrect->fX,
 
  157                                         oldrect->fY, oldrect->fW, oldrect->fH);
 
  158                gVirtualX->DrawRectangle(fId, GetBlackGC()(), oldrect->fX, oldrect->fY,
 
  159                                         oldrect->fW, oldrect->fH);
 
  161             gVirtualX->FillRectangle(fId, fRectGC(), rect->fX, rect->fY, rect->fW,
 
  163             gVirtualX->DrawRectangle(fId, GetBlackGC()(), rect->fX, rect->fY,
 
  171       gVirtualX->FillRectangle(fId, GetBckgndGC()(), oldrect->fX,
 
  172                                oldrect->fY, oldrect->fW, oldrect->fH);
 
  173       gVirtualX->DrawRectangle(fId, GetBlackGC()(), oldrect->fX, oldrect->fY,
 
  174                                oldrect->fW, oldrect->fH);
 
  181 void TGSplitTool::Hide()
 
  183    gVirtualX->GrabPointer(0, 0, 0, 0, kFALSE);  
 
  192 void TGSplitTool::Reset()
 
  202 void TGSplitTool::SetPosition(Int_t x, Int_t y)
 
  213       if (fX > (Int_t) fWindow->GetWidth())
 
  214          fX = fWindow->GetWidth();
 
  215       if (fY > (Int_t) fWindow->GetHeight())
 
  216          fY = fWindow->GetHeight();
 
  223 void TGSplitTool::Show(Int_t x, Int_t y)
 
  230    gVirtualX->GrabPointer(fId, kButtonPressMask | kPointerMotionMask, kNone,
 
  231                           fClient->GetResourcePool()->GetGrabCursor(),
 
  241 TGSplitFrame::TGSplitFrame(
const TGWindow *p, UInt_t w, UInt_t h,
 
  242         UInt_t options) : TGCompositeFrame(p, w, h, options),
 
  243         fFrame(0), fSplitter(0), fFirst(0), fSecond(0)
 
  245    fSplitTool = 
new TGSplitTool(gClient->GetDefaultRoot(), 
this);
 
  246    fHRatio = fWRatio = 0.0;
 
  248    AddInput(kStructureNotifyMask);
 
  249    SetCleanup(kLocalCleanup);
 
  255 TGSplitFrame::~TGSplitFrame()
 
  264 void TGSplitFrame::AddFrame(TGFrame *f, TGLayoutHints *l)
 
  266    TGCompositeFrame::AddFrame(f, l);
 
  273 void TGSplitFrame::RemoveFrame(TGFrame *f)
 
  275    TGCompositeFrame::RemoveFrame(f);
 
  283 void TGSplitFrame::Cleanup()
 
  285    TGCompositeFrame::Cleanup();
 
  295 TGSplitFrame *TGSplitFrame::GetTopFrame()
 
  297    TGSplitFrame *top = 
this;
 
  298    TGWindow *w = (TGWindow *)GetParent();
 
  299    TGSplitFrame *p = 
dynamic_cast<TGSplitFrame *
>(w);
 
  302       w = (TGWindow *)p->GetParent();
 
  303       p = 
dynamic_cast<TGSplitFrame *
>(w);
 
  312 void TGSplitFrame::Close()
 
  315       fFrame->UnmapWindow();
 
  325 void TGSplitFrame::CloseAndCollapse()
 
  327    if (!fSplitter || !fFirst || !fSecond) {
 
  328       TGSplitFrame *parent = (TGSplitFrame *)GetParent();
 
  329       if (parent->GetFirst() && parent->GetSecond()) {
 
  330          if (parent->GetFirst()  == 
this)
 
  331             parent->UnSplit(
"first");
 
  332          else if (parent->GetSecond() == 
this)
 
  333             parent->UnSplit(
"second");
 
  340 void TGSplitFrame::Docked(TGFrame* frame)
 
  342    Emit(
"Docked(TGFrame*)", (Long_t)frame);
 
  350 void TGSplitFrame::ExtractFrame()
 
  353       fFrame->UnmapWindow();
 
  354       fUndocked = 
new TGTransientFrame(gClient->GetDefaultRoot(), GetMainFrame(), 800, 600);
 
  355       fFrame->ReparentWindow(fUndocked);
 
  356       fUndocked->AddFrame(fFrame, 
new TGLayoutHints(kLHintsExpandX | kLHintsExpandY));
 
  358       fUndocked->MapSubwindows();
 
  360       fUndocked->MapWindow();
 
  362       fUndocked->Connect(
"CloseWindow()", 
"TGSplitFrame", 
this, 
"SwallowBack()");
 
  372 Bool_t TGSplitFrame::HandleConfigureNotify(Event_t *)
 
  376       TGWindow *w = (TGWindow *)GetParent();
 
  377       TGSplitFrame *p = 
dynamic_cast<TGSplitFrame *
>(w);
 
  381             Float_t hratio = (Float_t)p->GetFirst()->GetHeight() / (Float_t)p->GetHeight();
 
  382             Float_t wratio = (Float_t)p->GetFirst()->GetWidth() / (Float_t)p->GetWidth();
 
  383             p->SetHRatio(hratio);
 
  384             p->SetWRatio(wratio);
 
  390    if ((fHRatio > 0.0) && (fWRatio > 0.0)) {
 
  391       Float_t h = fHRatio * (Float_t)GetHeight();
 
  392       fFirst->SetHeight((UInt_t)h);
 
  393       Float_t w = fWRatio * (Float_t)GetWidth();
 
  394       fFirst->SetWidth((UInt_t)w);
 
  397    fHRatio = (Float_t)fFirst->GetHeight() / (Float_t)GetHeight();
 
  398    fWRatio = (Float_t)fFirst->GetWidth() / (Float_t)GetWidth();
 
  399    fClient->NeedRedraw(
this);
 
  400    if (!gVirtualX->InheritsFrom(
"TGX11"))
 
  408 void TGSplitFrame::HSplit(UInt_t h)
 
  411    if ((fSplitter != 0) || (fFirst != 0) || (fSecond != 0) || (fFrame != 0))
 
  413    UInt_t height = (h > 0) ? h : fHeight/2;
 
  415    ChangeOptions((GetOptions() & ~kHorizontalFrame) | kVerticalFrame);
 
  417    fFirst = 
new TGSplitFrame(
this, fWidth, height, kSunkenFrame | kFixedHeight);
 
  419    fSecond = 
new TGSplitFrame(
this, fWidth, height, kSunkenFrame);
 
  421    fSplitter = 
new TGHSplitter(
this, 4, 4);
 
  423    fSplitter->SetFrame(fFirst, kTRUE);
 
  424    fSplitter->Connect(
"ProcessedEvent(Event_t*)", 
"TGSplitFrame", 
this,
 
  425                       "OnSplitterClicked(Event_t*)");
 
  427    TGCompositeFrame::AddFrame(fFirst, 
new TGLayoutHints(kLHintsExpandX));
 
  428    TGCompositeFrame::AddFrame(fSplitter, 
new TGLayoutHints(kLHintsLeft |
 
  429                               kLHintsTop | kLHintsExpandX));
 
  430    TGCompositeFrame::AddFrame(fSecond, 
new TGLayoutHints(kLHintsExpandX |
 
  437 void TGSplitFrame::VSplit(UInt_t w)
 
  440    if ((fSplitter != 0) || (fFirst != 0) || (fSecond != 0) || (fFrame != 0))
 
  442    UInt_t width = (w > 0) ? w : fWidth/2;
 
  444    ChangeOptions((GetOptions() & ~kVerticalFrame) | kHorizontalFrame);
 
  446    fFirst = 
new TGSplitFrame(
this, width, fHeight, kSunkenFrame | kFixedWidth);
 
  448    fSecond = 
new TGSplitFrame(
this, width, fHeight, kSunkenFrame);
 
  450    fSplitter = 
new TGVSplitter(
this, 4, 4);
 
  452    fSplitter->SetFrame(fFirst, kTRUE);
 
  453    fSplitter->Connect(
"ProcessedEvent(Event_t*)", 
"TGSplitFrame", 
this,
 
  454                       "OnSplitterClicked(Event_t*)");
 
  456    TGCompositeFrame::AddFrame(fFirst, 
new TGLayoutHints(kLHintsExpandY));
 
  457    TGCompositeFrame::AddFrame(fSplitter, 
new TGLayoutHints(kLHintsLeft |
 
  458                               kLHintsTop | kLHintsExpandY));
 
  459    TGCompositeFrame::AddFrame(fSecond, 
new TGLayoutHints(kLHintsExpandX |
 
  466 void TGSplitFrame::MapToSPlitTool(TGSplitFrame *top)
 
  468    Int_t px = 0, py = 0;
 
  469    Int_t rx = 0, ry = 0;
 
  470    Int_t cx, cy, cw, ch;
 
  472    if (!fFirst && !fSecond) {
 
  473       TGSplitFrame *parent = 
dynamic_cast<TGSplitFrame *
>((TGFrame *)fParent);
 
  474       if (parent && parent->fSecond == 
this) {
 
  475          if (parent->GetOptions() & kVerticalFrame)
 
  476             ry = parent->GetFirst()->GetHeight();
 
  477          if (parent->GetOptions() & kHorizontalFrame)
 
  478             rx = parent->GetFirst()->GetWidth();
 
  480       gVirtualX->TranslateCoordinates(GetId(), top->GetId(),
 
  481                                       fX, fY, px, py, wtarget);
 
  486       top->GetSplitTool()->AddRectangle(
this, cx, cy, cw, ch);
 
  490       fFirst->MapToSPlitTool(top);
 
  492       fSecond->MapToSPlitTool(top);
 
  498 void TGSplitFrame::OnSplitterClicked(Event_t *event)
 
  500    Int_t    px = 0, py = 0;
 
  502    if (event->fType != kButtonPress)
 
  504    if (event->fCode != kButton3)
 
  506    gVirtualX->TranslateCoordinates(event->fWindow,
 
  507                                    gClient->GetDefaultRoot()->GetId(),
 
  508                                    event->fX, 
event->fY, px, py, wtarget);
 
  509    TGSplitFrame *top = GetTopFrame();
 
  510    top->GetSplitTool()->Reset();
 
  511    top->GetSplitTool()->Resize(1+top->GetWidth()/10, 1+top->GetHeight()/10);
 
  512    top->MapToSPlitTool(top);
 
  513    top->GetSplitTool()->Show(px, py);
 
  521 void TGSplitFrame::SplitHor()
 
  524    snprintf(side, 200, 
"top");
 
  526       new TGInputDialog(gClient->GetRoot(), GetTopFrame(),
 
  527                "In which side the actual frame has to be kept (top / bottom)",
 
  529       if ( strcmp(side, 
"") == 0 )  
 
  532    SplitHorizontal(side);
 
  540 void TGSplitFrame::SplitHorizontal(
const char *side)
 
  543       TGFrame *frame = fFrame;
 
  544       frame->UnmapWindow();
 
  545       frame->ReparentWindow(gClient->GetDefaultRoot());
 
  548       if (!strcmp(side, 
"top")) {
 
  549          frame->ReparentWindow(GetFirst());
 
  550          GetFirst()->AddFrame(frame, 
new TGLayoutHints(kLHintsExpandX | kLHintsExpandY));
 
  552       else if (!strcmp(side, 
"bottom")) {
 
  553          frame->ReparentWindow(GetSecond());
 
  554          GetSecond()->AddFrame(frame, 
new TGLayoutHints(kLHintsExpandX | kLHintsExpandY));
 
  569 void TGSplitFrame::SplitVer()
 
  572    snprintf(side, 200, 
"left");
 
  574       new TGInputDialog(gClient->GetRoot(), GetTopFrame(),
 
  575                "In which side the actual frame has to be kept (left / right)",
 
  577       if ( strcmp(side, 
"") == 0 )  
 
  588 void TGSplitFrame::SplitVertical(
const char *side)
 
  591       TGFrame *frame = fFrame;
 
  592       frame->UnmapWindow();
 
  593       frame->ReparentWindow(gClient->GetDefaultRoot());
 
  596       if (!strcmp(side, 
"left")) {
 
  597          frame->ReparentWindow(GetFirst());
 
  598          GetFirst()->AddFrame(frame, 
new TGLayoutHints(kLHintsExpandX | kLHintsExpandY));
 
  600       else if (!strcmp(side, 
"right")) {
 
  601          frame->ReparentWindow(GetSecond());
 
  602          GetSecond()->AddFrame(frame, 
new TGLayoutHints(kLHintsExpandX | kLHintsExpandY));
 
  616 void TGSplitFrame::SwallowBack()
 
  619       fUndocked = 
dynamic_cast<TGTransientFrame *
>((TQObject*)gTQSender);
 
  622       TGFrameElement *el = 
dynamic_cast<TGFrameElement*
>(fUndocked->GetList()->First());
 
  623       if (!el || !el->fFrame) 
return;
 
  624       TGSplitFrame *frame = (TGSplitFrame *)el->fFrame;
 
  625       frame->UnmapWindow();
 
  626       fUndocked->RemoveFrame(frame);
 
  627       frame->ReparentWindow(
this);
 
  628       AddFrame(frame, 
new TGLayoutHints(kLHintsExpandX | kLHintsExpandY));
 
  632       fUndocked->CloseWindow();
 
  644 void TGSplitFrame::SwitchFrames(TGFrame *frame, TGCompositeFrame *dest,
 
  648    TGCompositeFrame *parent = (TGCompositeFrame *)frame->GetParent();
 
  653    dest->RemoveFrame(prev);
 
  655    prev->ReparentWindow(gClient->GetDefaultRoot());
 
  658    frame->UnmapWindow();
 
  660    parent->RemoveFrame(frame);
 
  662    frame->ReparentWindow(dest);
 
  664    dest->AddFrame(frame, 
new TGLayoutHints(kLHintsExpandX | kLHintsExpandY));
 
  666    frame->Resize(dest->GetDefaultSize());
 
  667    dest->MapSubwindows();
 
  672    prev->ReparentWindow(parent);
 
  674    parent->AddFrame(prev, 
new TGLayoutHints(kLHintsExpandX | kLHintsExpandY));
 
  676    prev->Resize(parent->GetDefaultSize());
 
  677    parent->MapSubwindows();
 
  684 void TGSplitFrame::SwitchToMain()
 
  686    TGFrame *source = fFrame;
 
  687    TGSplitFrame *dest = GetTopFrame()->GetFirst();
 
  688    TGFrame *prev = (TGFrame *)(dest->GetFrame());
 
  689    if ((source != prev) && (source != dest))
 
  690       SwitchFrames(source, dest, prev);
 
  696 void TGSplitFrame::Undocked(TGFrame* frame)
 
  698    Emit(
"Undocked(TGFrame*)", (Long_t)frame);
 
  705 void TGSplitFrame::UnSplit(
const char *which)
 
  707    TGCompositeFrame *keepframe = 0;
 
  708    TGSplitFrame *kframe = 0, *dframe = 0;
 
  709    if (!strcmp(which, 
"first")) {
 
  711       kframe = GetSecond();
 
  713    else if (!strcmp(which, 
"second")) {
 
  714       dframe = GetSecond();
 
  717    if (!kframe || !dframe)
 
  719    keepframe = (TGCompositeFrame *)kframe->GetFrame();
 
  721       keepframe->UnmapWindow();
 
  722       keepframe->ReparentWindow(gClient->GetDefaultRoot());
 
  723       kframe->RemoveFrame(keepframe);
 
  727       keepframe->ReparentWindow(
this);
 
  728       AddFrame(keepframe, 
new TGLayoutHints(kLHintsExpandX | kLHintsExpandY));
 
  737 void TGSplitFrame::SavePrimitive(std::ostream &out, Option_t *option )
 
  739    if (fBackground != GetDefaultFrameBackground()) SaveUserColor(out, option);
 
  741    out << std::endl << 
"   // splittable frame" << std::endl;
 
  742    out << 
"   TGSplitFrame *";
 
  743    out << GetName() << 
" = new TGSplitFrame(" << fParent->GetName()
 
  744        << 
"," << GetWidth() << 
"," << GetHeight();
 
  746    if (fBackground == GetDefaultFrameBackground()) {
 
  748          out << 
");" << std::endl;
 
  750          out << 
"," << GetOptionString() <<
");" << std::endl;
 
  753       out << 
"," << GetOptionString() << 
",ucolor);" << std::endl;
 
  755    if (option && strstr(option, 
"keep_names"))
 
  756       out << 
"   " << GetName() << 
"->SetName(\"" << GetName() << 
"\");" << std::endl;
 
  761    TGLayoutManager * lm = GetLayoutManager();
 
  762    if ((GetOptions() & kHorizontalFrame) &&
 
  763        (lm->InheritsFrom(TGHorizontalLayout::Class()))) {
 
  765    } 
else if ((GetOptions() & kVerticalFrame) &&
 
  766               (lm->InheritsFrom(TGVerticalLayout::Class()))) {
 
  769       out << 
"   " << GetName() <<
"->SetLayoutManager(";
 
  770       lm->SavePrimitive(out, option);
 
  771       out << 
");"<< std::endl;
 
  774    SavePrimitiveSubframes(out, option);