00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 
00025 
00026 
00027 
00028 
00029 
00030 
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    
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    
00078 }
00079 
00080 
00081 Bool_t TGDockButton::HandleCrossing(Event_t *event)
00082 {
00083    
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    
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    
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    
00141 
00142    Resize(10, 8);
00143    fAspectRatio = 0;
00144    SetWindowName();
00145 }
00146 
00147 
00148 void TGDockHideButton::DoRedraw()
00149 {
00150    
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    
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    
00190 
00191    if (fDockable && !fDockable->fDeleted) {
00192       fDockable->DockContainer(kFALSE);
00193    }
00194 }
00195 
00196 
00197 void TGUndockedFrame::FixSize()
00198 {
00199    
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    
00210 
00211    DeleteWindow();
00212 }
00213 
00214 
00215 
00216 TGDockableFrame::TGDockableFrame(const TGWindow *p, int id, UInt_t )
00217    : TGCompositeFrame(p, 10, 10, kHorizontalFrame), TGWidget(id)
00218 {
00219    
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    
00262 
00263    
00264    
00265    if (fFrame) {
00266       fDeleted = kTRUE;
00267       delete fFrame;
00268    }
00269 }
00270 
00271 
00272 void TGDockableFrame::AddFrame(TGFrame *f, TGLayoutHints *hints)
00273 {
00274    
00275 
00276    f->ReparentWindow(fContainer);
00277    fContainer->AddFrame(f, fHints = hints);
00278    fContainer->Layout();
00279 }
00280 
00281 
00282 void TGDockableFrame::UndockContainer()
00283 {
00284    
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);  
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())           
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    
00324 
00325    if (!fFrame) return;
00326    if (del) {
00327       delete fFrame;  
00328       return;
00329    }
00330 
00331    fFrame->RemoveFrame(fContainer);
00332    fContainer->ReparentWindow(this);
00333    TGCompositeFrame::AddFrame(fContainer, fCl);  
00334 
00335    
00336    fDockButton->Resize(fDockButton->GetDefaultWidth(), 1);
00337 
00338    Layout();
00339    if (((TGFrame *)fParent)->IsComposite())           
00340       ((TGCompositeFrame *)fParent)->ShowFrame(this);
00341 
00342    
00343    
00344    
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    
00356 
00357    if (!fHidden) return;
00358 
00359    ShowFrame(fContainer);
00360    if (fEnableUndock) fButtons->ShowFrame(fDockButton);
00361    fHideButton->SetAspectRatio(0);
00362    if (((TGFrame *)fParent)->IsComposite())           
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    
00373 
00374    if (fHidden || !fEnableHide) return;
00375 
00376    HideFrame(fContainer);
00377    fButtons->HideFrame(fDockButton);
00378    fHideButton->SetAspectRatio(1);
00379    if (((TGFrame *)fParent)->IsComposite())           
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    
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    
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    
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    
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    
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 }