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
00035
00036
00037
00038
00039
00040
00041 #include "KeySymbols.h"
00042 #include "TGFrame.h"
00043 #include "TGMdiMainFrame.h"
00044 #include "TGMdiDecorFrame.h"
00045 #include "TGMdiFrame.h"
00046 #include "TGMdiMenu.h"
00047 #include "TGGC.h"
00048 #include "TGResourcePool.h"
00049 #include "Riostream.h"
00050 #include "TList.h"
00051
00052 ClassImp(TGMdiMainFrame)
00053 ClassImp(TGMdiContainer)
00054 ClassImp(TGMdiGeometry)
00055 ClassImp(TGMdiFrameList)
00056
00057
00058 TGMdiMainFrame::TGMdiMainFrame(const TGWindow *p, TGMdiMenuBar *menuBar,
00059 Int_t w, Int_t h, UInt_t options,
00060 Pixel_t back) :
00061 TGCanvas(p, w, h, options | kDoubleBorder | kSunkenFrame | kMdiMainFrame, back)
00062 {
00063
00064
00065 fContainer = new TGMdiContainer(this, 10, 10, kOwnBackground,
00066 fClient->GetShadow(GetDefaultFrameBackground()));
00067 TGCanvas::SetContainer(fContainer);
00068
00069 fNumberOfFrames = 0;
00070 fMenuBar = menuBar;
00071 fChildren = 0;
00072 fCurrent = 0;
00073 fArrangementMode = 0;
00074
00075 const TGResourcePool *res = GetResourcePool();
00076 fBackCurrent = res->GetSelectedBgndColor();
00077 fForeCurrent = res->GetSelectedFgndColor();
00078 fForeNotCurrent = res->GetFrameBgndColor();
00079 fBackNotCurrent = res->GetFrameShadowColor();
00080 fFontCurrent = (TGFont *)res->GetMenuFont();
00081 fFontNotCurrent = fFontCurrent;
00082
00083 fBoxGC = new TGGC(*gClient->GetResourcePool()->GetFrameGC());
00084 fBoxGC->SetForeground(fForeNotCurrent);
00085 fBoxGC->SetBackground(fBackNotCurrent);
00086 fBoxGC->SetFunction(kGXxor);
00087 fBoxGC->SetLineWidth(TGMdiDecorFrame::kMdiBorderWidth-3);
00088 fBoxGC->SetSubwindowMode(kIncludeInferiors);
00089 fBoxGC->SetStipple(fClient->GetResourcePool()->GetCheckeredBitmap());
00090 fBoxGC->SetFillStyle(kFillOpaqueStippled);
00091
00092 fCurrentX = fCurrentY = 0;
00093 fResizeMode = kMdiDefaultResizeMode;
00094
00095 fWinListMenu = new TGPopupMenu(fClient->GetDefaultRoot());
00096
00097 const TGMainFrame *main = (TGMainFrame *) GetMainFrame();
00098 if (main){
00099 Int_t keycode = gVirtualX->KeysymToKeycode(kKey_Tab);
00100 main->BindKey(this, keycode, kKeyControlMask);
00101 main->BindKey(this, keycode, kKeyControlMask | kKeyShiftMask);
00102 keycode = gVirtualX->KeysymToKeycode(kKey_F4);
00103 main->BindKey(this, keycode, kKeyControlMask);
00104 }
00105
00106 MapSubwindows();
00107 Layout();
00108 MapWindow();
00109 SetWindowName();
00110 }
00111
00112
00113 TGMdiMainFrame::~TGMdiMainFrame()
00114 {
00115
00116
00117 TGMdiFrameList *tmp, *travel = fChildren;
00118
00119 while (travel) {
00120 tmp = travel->GetNext();
00121 delete travel;
00122 travel = tmp;
00123 }
00124
00125 if (fFontCurrent) fClient->FreeFont((TGFont *)fFontCurrent);
00126 if (fFontNotCurrent != fFontCurrent) fClient->FreeFont((TGFont *)fFontNotCurrent);
00127
00128 delete fBoxGC;
00129
00130 if (!MustCleanup()) {
00131
00132 const TGMainFrame *main = (TGMainFrame *) GetMainFrame();
00133
00134 if (main && main->InheritsFrom("TGMainFrame")) {
00135 Int_t keycode = gVirtualX->KeysymToKeycode(kKey_Tab);
00136 main->RemoveBind(this, keycode, kKeyControlMask);
00137 main->RemoveBind(this, keycode, kKeyControlMask | kKeyShiftMask);
00138 keycode = gVirtualX->KeysymToKeycode(kKey_F4);
00139 main->RemoveBind(this, keycode, kKeyControlMask);
00140 }
00141 }
00142 }
00143
00144
00145 void TGMdiMainFrame::SetResizeMode(Int_t mode)
00146 {
00147
00148
00149 TGMdiFrameList *travel;
00150
00151 fResizeMode = mode;
00152 for (travel = fChildren; travel; travel = travel->GetNext()) {
00153 travel->GetDecorFrame()->SetResizeMode(mode);
00154 }
00155 }
00156
00157
00158 Bool_t TGMdiMainFrame::HandleKey(Event_t *event)
00159 {
00160
00161
00162 char input[10];
00163 UInt_t keysym;
00164
00165 if (event->fType == kGKeyPress) {
00166 gVirtualX->LookupString(event, input, sizeof(input), keysym);
00167 if ((EKeySym)keysym == kKey_Tab) {
00168 if (event->fState & kKeyControlMask) {
00169 if (event->fState & kKeyShiftMask) {
00170 CirculateUp();
00171 } else {
00172 CirculateDown();
00173 }
00174 return kTRUE;
00175 }
00176 } else if ((EKeySym)keysym == kKey_F4) {
00177 if (event->fState & kKeyControlMask) {
00178 Close(GetCurrent());
00179 return kTRUE;
00180 }
00181 }
00182 }
00183 return kFALSE;
00184 }
00185
00186
00187 void TGMdiMainFrame::AddMdiFrame(TGMdiFrame *frame)
00188 {
00189
00190
00191 TGMdiFrameList *travel;
00192
00193 frame->UnmapWindow();
00194
00195 travel = new TGMdiFrameList;
00196 travel->SetCyclePrev(travel);
00197 travel->SetCycleNext(travel);
00198 travel->SetPrev(0);
00199 if (fChildren) fChildren->SetPrev(travel);
00200 travel->SetNext(fChildren);
00201 fChildren = travel;
00202
00203 travel->SetDecorFrame(new TGMdiDecorFrame(this, frame, frame->GetWidth(),
00204 frame->GetHeight(), fBoxGC));
00205
00206 travel->SetFrameId(frame->GetId());
00207 travel->GetDecorFrame()->SetResizeMode(fResizeMode);
00208
00209 if (fCurrentX + travel->GetDecorFrame()->GetWidth() > fWidth) fCurrentX = 0;
00210 if (fCurrentY + travel->GetDecorFrame()->GetHeight() > fHeight) fCurrentY = 0;
00211 travel->GetDecorFrame()->Move(fCurrentX, fCurrentY);
00212
00213 fCurrentX += travel->GetDecorFrame()->GetTitleBar()->GetHeight() + fBorderWidth * 2;
00214 fCurrentY += travel->GetDecorFrame()->GetTitleBar()->GetHeight() + fBorderWidth * 2;
00215
00216 fNumberOfFrames++;
00217
00218 UpdateWinListMenu();
00219 SetCurrent(travel);
00220 Layout();
00221
00222 SendMessage(fParent, MK_MSG(kC_MDI, kMDI_CREATE), travel->GetDecorFrame()->GetId(), 0);
00223 FrameCreated(travel->GetDecorFrame()->GetId());
00224 }
00225
00226
00227 Bool_t TGMdiMainFrame::RemoveMdiFrame(TGMdiFrame *frame)
00228 {
00229
00230
00231 TGMdiFrameList *travel = fChildren;
00232
00233 if (!frame) return kFALSE;
00234
00235 if (frame->IsEditable()) frame->SetEditable(kFALSE);
00236
00237 while (travel && (travel->GetFrameId() != frame->GetId()))
00238 travel = travel->GetNext();
00239 if (!travel) return kFALSE;
00240
00241 if (travel == fCurrent) fCurrent = 0;
00242
00243
00244 travel->GetCyclePrev()->SetCycleNext(travel->GetCycleNext());
00245 travel->GetCycleNext()->SetCyclePrev(travel->GetCyclePrev());
00246
00247
00248 if (travel->GetNext()) {
00249 travel->GetNext()->SetPrev(travel->GetPrev());
00250 }
00251 if (travel->GetPrev()) {
00252 travel->GetPrev()->SetNext(travel->GetNext());
00253 } else {
00254 fChildren = travel->GetNext();
00255 }
00256
00257 if (!fCurrent) {
00258 if (fChildren) SetCurrent(travel->GetCyclePrev());
00259 }
00260
00261 travel->GetDecorFrame()->RemoveFrame(frame);
00262
00263 UInt_t old_id = frame->GetId();
00264
00265 delete travel->fDecor;
00266
00267 fNumberOfFrames--;
00268
00269 UpdateWinListMenu();
00270 Layout();
00271
00272 SendMessage(fParent, MK_MSG(kC_MDI, kMDI_CLOSE), old_id, 0);
00273 FrameClosed(old_id);
00274
00275 return kTRUE;
00276 }
00277
00278
00279 Bool_t TGMdiMainFrame::SetCurrent(UInt_t id)
00280 {
00281
00282
00283 if (fCurrent && (fCurrent->GetDecorFrame()->GetId() == id)) {
00284 fCurrent->GetDecorFrame()->RaiseWindow();
00285 if (fCurrent->GetDecorFrame()->IsMaximized() && fMenuBar)
00286 fMenuBar->ShowFrames(fCurrent->GetDecorFrame()->GetTitleBar()->GetWinIcon(),
00287 fCurrent->GetDecorFrame()->GetTitleBar()->GetButtons());
00288
00289 Emit("SetCurrent(TGMdiFrame*)", (long)fCurrent->GetDecorFrame()->GetMdiFrame());
00290 return kTRUE;
00291 }
00292
00293 TGMdiFrameList *travel = fChildren;
00294 while (travel && (travel->GetDecorFrame()->GetId() != id)) travel = travel->GetNext();
00295 if (!travel) return kFALSE;
00296
00297 return SetCurrent(travel);
00298 }
00299
00300
00301 Bool_t TGMdiMainFrame::SetCurrent(TGMdiFrame *f)
00302 {
00303
00304
00305 if (fCurrent && (fCurrent->GetDecorFrame()->GetMdiFrame() == f)) {
00306 fCurrent->GetDecorFrame()->RaiseWindow();
00307 if (fCurrent->GetDecorFrame()->IsMaximized() && fMenuBar)
00308 fMenuBar->ShowFrames(fCurrent->GetDecorFrame()->GetTitleBar()->GetWinIcon(),
00309 fCurrent->GetDecorFrame()->GetTitleBar()->GetButtons());
00310 Emit("SetCurrent(TGMdiFrame*)", (long)fCurrent->GetDecorFrame()->GetMdiFrame());
00311 return kTRUE;
00312 }
00313
00314 TGMdiFrameList *travel = fChildren;
00315 while (travel && (travel->GetDecorFrame()->GetMdiFrame() != f)) travel = travel->GetNext();
00316 if (!travel) return kFALSE;
00317
00318 return SetCurrent(travel);
00319 }
00320
00321
00322 Bool_t TGMdiMainFrame::SetCurrent(TGMdiFrameList *newcurrent)
00323 {
00324
00325
00326 if (fCurrent && (fCurrent == newcurrent)) {
00327 fCurrent->GetDecorFrame()->RaiseWindow();
00328 if (fCurrent->GetDecorFrame()->IsMaximized() && fMenuBar)
00329 fMenuBar->ShowFrames(fCurrent->GetDecorFrame()->GetTitleBar()->GetWinIcon(),
00330 fCurrent->GetDecorFrame()->GetTitleBar()->GetButtons());
00331 Emit("SetCurrent(TGMdiFrame*)", (long)fCurrent->GetDecorFrame()->GetMdiFrame());
00332 return kTRUE;
00333 }
00334
00335 if (fCurrent) {
00336 if (!fCurrent->GetDecorFrame()->IsMaximized())
00337 fCurrent->GetDecorFrame()->GetTitleBar()->SetTitleBarColors(fForeNotCurrent,
00338 fBackNotCurrent,
00339 fFontNotCurrent);
00340 }
00341
00342 if (newcurrent) {
00343 if (fCurrent) {
00344
00345 newcurrent->GetCyclePrev()->SetCycleNext(newcurrent->GetCycleNext());
00346 newcurrent->GetCycleNext()->SetCyclePrev(newcurrent->GetCyclePrev());
00347
00348 newcurrent->SetCyclePrev(fCurrent);
00349 newcurrent->SetCycleNext(fCurrent->GetCycleNext());
00350 fCurrent->SetCycleNext(newcurrent);
00351 newcurrent->GetCycleNext()->SetCyclePrev(newcurrent);
00352 } else {
00353
00354 if (fChildren && newcurrent != fChildren) {
00355
00356 newcurrent->GetCyclePrev()->SetCycleNext(newcurrent->GetCycleNext());
00357 newcurrent->GetCycleNext()->SetCyclePrev(newcurrent->GetCyclePrev());
00358
00359 newcurrent->SetCyclePrev(fChildren);
00360 newcurrent->SetCycleNext(fChildren->GetCycleNext());
00361 fChildren->SetCycleNext(newcurrent);
00362 newcurrent->GetCycleNext()->SetCyclePrev(newcurrent);
00363 }
00364 }
00365 }
00366
00367 fCurrent = newcurrent;
00368
00369 if (!fCurrent) return kFALSE;
00370
00371 if (!fCurrent->GetDecorFrame()->IsMaximized())
00372 fCurrent->GetDecorFrame()->GetTitleBar()->SetTitleBarColors(fForeCurrent,
00373 fBackCurrent,
00374 fFontCurrent);
00375
00376 fCurrent->GetDecorFrame()->RaiseWindow();
00377 Emit("SetCurrent(TGMdiFrame*)", (long)fCurrent->GetDecorFrame()->GetMdiFrame());
00378
00379 fWinListMenu->RCheckEntry(fCurrent->GetDecorFrame()->GetId(), 0, kMaxInt);
00380
00381 if (fCurrent->GetDecorFrame()->IsMaximized() && fMenuBar)
00382 fMenuBar->ShowFrames(fCurrent->GetDecorFrame()->GetTitleBar()->GetWinIcon(),
00383 fCurrent->GetDecorFrame()->GetTitleBar()->GetButtons());
00384
00385 return kTRUE;
00386 }
00387
00388
00389 void TGMdiMainFrame::CirculateUp()
00390 {
00391
00392
00393 if (fCurrent) {
00394 fCurrent->GetDecorFrame()->GetTitleBar()->SetTitleBarColors(fForeNotCurrent,
00395 fBackNotCurrent,
00396 fFontNotCurrent);
00397
00398 fCurrent = fCurrent->GetCycleNext();
00399
00400 fCurrent->GetDecorFrame()->RaiseWindow();
00401 fCurrent->GetDecorFrame()->GetTitleBar()->SetTitleBarColors(fForeCurrent,
00402 fBackCurrent,
00403 fFontCurrent);
00404 if (fCurrent->GetDecorFrame()->IsMaximized() && fMenuBar)
00405 fMenuBar->ShowFrames(fCurrent->GetDecorFrame()->GetTitleBar()->GetWinIcon(),
00406 fCurrent->GetDecorFrame()->GetTitleBar()->GetButtons());
00407
00408 } else if (fChildren) {
00409 SetCurrent(fChildren);
00410 }
00411 }
00412
00413
00414 void TGMdiMainFrame::CirculateDown()
00415 {
00416
00417
00418 if (fCurrent) {
00419 fCurrent->GetDecorFrame()->LowerWindow();
00420 fCurrent->GetDecorFrame()->GetTitleBar()->SetTitleBarColors(fForeNotCurrent,
00421 fBackNotCurrent,
00422 fFontNotCurrent);
00423
00424 fCurrent = fCurrent->GetCyclePrev();
00425
00426 fCurrent->GetDecorFrame()->RaiseWindow();
00427 fCurrent->GetDecorFrame()->GetTitleBar()->SetTitleBarColors(fForeCurrent,
00428 fBackCurrent,
00429 fFontCurrent);
00430 if (fCurrent->GetDecorFrame()->IsMaximized() && fMenuBar)
00431 fMenuBar->ShowFrames(fCurrent->GetDecorFrame()->GetTitleBar()->GetWinIcon(),
00432 fCurrent->GetDecorFrame()->GetTitleBar()->GetButtons());
00433 } else if (fChildren) {
00434 SetCurrent(fChildren);
00435 }
00436 }
00437
00438
00439 TGMdiDecorFrame *TGMdiMainFrame::GetDecorFrame(TGMdiFrame *frame) const
00440 {
00441
00442
00443 TGMdiFrameList *travel = fChildren;
00444 while (travel && (travel->GetDecorFrame()->GetMdiFrame() != frame))
00445 travel = travel->GetNext();
00446 if (!travel) return 0;
00447 return travel->GetDecorFrame();
00448 }
00449
00450
00451 TGMdiDecorFrame *TGMdiMainFrame::GetDecorFrame(UInt_t id) const
00452 {
00453
00454
00455 TGMdiFrameList *travel = fChildren;
00456 while (travel && (travel->GetDecorFrame()->GetId() != id)) travel = travel->GetNext();
00457 if (!travel) return 0;
00458 return travel->GetDecorFrame();
00459 }
00460
00461
00462 TGMdiFrame *TGMdiMainFrame::GetMdiFrame(UInt_t id) const
00463 {
00464
00465
00466 TGMdiDecorFrame *frame = GetDecorFrame(id);
00467 if (!frame) return 0;
00468 return frame->GetMdiFrame();
00469 }
00470
00471
00472 TGRectangle TGMdiMainFrame::GetBBox() const
00473 {
00474
00475
00476 if (fCurrent && fCurrent->GetDecorFrame()->IsMaximized()) {
00477 return TGRectangle(0, 0, fWidth - 2 * fBorderWidth, fHeight - 2 * fBorderWidth);
00478 } else {
00479 TGRectangle rect;
00480 TGMdiFrameList *travel;
00481
00482 for (travel = fChildren; travel; travel = travel->GetNext()) {
00483 Int_t x = travel->GetDecorFrame()->GetX();
00484 Int_t y = travel->GetDecorFrame()->GetY();
00485 UInt_t w = travel->GetDecorFrame()->GetWidth();
00486 UInt_t h = travel->GetDecorFrame()->GetHeight();
00487 TGRectangle wrect(x, y, w, h);
00488 rect.Merge(wrect);
00489 }
00490 return rect;
00491 }
00492 }
00493
00494
00495 TGRectangle TGMdiMainFrame::GetMinimizedBBox() const
00496 {
00497
00498
00499 TGRectangle rect;
00500 TGMdiFrameList *travel;
00501 Int_t first = kTRUE;
00502
00503 for (travel = fChildren; travel; travel = travel->GetNext()) {
00504 if (travel->GetDecorFrame()->IsMinimized()) {
00505 TGRectangle wrect(travel->GetDecorFrame()->GetX(), travel->GetDecorFrame()->GetY(),
00506 travel->GetDecorFrame()->GetWidth(), travel->GetDecorFrame()->GetHeight());
00507 if (first) rect = wrect;
00508 else rect.Merge(wrect);
00509 first = kFALSE;
00510 }
00511 }
00512 return rect;
00513 }
00514
00515
00516 void TGMdiMainFrame::UpdateWinListMenu()
00517 {
00518
00519
00520 TString buf;
00521 char scut;
00522 TGMdiFrameList *travel;
00523 const TGPicture *pic;
00524
00525 TGMenuEntry *e;
00526 TIter fNext(fWinListMenu->GetListOfEntries());
00527 while ((e = (TGMenuEntry*)fNext())) {
00528 fWinListMenu->DeleteEntry(e);
00529 }
00530 scut = '0';
00531
00532 if (!fChildren) {
00533 fWinListMenu->AddEntry(new TGHotString("(None)"), 1000);
00534 fWinListMenu->DisableEntry(1000);
00535 return;
00536 }
00537
00538 for (travel = fChildren; travel; travel = travel->GetNext()) {
00539 scut++;
00540 if (scut == ('9' + 1)) scut = 'A';
00541 buf = TString::Format("&%c. %s", scut, travel->GetDecorFrame()->GetWindowName());
00542 if (travel->GetDecorFrame()->GetMdiButtons() & kMdiMenu)
00543 pic = travel->GetDecorFrame()->GetWindowIcon();
00544 else
00545 pic = 0;
00546 fWinListMenu->AddEntry(new TGHotString(buf.Data()), travel->GetDecorFrame()->GetId(), 0, pic);
00547 }
00548
00549 if (fCurrent)
00550 fWinListMenu->RCheckEntry(fCurrent->GetDecorFrame()->GetId(), 0, kMaxInt);
00551 }
00552
00553
00554 void TGMdiMainFrame::Layout()
00555 {
00556
00557
00558 TGCanvas::Layout();
00559 if (fCurrent && fCurrent->GetDecorFrame()->IsMaximized())
00560 fCurrent->GetDecorFrame()->MoveResize(0, 0, fWidth - 2 *fBorderWidth, fHeight -
00561 2 * fBorderWidth);
00562 }
00563
00564
00565 void TGMdiMainFrame::ArrangeFrames(Int_t mode)
00566 {
00567
00568
00569
00570 Int_t factor_x = 0;
00571 Int_t factor_y = 0;
00572 Int_t num_mapped = 0;
00573 Int_t x = 0;
00574 Int_t y = 0;
00575 Int_t w = fWidth - 2 * fBorderWidth;
00576 Int_t h = fHeight - 2 * fBorderWidth;
00577
00578 fArrangementMode = mode;
00579
00580 TGMdiFrameList *tmp, *travel;
00581
00582 for (travel = fChildren; travel; travel = travel->GetNext()) {
00583 if (travel->GetDecorFrame()->IsMaximized())
00584 Restore(travel->GetDecorFrame()->GetMdiFrame());
00585 if (!travel->GetDecorFrame()->IsMinimized())
00586 ++num_mapped;
00587 }
00588
00589
00590 GetViewPort()->SetHPos(0);
00591 GetViewPort()->SetVPos(0);
00592
00593 ArrangeMinimized();
00594
00595 travel = fChildren;
00596
00597 if (num_mapped == 0) return;
00598
00599 TGRectangle irect = GetMinimizedBBox();
00600 h -= irect.fH;
00601
00602 switch (mode) {
00603 case kMdiTileHorizontal:
00604 factor_y = h / num_mapped;
00605 for (travel = fChildren; travel; travel = travel->GetNext()) {
00606 if (!travel->GetDecorFrame()->IsMinimized()) {
00607 travel->GetDecorFrame()->MoveResize(x, y, w, factor_y);
00608 y = y + factor_y;
00609 }
00610 }
00611 break;
00612
00613 case kMdiTileVertical:
00614 factor_x = w / num_mapped;
00615 for (travel = fChildren; travel; travel = travel->GetNext()) {
00616 if (!travel->GetDecorFrame()->IsMinimized()) {
00617 travel->GetDecorFrame()->MoveResize(x, y, factor_x, h);
00618 x = x + factor_x;
00619 }
00620 }
00621 break;
00622
00623 case kMdiCascade:
00624 y = travel->GetDecorFrame()->GetTitleBar()->GetX() +
00625 travel->GetDecorFrame()->GetTitleBar()->GetHeight();
00626 x = y;
00627 factor_y = (h * 2) / 3;
00628 factor_x = (w * 2) / 3;
00629
00630 travel = fCurrent;
00631 if (!travel) travel = fChildren;
00632 tmp = travel;
00633 if (travel) {
00634 do {
00635 travel = travel->GetCycleNext();
00636 if (!travel->GetDecorFrame()->IsMinimized()) {
00637 travel->GetDecorFrame()->MoveResize(x - y, x - y, factor_x, factor_y);
00638 x += y;
00639 }
00640 } while (travel != tmp);
00641 }
00642 break;
00643 }
00644
00645 FramesArranged(mode);
00646
00647 Layout();
00648 }
00649
00650
00651 void TGMdiMainFrame::ArrangeMinimized()
00652 {
00653
00654
00655 TGMdiFrameList *travel, *closest;
00656 Int_t x, y, w, h;
00657
00658 Bool_t arranged = kTRUE;
00659
00660 for (travel = fChildren; travel && arranged; travel = travel->GetNext())
00661 if (travel->GetDecorFrame()->IsMinimized()) arranged = kFALSE;
00662
00663
00664
00665 if (arranged || !fChildren) return;
00666
00667 h = fChildren->GetDecorFrame()->GetTitleBar()->GetDefaultHeight() +
00668 fChildren->GetDecorFrame()->GetBorderWidth();
00669 w = kMinimizedWidth * h + fChildren->GetDecorFrame()->GetBorderWidth();
00670
00671 x = 0;
00672 y = GetViewPort()->GetHeight() - h;
00673
00674
00675
00676 for (travel = fChildren; travel; travel = travel->GetNext())
00677 travel->GetDecorFrame()->SetMinUserPlacement();
00678
00679 do {
00680 closest = 0;
00681 Int_t cdist = 0;
00682 for (travel = fChildren; travel; travel = travel->GetNext()) {
00683 if (travel->GetDecorFrame()->IsMinimized()) {
00684 if (travel->GetDecorFrame()->GetMinUserPlacement()) {
00685 Int_t dx = travel->GetDecorFrame()->GetX() - x;
00686 Int_t dy = y - travel->GetDecorFrame()->GetY();
00687 Int_t dist = dx * dx + dy * dy;
00688 if (!closest || (dist < cdist)) {
00689 closest = travel;
00690 cdist = dist;
00691 }
00692 }
00693 }
00694 }
00695
00696 if (closest) {
00697 closest->GetDecorFrame()->SetMinimizedX(x);
00698 closest->GetDecorFrame()->SetMinimizedY(y);
00699 closest->GetDecorFrame()->MoveResize(x, y, w, h);
00700 closest->GetDecorFrame()->SetMinUserPlacement(kFALSE);
00701
00702 x += w;
00703 if (x + w > (Int_t)GetViewPort()->GetWidth()) {
00704 x = 0;
00705 y -= h;
00706 }
00707 }
00708
00709 } while (closest);
00710
00711
00712
00713 for (travel = fChildren; travel; travel = travel->GetNext())
00714 travel->GetDecorFrame()->SetMinUserPlacement(kFALSE);
00715 }
00716
00717
00718 Bool_t TGMdiMainFrame::ProcessMessage(Long_t msg, Long_t parm1, Long_t parm2)
00719 {
00720
00721
00722 switch (GET_MSG(msg)) {
00723 case kC_MDI:
00724 SetCurrent(parm1);
00725 switch (GET_SUBMSG(msg)) {
00726
00727 case kMDI_MINIMIZE:
00728 Minimize(GetCurrent());
00729 break;
00730
00731 case kMDI_MAXIMIZE:
00732 Maximize(GetCurrent());
00733 break;
00734
00735 case kMDI_RESTORE:
00736 Restore(GetCurrent());
00737 break;
00738
00739 case kMDI_CLOSE:
00740 Close(GetCurrent());
00741 break;
00742
00743 case kMDI_MOVE:
00744 FreeMove(GetCurrent());
00745 break;
00746
00747 case kMDI_SIZE:
00748 FreeSize(GetCurrent());
00749 break;
00750
00751 case kMDI_HELP:
00752 ContextHelp(GetCurrent());
00753 break;
00754 }
00755 break;
00756
00757 default:
00758 return TGCanvas::ProcessMessage(msg, parm1, parm2);
00759 }
00760
00761 return kTRUE;
00762 }
00763
00764
00765 void TGMdiMainFrame::Maximize(TGMdiFrame *mdiframe)
00766 {
00767
00768
00769 TGMdiDecorFrame *frame = GetDecorFrame(mdiframe);
00770
00771 if (!frame) return;
00772
00773 if (frame->IsMaximized()) return;
00774
00775 if (frame->IsMinimized()) Restore(mdiframe);
00776
00777 frame->SetDecorBorderWidth(0);
00778 frame->SetPreResizeX(frame->GetX());
00779 frame->SetPreResizeY(frame->GetY());
00780 frame->SetPreResizeWidth(frame->GetWidth());
00781 frame->SetPreResizeHeight(frame->GetHeight());
00782 frame->GetUpperHR()->UnmapWindow();
00783 frame->GetLowerHR()->UnmapWindow();
00784 frame->GetLeftVR()->UnmapWindow();
00785 frame->GetRightVR()->UnmapWindow();
00786 frame->GetUpperLeftCR()->UnmapWindow();
00787 frame->GetUpperRightCR()->UnmapWindow();
00788 frame->GetLowerLeftCR()->UnmapWindow();
00789 frame->GetLowerRightCR()->UnmapWindow();
00790
00791 frame->MoveResize(fBorderWidth, fBorderWidth, fWidth - 2 *fBorderWidth,
00792 fHeight - 2 * fBorderWidth);
00793 frame->Maximize();
00794 frame->GetTitleBar()->LayoutButtons(frame->GetMdiButtons(), frame->IsMinimized(),
00795 frame->IsMaximized());
00796 frame->GetTitleBar()->RemoveFrames(frame->GetTitleBar()->GetWinIcon(),
00797 frame->GetTitleBar()->GetButtons());
00798 frame->HideFrame(frame->GetTitleBar());
00799
00800 if (fMenuBar) {
00801 frame->GetTitleBar()->GetWinIcon()->SetBackgroundColor(GetDefaultFrameBackground());
00802 frame->GetTitleBar()->GetButtons()->SetBackgroundColor(GetDefaultFrameBackground());
00803 fMenuBar->AddFrames(frame->GetTitleBar()->GetWinIcon(),
00804 frame->GetTitleBar()->GetButtons());
00805 fMenuBar->Layout();
00806 }
00807
00808 SendMessage(fParent, MK_MSG(kC_MDI, kMDI_MAXIMIZE), frame->GetId(), 0);
00809 FrameMaximized(frame->GetId());
00810
00811 Layout();
00812 }
00813
00814
00815 void TGMdiMainFrame::Restore(TGMdiFrame *mdiframe)
00816 {
00817
00818
00819 TGMdiDecorFrame *frame = GetDecorFrame(mdiframe);
00820
00821 if (!frame) return;
00822
00823 if (frame->IsMinimized() == kFALSE && frame->IsMaximized() == kFALSE) return;
00824
00825 if (frame->IsMinimized()) {
00826 frame->SetMinimizedX(frame->GetX());
00827 frame->SetMinimizedY(frame->GetY());
00828 frame->Minimize(kFALSE);
00829 frame->GetTitleBar()->SetTitleBarColors(fForeCurrent,
00830 fBackCurrent,
00831 fFontCurrent);
00832 } else if (frame->IsMaximized()) {
00833 frame->SetDecorBorderWidth(TGMdiDecorFrame::kMdiBorderWidth);
00834 frame->MapSubwindows();
00835
00836 if (fMenuBar) {
00837 fMenuBar->RemoveFrames(frame->GetTitleBar()->GetWinIcon(),
00838 frame->GetTitleBar()->GetButtons());
00839 fMenuBar->Layout();
00840 }
00841
00842 frame->GetTitleBar()->AddFrames(frame->GetTitleBar()->GetWinIcon(),
00843 frame->GetTitleBar()->GetButtons());
00844 frame->GetTitleBar()->SetTitleBarColors(fForeCurrent, fBackCurrent,
00845 fFontCurrent);
00846 frame->ShowFrame(frame->GetTitleBar());
00847 }
00848 frame->Minimize(kFALSE);
00849 frame->Maximize(kFALSE);
00850 frame->GetTitleBar()->LayoutButtons(frame->GetMdiButtons(), kFALSE, kFALSE);
00851 frame->MoveResize(frame->GetPreResizeX(), frame->GetPreResizeY(),
00852 frame->GetPreResizeWidth(), frame->GetPreResizeHeight());
00853 SetCurrent(mdiframe);
00854 SendMessage(fParent, MK_MSG(kC_MDI, kMDI_RESTORE), frame->GetId(), 0);
00855 FrameRestored(frame->GetId());
00856
00857 Layout();
00858 }
00859
00860
00861 void TGMdiMainFrame::Minimize(TGMdiFrame *mdiframe)
00862 {
00863
00864
00865 Int_t x, y, w, h;
00866 TGMdiDecorFrame *frame = GetDecorFrame(mdiframe);
00867
00868 if (!frame) return;
00869
00870 if (frame->IsMinimized()) return;
00871
00872 if (frame->IsMaximized()) Restore(mdiframe);
00873
00874 frame->SetPreResizeX(frame->GetX());
00875 frame->SetPreResizeY(frame->GetY());
00876 frame->SetPreResizeWidth(frame->GetWidth());
00877 frame->SetPreResizeHeight(frame->GetHeight());
00878
00879 h = frame->GetTitleBar()->GetDefaultHeight() + frame->GetBorderWidth();
00880 w = kMinimizedWidth * h + frame->GetBorderWidth();
00881
00882 if (!frame->GetMinUserPlacement()) {
00883
00884 x = 0;
00885 y = GetViewPort()->GetHeight() - h;
00886
00887 while (1) {
00888 TGMdiFrameList *travel;
00889 Bool_t taken = kFALSE;
00890
00891
00892 for (travel = fChildren; travel; travel = travel->GetNext()) {
00893 if (travel->GetDecorFrame()->IsMinimized()) {
00894 TGPosition p(travel->GetDecorFrame()->GetX(),
00895 travel->GetDecorFrame()->GetY());
00896 TGDimension s(travel->GetDecorFrame()->GetWidth(),
00897 travel->GetDecorFrame()->GetHeight());
00898 if ((x <= p.fX + (Int_t) s.fWidth - 1) && (x + w - 1 >= p.fX) &&
00899 (y <= p.fY + (Int_t) s.fHeight - 1) && (y + h - 1 >= p.fY)) {
00900 taken = kTRUE;
00901 break;
00902 }
00903 }
00904 }
00905 if (!taken) break;
00906
00907 x += w;
00908 if (x + w > (Int_t)GetViewPort()->GetWidth()) {
00909 x = 0;
00910 y -= h;
00911 }
00912 }
00913
00914 frame->SetMinimizedX(x);
00915 frame->SetMinimizedY(y);
00916 }
00917
00918 frame->Minimize();
00919
00920 frame->MoveResize(frame->GetMinimizedX(), frame->GetMinimizedY(), w, h);
00921 frame->LowerWindow();
00922 frame->GetTitleBar()->LayoutButtons(frame->GetMdiButtons(),
00923 frame->IsMinimized(),
00924 frame->IsMaximized());
00925 frame->Layout();
00926
00927 SendMessage(fParent, MK_MSG(kC_MDI, kMDI_MINIMIZE), frame->GetId(), 0);
00928 FrameMinimized(frame->GetId());
00929
00930 Layout();
00931 }
00932
00933
00934 Int_t TGMdiMainFrame::Close(TGMdiFrame *mdiframe)
00935 {
00936
00937
00938 if (!mdiframe) return kFALSE;
00939
00940 TGMdiDecorFrame *frame = GetDecorFrame(mdiframe);
00941 Restore(mdiframe);
00942 mdiframe->Emit("CloseWindow()");
00943 if (frame && mdiframe->TestBit(kNotDeleted) && !mdiframe->TestBit(TGMdiFrame::kDontCallClose))
00944 return frame->CloseWindow();
00945 return kTRUE;
00946 }
00947
00948
00949 void TGMdiMainFrame::FreeMove(TGMdiFrame *mdiframe)
00950 {
00951
00952
00953 TGMdiDecorFrame *frame = GetDecorFrame(mdiframe);
00954 if (!frame) return;
00955
00956 Int_t x = frame->GetTitleBar()->GetWidth() / 2;
00957 Int_t y = frame->GetTitleBar()->GetHeight() - 1;
00958
00959 gVirtualX->Warp(x, y, frame->GetTitleBar()->GetId());
00960
00961 frame->GetTitleBar()->SetLeftButPressed();
00962 frame->GetTitleBar()->SetX0(x);
00963 frame->GetTitleBar()->SetY0(y);
00964 Cursor_t cursor = gVirtualX->CreateCursor(kMove);
00965 gVirtualX->SetCursor(frame->GetTitleBar()->GetId(), cursor);
00966
00967 gVirtualX->GrabPointer(frame->GetTitleBar()->GetId(),
00968 kButtonReleaseMask | kPointerMotionMask,
00969 kNone, cursor, kTRUE, kFALSE);
00970 }
00971
00972
00973 void TGMdiMainFrame::FreeSize(TGMdiFrame *mdiframe)
00974 {
00975
00976
00977 TGMdiDecorFrame *frame = GetDecorFrame(mdiframe);
00978 if (!frame) return;
00979
00980 Int_t x = frame->GetLowerRightCR()->GetWidth() - 5;
00981 Int_t y = frame->GetLowerRightCR()->GetHeight() - 5;
00982
00983 Int_t xroot, yroot;
00984 Window_t win;
00985
00986 gVirtualX->TranslateCoordinates(frame->GetLowerRightCR()->GetId(),
00987 fClient->GetDefaultRoot()->GetId(), x, y, xroot, yroot, win);
00988
00989 gVirtualX->Warp(x, y, frame->GetLowerRightCR()->GetId());
00990
00991 Event_t event;
00992
00993 event.fType = kButtonPress;
00994 event.fWindow = frame->GetLowerRightCR()->GetId();
00995 event.fCode = kButton1;
00996 event.fX = x;
00997 event.fY = y;
00998 event.fXRoot = xroot;
00999 event.fYRoot = yroot;
01000
01001 Cursor_t cursor = gVirtualX->CreateCursor(kBottomRight);
01002 gVirtualX->SetCursor(frame->GetLowerRightCR()->GetId(), cursor);
01003
01004 gVirtualX->GrabPointer(frame->GetLowerRightCR()->GetId(),
01005 kButtonReleaseMask | kPointerMotionMask,
01006 kNone, cursor, kTRUE, kFALSE);
01007
01008 frame->GetLowerRightCR()->HandleButton(&event);
01009 }
01010
01011
01012 Int_t TGMdiMainFrame::ContextHelp(TGMdiFrame *mdiframe)
01013 {
01014
01015
01016 if (mdiframe)
01017 return mdiframe->Help();
01018 else
01019 return kFALSE;
01020 }
01021
01022
01023 TGMdiFrame *TGMdiMainFrame::GetCurrent() const
01024 {
01025
01026
01027 if (fCurrent)
01028 return fCurrent->GetDecorFrame()->GetMdiFrame();
01029 else
01030 return 0;
01031 }
01032
01033
01034 TGMdiGeometry TGMdiMainFrame::GetWindowGeometry(TGMdiFrame *f) const
01035 {
01036
01037
01038 TGMdiGeometry geom;
01039
01040 geom.fValueMask = 0;
01041
01042 const TGMdiDecorFrame *frame = GetDecorFrame(f);
01043 if (frame) {
01044 Int_t th = frame->GetTitleBar()->GetDefaultHeight();
01045 Int_t bw = frame->GetBorderWidth();
01046
01047 if (frame->IsMinimized() || frame->IsMaximized()) {
01048 geom.fDecoration = TGRectangle(frame->GetPreResizeX(),
01049 frame->GetPreResizeY(),
01050 (unsigned) frame->GetPreResizeWidth(),
01051 (unsigned) frame->GetPreResizeHeight());
01052 } else {
01053 geom.fDecoration = TGRectangle(frame->GetX(),
01054 frame->GetY(),
01055 (unsigned) frame->GetWidth(),
01056 (unsigned) frame->GetHeight());
01057 }
01058 geom.fValueMask |= kMdiDecorGeometry;
01059
01060 geom.fClient = TGRectangle(geom.fDecoration.fX + bw,
01061 geom.fDecoration.fY + bw + th,
01062 (unsigned) (geom.fDecoration.fW - 2 * bw),
01063 (unsigned) (geom.fDecoration.fH - 2 * bw - th));
01064 geom.fValueMask |= kMdiClientGeometry;
01065
01066 if (frame->GetMinUserPlacement()) {
01067 Int_t mh = th + 2 * bw;
01068 Int_t mw = kMinimizedWidth * mh;
01069
01070 geom.fIcon = TGRectangle(frame->GetMinimizedX(),
01071 frame->GetMinimizedY(),
01072 (unsigned) mw,
01073 (unsigned) mh);
01074 geom.fValueMask |= kMdiIconGeometry;
01075 }
01076
01077 }
01078
01079 return geom;
01080 }
01081
01082
01083 void TGMdiMainFrame::ConfigureWindow(TGMdiFrame *f, TGMdiGeometry &geom)
01084 {
01085
01086
01087 TGMdiDecorFrame *frame = GetDecorFrame(f);
01088 if (frame) {
01089 if (geom.fValueMask & kMdiDecorGeometry) {
01090 if (frame->IsMinimized() || frame->IsMaximized()) {
01091 frame->SetPreResizeX(geom.fDecoration.fX);
01092 frame->SetPreResizeY(geom.fDecoration.fY);
01093 frame->SetPreResizeWidth(geom.fDecoration.fW);
01094 frame->SetPreResizeHeight(geom.fDecoration.fH);
01095 } else {
01096 frame->MoveResize(geom.fDecoration.fX, geom.fDecoration.fY,
01097 geom.fDecoration.fW, geom.fDecoration.fH);
01098 }
01099 } else if (geom.fValueMask & kMdiClientGeometry) {
01100
01101 }
01102 if (geom.fValueMask & kMdiIconGeometry) {
01103 frame->SetMinimizedX(geom.fIcon.fX);
01104 frame->SetMinimizedY(geom.fIcon.fY);
01105 frame->SetMinUserPlacement();
01106 if (frame->IsMinimized())
01107 frame->Move(frame->GetMinimizedX(), frame->GetMinimizedY());
01108 }
01109 Layout();
01110 }
01111 }
01112
01113
01114 void TGMdiMainFrame::CloseAll()
01115 {
01116
01117
01118 TGMdiFrameList *tmp, *travel = fChildren;
01119
01120 while (travel) {
01121 tmp = travel->GetNext();
01122 SetCurrent(travel);
01123 Close(GetCurrent());
01124 travel = tmp;
01125 }
01126 }
01127
01128
01129 Bool_t TGMdiMainFrame::IsMaximized(TGMdiFrame *f)
01130 {
01131
01132
01133 TGMdiDecorFrame *frame = GetDecorFrame(f);
01134 if (frame) return frame->IsMaximized();
01135 return kFALSE;
01136 }
01137
01138
01139 Bool_t TGMdiMainFrame::IsMinimized(TGMdiFrame *f)
01140 {
01141
01142
01143 TGMdiDecorFrame *frame = GetDecorFrame(f);
01144 if (frame) return frame->IsMinimized();
01145 return kFALSE;
01146 }
01147
01148
01149 TGMdiContainer::TGMdiContainer(const TGMdiMainFrame *p, Int_t w, Int_t h,
01150 UInt_t options, ULong_t back) :
01151 TGFrame(p->GetViewPort(), w, h, options, back)
01152 {
01153
01154
01155 fMain = p;
01156 AddInput(kStructureNotifyMask);
01157 }
01158
01159
01160 TGDimension TGMdiContainer::GetDefaultSize() const
01161 {
01162
01163
01164 TGRectangle rect = fMain->GetBBox();
01165
01166 Int_t xpos = -fMain->GetViewPort()->GetHPos() - rect.LeftTop().fX;
01167 Int_t ypos = -fMain->GetViewPort()->GetVPos() - rect.LeftTop().fY;
01168
01169 return TGDimension(TMath::Max(Int_t(xpos + fWidth), rect.RightBottom().fX + 1),
01170 TMath::Max(Int_t(ypos + fHeight), rect.RightBottom().fY + 1));
01171 }
01172
01173
01174 Bool_t TGMdiContainer::HandleConfigureNotify(Event_t *event)
01175 {
01176
01177
01178 if (event->fWindow != fId) {
01179 TGRectangle rect = fMain->GetBBox();
01180
01181 Int_t vw = fMain->GetViewPort()->GetWidth();
01182 Int_t vh = fMain->GetViewPort()->GetHeight();
01183
01184 Int_t w = TMath::Max(vw, rect.RightBottom().fX + 1);
01185 Int_t h = TMath::Max(vh, rect.RightBottom().fY + 1);
01186
01187 if ((w != (Int_t)fWidth) || (h != (Int_t)fHeight)) {
01188 ((TGMdiMainFrame*)fMain)->Layout();
01189 return kTRUE;
01190 }
01191 }
01192 return kFALSE;
01193 }
01194
01195
01196 void TGMdiMainFrame::SavePrimitive(ostream &out, Option_t *option )
01197 {
01198
01199
01200 if (fBackground != GetDefaultFrameBackground()) SaveUserColor(out, option);
01201
01202 out << endl << " // MDI main frame" << endl;
01203 out << " TGMdiMainFrame *";
01204 out << GetName() << " = new TGMdiMainFrame(" << fParent->GetName()
01205 << "," << GetMenu()->GetName() << "," << GetWidth() << "," << GetHeight();
01206
01207 if (fBackground == GetDefaultFrameBackground()) {
01208 if (!GetOptions()) {
01209 out << ");" << endl;
01210 } else {
01211 out << "," << GetOptionString() <<");" << endl;
01212 }
01213 } else {
01214 out << "," << GetOptionString() << ",ucolor);" << endl;
01215 }
01216 if (option && strstr(option, "keep_names"))
01217 out << " " << GetName() << "->SetName(\"" << GetName() << "\");" << endl;
01218
01219 TGMdiFrameList *travel=fChildren;
01220 travel->SetCycleNext(travel);
01221 for (travel = fChildren; travel; travel = travel->GetNext()) {
01222 TGMdiFrame *mf = travel->GetDecorFrame()->GetMdiFrame();
01223 if (mf) mf->SavePrimitive(out, option);
01224 }
01225 if (fArrangementMode) {
01226 out << " " << GetName() << "->ArrangeFrames(";
01227 switch (fArrangementMode) {
01228
01229 case kMdiTileHorizontal:
01230 out << "kMdiTileHorizontal);" << endl;
01231 break;
01232
01233 case kMdiTileVertical:
01234 out << "kMdiTileVertical);" << endl;
01235 break;
01236
01237 case kMdiCascade:
01238 out << "kMdiCascade);" << endl;
01239 break;
01240 }
01241 }
01242 if (fResizeMode != kMdiOpaque)
01243 out << " " << GetName() << "->SetResizeMode(kMdiNonOpaque);" << endl;
01244
01245 if (fCurrent)
01246 out << " " << GetName() << "->SetCurrent(" << GetCurrent()->GetName()
01247 << ");" << endl;
01248 }
01249
01250