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 }