TGDockableFrame.cxx

Go to the documentation of this file.
00001 // @(#)root/gui:$Id: TGDockableFrame.cxx 35582 2010-09-22 13:38:27Z bellenot $
00002 // Author: Abdelhalim Ssadik   07/07/04
00003 
00004 /*************************************************************************
00005  * Copyright (C) 1995-2004, 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 // A TGDockableFrame is a frame with handles that allow it to be        //
00026 // undocked (i.e. put in a transient frame of its own) and to be docked //
00027 // again or hidden and shown again. It uses the TGDockButton, which is  //
00028 // a button with two vertical bars (||) and TGDockHideButton, which is  //
00029 // a button with a small triangle. The TGUndockedFrame is a transient   //
00030 // frame that on closure will put the frame back in the dock.           //
00031 //                                                                      //
00032 //////////////////////////////////////////////////////////////////////////
00033 
00034 #include "TColor.h"
00035 #include "TGFrame.h"
00036 #include "TMessage.h"
00037 #include "TGWidget.h"
00038 #include "TGButton.h"
00039 #include "TGDockableFrame.h"
00040 #include "TGWindow.h"
00041 #include "TList.h"
00042 #include "TVirtualX.h"
00043 #include "Riostream.h"
00044 
00045 
00046 ClassImp(TGDockButton)
00047 ClassImp(TGDockHideButton)
00048 ClassImp(TGUndockedFrame)
00049 ClassImp(TGDockableFrame)
00050 
00051 //______________________________________________________________________________
00052 TGDockButton::TGDockButton(const TGCompositeFrame *p, int id) :
00053    TGButton (p, id, GetDefaultGC()(), kChildFrame)
00054 {
00055    // Create a dock button (i.e. button with two vertical bars).
00056 
00057    fWidgetFlags = kWidgetIsEnabled;
00058    fMouseOn = kFALSE;
00059    Resize(10, GetDefaultHeight());
00060 
00061    fNormBg = fBackground;
00062 
00063    Float_t r, g, b, h, l, s;
00064    TColor::Pixel2RGB(fNormBg, r, g, b);
00065    TColor::RGB2HLS(r, g, b, h, l, s);
00066    l = l + (1. - l) * 45. / 100.;
00067    TColor::HLS2RGB(h, l, s, r, g, b);
00068    fHiBg = TColor::RGB2Pixel(r, g, b);
00069 
00070    AddInput(kEnterWindowMask | kLeaveWindowMask);
00071    SetWindowName();
00072 }
00073 
00074 //______________________________________________________________________________
00075 TGDockButton::~TGDockButton()
00076 {
00077    // Delete dock button.
00078 }
00079 
00080 //______________________________________________________________________________
00081 Bool_t TGDockButton::HandleCrossing(Event_t *event)
00082 {
00083    // Handle dock button crossing events.
00084 
00085    TGButton::HandleCrossing(event);
00086    if (event->fType == kLeaveNotify) {
00087       fMouseOn = kFALSE;
00088    } else if (event->fType == kEnterNotify) {
00089       fMouseOn = kTRUE;
00090    }
00091    if (IsEnabled())
00092       fClient->NeedRedraw(this);
00093 
00094    return kTRUE;
00095 }
00096 
00097 //______________________________________________________________________________
00098 void TGDockButton::DrawBorder()
00099 {
00100    // Draw borders of dock button.
00101 
00102    int options = GetOptions();
00103 
00104    if (fState == kButtonDown || fState == kButtonEngaged)
00105       ;
00106    else if (fMouseOn == kTRUE && IsEnabled()) {
00107       SetBackgroundColor(fHiBg);
00108       ChangeOptions(kChildFrame);
00109    } else {
00110       SetBackgroundColor(fNormBg);
00111       ChangeOptions(kChildFrame);
00112    }
00113    gVirtualX->ClearWindow(fId);
00114    TGFrame::DrawBorder();
00115 
00116    ChangeOptions(options);
00117 }
00118 
00119 //______________________________________________________________________________
00120 void TGDockButton::DoRedraw()
00121 {
00122    // Draw the dock button, i.e. two vertical lines.
00123 
00124    int x = 1, y = 0;
00125 
00126    DrawBorder();
00127    if (fState == kButtonDown || fState == kButtonEngaged) { ++x; ++y; }
00128 
00129    for (int i = 0; i < 5; i +=4) {
00130       gVirtualX->DrawLine(fId, GetHilightGC()(), i+x,   y+1, i+x,   fHeight-y-3);
00131       gVirtualX->DrawLine(fId, GetShadowGC()(),  i+x+1, y+1, i+x+1, fHeight-y-3);
00132    }
00133 }
00134 
00135 
00136 //______________________________________________________________________________
00137 TGDockHideButton::TGDockHideButton(const TGCompositeFrame *p) :
00138    TGDockButton (p, 2)
00139 {
00140    // Create a dock hide button (i.e. button with small triangle).
00141 
00142    Resize(10, 8);
00143    fAspectRatio = 0;
00144    SetWindowName();
00145 }
00146 
00147 //______________________________________________________________________________
00148 void TGDockHideButton::DoRedraw()
00149 {
00150    // Draw dock hide button.
00151 
00152    int x = 1, y = 0;
00153 
00154    DrawBorder();
00155    if (fState == kButtonDown || fState == kButtonEngaged) { ++x; ++y; }
00156 
00157    if (fAspectRatio) {
00158       gVirtualX->DrawLine(fId, GetBlackGC()(), x+1, y+1, x+5, y+3);
00159       gVirtualX->DrawLine(fId, GetBlackGC()(), x+1, y+5, x+5, y+3);
00160       gVirtualX->DrawLine(fId, GetHilightGC()(), x, y+1, x, y+5);
00161    } else {
00162       gVirtualX->DrawLine(fId, GetHilightGC()(), x+5, y+1, x+1, y+3);
00163       gVirtualX->DrawLine(fId, GetHilightGC()(), x+5, y+5, x+1, y+3);
00164       gVirtualX->DrawLine(fId, GetBlackGC()(), x+6, y+1, x+6, y+5);
00165    }
00166 }
00167 
00168 
00169 //______________________________________________________________________________
00170 TGUndockedFrame::TGUndockedFrame(const TGWindow *p, TGDockableFrame *dockable) :
00171    TGTransientFrame(p, dockable ? dockable->GetMainFrame() : 0, 10, 10)
00172 {
00173    // Create the undocked (transient) frame.
00174 
00175    SetWindowName("");
00176    fDockable = dockable;
00177 
00178    SetMWMHints(kMWMDecorAll | kMWMDecorResizeH  | kMWMDecorMaximize |
00179                               kMWMDecorMinimize | kMWMDecorMenu,
00180                kMWMFuncAll  | kMWMFuncResize    | kMWMFuncMaximize |
00181                               kMWMFuncMinimize,
00182                kMWMInputModeless);
00183    SetWindowName();
00184 }
00185 
00186 //______________________________________________________________________________
00187 TGUndockedFrame::~TGUndockedFrame()
00188 {
00189    // Delete undocked frame. Puts back dockable frame in its original container.
00190 
00191    if (fDockable && !fDockable->fDeleted) {
00192       fDockable->DockContainer(kFALSE);
00193    }
00194 }
00195 
00196 //______________________________________________________________________________
00197 void TGUndockedFrame::FixSize()
00198 {
00199    // Fix the size of the undocked frame so it cannot be changed via the WM.
00200 
00201    ChangeOptions(GetOptions() | kFixedSize);
00202    SetWMSize(fWidth, fHeight);
00203    SetWMSizeHints(fWidth, fHeight, fWidth, fHeight, 0, 0);
00204 }
00205 
00206 //______________________________________________________________________________
00207 void TGUndockedFrame::CloseWindow()
00208 {
00209    // Close undocked frame (called via WM close button).
00210 
00211    DeleteWindow();
00212 }
00213 
00214 
00215 //______________________________________________________________________________
00216 TGDockableFrame::TGDockableFrame(const TGWindow *p, int id, UInt_t /*options*/)
00217    : TGCompositeFrame(p, 10, 10, kHorizontalFrame), TGWidget(id)
00218 {
00219    // Create a dockable frame widget.
00220 
00221    fMsgWindow = fParent;
00222 
00223    fCl = new TGLayoutHints(kLHintsExpandY | kLHintsExpandX);
00224 
00225    TGLayoutHints *l1 = new TGLayoutHints(kLHintsTop | kLHintsLeft);
00226    TGLayoutHints *l2 = new TGLayoutHints(kLHintsExpandY | kLHintsLeft);
00227    fLb = new TGLayoutHints(kLHintsExpandY | kLHintsLeft, 0, 2, 0, 0);
00228    fLc = new TGLayoutHints(kLHintsExpandY | kLHintsExpandX);
00229 
00230    fButtons = new TGCompositeFrame(this, 10, 10, kVerticalFrame);
00231    fButtons->SetCleanup();
00232    fHideButton = new TGDockHideButton(fButtons);
00233    fButtons->AddFrame(fHideButton, l1);
00234    fDockButton = new TGDockButton(fButtons);
00235    fButtons->AddFrame(fDockButton, l2);
00236 
00237    TGCompositeFrame::AddFrame(fButtons, fLb);
00238 
00239    fContainer = new TGCompositeFrame(this, 10, 10);
00240    
00241    TGCompositeFrame::AddFrame(fContainer, fLc);
00242 
00243    fEnableHide   = kTRUE;
00244    fEnableUndock = kTRUE;
00245    fHidden       = kFALSE;
00246    fFrame        = 0;
00247    fDeleted      = kFALSE;
00248    fFixedSize    = kTRUE;
00249 
00250    fDockButton->Associate(this);
00251    fHideButton->Associate(this);
00252 
00253    MapSubwindows();
00254    Resize(GetDefaultSize());
00255    TGFrame::SetWindowName();
00256 }
00257 
00258 //______________________________________________________________________________
00259 TGDockableFrame::~TGDockableFrame()
00260 {
00261    // Cleanup dockable frame.
00262 
00263    // Just set the flag and delete fFrame. The other components
00264    // are deleted in TGCompositeFrame destructor.
00265    if (fFrame) {
00266       fDeleted = kTRUE;
00267       delete fFrame;
00268    }
00269 }
00270 
00271 //______________________________________________________________________________
00272 void TGDockableFrame::AddFrame(TGFrame *f, TGLayoutHints *hints)
00273 {
00274    // Add frame to dockable frame container. Frame and hints are NOT adopted.
00275 
00276    f->ReparentWindow(fContainer);
00277    fContainer->AddFrame(f, fHints = hints);
00278    fContainer->Layout();
00279 }
00280 
00281 //______________________________________________________________________________
00282 void TGDockableFrame::UndockContainer()
00283 {
00284    // Undock container.
00285 
00286    int ax, ay;
00287    Window_t wdummy;
00288 
00289    if (fFrame || !fEnableUndock) return;
00290 
00291    fFrame = new TGUndockedFrame(fClient->GetDefaultRoot(), this);
00292    fFrame->SetEditDisabled();
00293 
00294    TGDimension size = fContainer->GetSize();
00295    RemoveFrame(fContainer);
00296    fContainer->ReparentWindow(fFrame);
00297    fFrame->AddFrame(fContainer, fCl);  // fHints
00298 
00299    gVirtualX->TranslateCoordinates(GetId(), fClient->GetDefaultRoot()->GetId(), fX,
00300                                    fY + fFrame->GetHeight(), ax, ay, wdummy);
00301 
00302    if (fDockName) fFrame->SetWindowName(fDockName);
00303 
00304    fFrame->MapSubwindows();
00305    fFrame->Resize(size);
00306    if (fFixedSize)
00307       fFrame->FixSize();
00308    fFrame->MapWindow();
00309    fFrame->Move(ax, ay);
00310 
00311    if (((TGFrame *)fParent)->IsComposite())           // paranoia check
00312       ((TGCompositeFrame *)fParent)->HideFrame(this);
00313 
00314    Layout();
00315 
00316    SendMessage(fMsgWindow, MK_MSG(kC_DOCK, kDOCK_UNDOCK), fWidgetId, 0);
00317    Undocked();
00318 }
00319 
00320 //______________________________________________________________________________
00321 void TGDockableFrame::DockContainer(Int_t del)
00322 {
00323    // Dock container back to TGDockableFrame.
00324 
00325    if (!fFrame) return;
00326    if (del) {
00327       delete fFrame;  // this will call DockContainer again with del = kFALSE
00328       return;
00329    }
00330 
00331    fFrame->RemoveFrame(fContainer);
00332    fContainer->ReparentWindow(this);
00333    TGCompositeFrame::AddFrame(fContainer, fCl);  // fHints
00334 
00335    // kludge! (for special case)
00336    fDockButton->Resize(fDockButton->GetDefaultWidth(), 1);
00337 
00338    Layout();
00339    if (((TGFrame *)fParent)->IsComposite())           // paranoia check
00340       ((TGCompositeFrame *)fParent)->ShowFrame(this);
00341 
00342    // fFrame is just being deleted (we're here called by TGUndockedFrame's
00343    // destructor) so just set it NULL below to avoid eventual problems in
00344    // TGDockableFrame's destructor.
00345 
00346    fFrame = 0;
00347 
00348    SendMessage(fMsgWindow, MK_MSG(kC_DOCK, kDOCK_DOCK), fWidgetId, 0);
00349    Docked();
00350 }
00351 
00352 //______________________________________________________________________________
00353 void TGDockableFrame::ShowContainer()
00354 {
00355    // Show dock container.
00356 
00357    if (!fHidden) return;
00358 
00359    ShowFrame(fContainer);
00360    if (fEnableUndock) fButtons->ShowFrame(fDockButton);
00361    fHideButton->SetAspectRatio(0);
00362    if (((TGFrame *)fParent)->IsComposite())           // paranoia check
00363       ((TGCompositeFrame *)fParent)->Layout();
00364    fHidden = kFALSE;
00365 
00366    SendMessage(fMsgWindow, MK_MSG(kC_DOCK, kDOCK_SHOW), fWidgetId, 0);
00367 }
00368 
00369 //______________________________________________________________________________
00370 void TGDockableFrame::HideContainer()
00371 {
00372    // Hide dock container.
00373 
00374    if (fHidden || !fEnableHide) return;
00375 
00376    HideFrame(fContainer);
00377    fButtons->HideFrame(fDockButton);
00378    fHideButton->SetAspectRatio(1);
00379    if (((TGFrame *)fParent)->IsComposite())           // paranoia check
00380       ((TGCompositeFrame *)fParent)->Layout();
00381    fHidden = kTRUE;
00382 
00383    SendMessage(fMsgWindow, MK_MSG(kC_DOCK, kDOCK_HIDE),fWidgetId, 0);
00384 }
00385 
00386 //______________________________________________________________________________
00387 Bool_t TGDockableFrame::ProcessMessage(Long_t msg, Long_t parm1, Long_t)
00388 {
00389    // Process dockable frame messages.
00390 
00391    switch (GET_MSG(msg)) {
00392       case kC_COMMAND:
00393          switch (GET_SUBMSG(msg)) {
00394             case kCM_BUTTON:
00395                switch (parm1) {
00396                   case 1:
00397                      if (!fHidden) UndockContainer();
00398                      break;
00399                   case 2:
00400                      if (!fHidden)
00401                         HideContainer();
00402                      else
00403                         ShowContainer();
00404                      break;
00405                }
00406                break;
00407          }
00408          break;
00409    }
00410 
00411    return kTRUE;
00412 }
00413 
00414 //______________________________________________________________________________
00415 void TGDockableFrame::EnableUndock(Bool_t onoff)
00416 {
00417    // Enable undocking.
00418 
00419    fEnableUndock = onoff;
00420    if (onoff)
00421       fButtons->ShowFrame(fDockButton);
00422    else
00423       fButtons->HideFrame(fDockButton);
00424    Layout();
00425 }
00426 
00427 //______________________________________________________________________________
00428 void TGDockableFrame::EnableHide(Bool_t onoff)
00429 {
00430    // Enable hiding.
00431 
00432    fEnableHide = onoff;
00433    if (onoff)
00434       fButtons->ShowFrame(fHideButton);
00435    else
00436       fButtons->HideFrame(fHideButton);
00437    Layout();
00438 }
00439 
00440 //______________________________________________________________________________
00441 void TGDockableFrame::SetWindowName(const char *name)
00442 {
00443    // Set window name so it appear as title of the undock window.
00444 
00445    fDockName = "";
00446    if (name) {
00447       fDockName = name;
00448       if (fFrame) fFrame->SetWindowName(fDockName);
00449    }
00450 }
00451 
00452 //______________________________________________________________________________
00453 void TGDockableFrame::SavePrimitive(ostream &out, Option_t *option /*= ""*/)
00454 {
00455    // Save a dockable frame widget as a C++ statement(s) on output stream out.
00456 
00457    char quote = '"';
00458 
00459    out << endl << "   // dockable frame" << endl;
00460    out << "   TGDockableFrame *";
00461    out << GetName()<<" = new TGDockableFrame(" << fParent->GetName();
00462 
00463    if (GetOptions() == kHorizontalFrame) {
00464       if (fWidgetId == -1) {
00465          out << ");" << endl;
00466       } else {
00467          out << "," << fWidgetId << ");" << endl;
00468       }
00469    } else {
00470       out << "," << fWidgetId << "," << GetOptionString() << ");" << endl;
00471    }
00472    if (option && strstr(option, "keep_names"))
00473       out << "   " << GetName() << "->SetName(\"" << GetName() << "\");" << endl;
00474 
00475    if (GetContainer()->GetList()->First()) {
00476       out << "   TGCompositeFrame *" << GetContainer()->GetName() << " = "
00477           << GetName() << "->GetContainer();" << endl;
00478 
00479       TGFrameElement *el;
00480       TIter next(GetContainer()->GetList());
00481 
00482       while ((el = (TGFrameElement *) next())) {
00483          el->fFrame->SavePrimitive(out, option);
00484          out << "   " << GetName() << "->AddFrame(" << el->fFrame->GetName();
00485          el->fLayout->SavePrimitive(out, option);
00486          out << ");"<< endl;
00487       }
00488    }
00489    out << endl << "   // next lines belong to the dockable frame widget" << endl;
00490    if (EnableUndock())
00491       out << "   " << GetName() << "->EnableUndock(kTRUE);" << endl;
00492    else
00493       out << "   " << GetName() << "->EnableUndock(kFALSE);" << endl;
00494 
00495    if (EnableHide())
00496       out << "   " << GetName() << "->EnableHide(kTRUE);" << endl;
00497    else
00498       out << "   " << GetName() << "->EnableHide(kFALSE);" << endl;
00499 
00500    if (fDockName != "")
00501       out << "   " << GetName() << "->SetWindowName(" << quote << fDockName
00502           << quote << ");" << endl;
00503 
00504    if (IsUndocked())
00505       out << "   " << GetName() << "->UndockContainer();" << endl;
00506    else
00507       out << "   " << GetName() << "->DockContainer();" << endl;
00508 
00509    if (IsHidden())
00510       out << "   " << GetName() << "->HideContainer();" << endl;
00511 
00512    out << endl;
00513 }

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