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
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063 #include "TGMenu.h"
00064 #include "TGResourcePool.h"
00065 #include "TTimer.h"
00066 #include "TMath.h"
00067 #include "TSystem.h"
00068 #include "TList.h"
00069 #include "Riostream.h"
00070 #include "KeySymbols.h"
00071 #include "TGButton.h"
00072 #include "TQConnection.h"
00073 #include "TParameter.h"
00074
00075 const TGGC *TGPopupMenu::fgDefaultGC = 0;
00076 const TGGC *TGPopupMenu::fgDefaultSelectedGC = 0;
00077 const TGGC *TGPopupMenu::fgDefaultSelectedBackgroundGC = 0;
00078 const TGFont *TGPopupMenu::fgDefaultFont = 0;
00079 const TGFont *TGPopupMenu::fgHilightFont = 0;
00080
00081 const TGGC *TGMenuTitle::fgDefaultGC = 0;
00082 const TGGC *TGMenuTitle::fgDefaultSelectedGC = 0;
00083 const TGFont *TGMenuTitle::fgDefaultFont = 0;
00084
00085
00086 ClassImp(TGMenuBar)
00087 ClassImp(TGMenuTitle)
00088 ClassImpQ(TGPopupMenu)
00089
00090
00091
00092 class TPopupDelayTimer : public TTimer {
00093 private:
00094 TGPopupMenu *fPopup;
00095 public:
00096 TPopupDelayTimer(TGPopupMenu *p, Long_t ms) : TTimer(ms, kTRUE) { fPopup = p; }
00097 Bool_t Notify();
00098 };
00099
00100
00101 Bool_t TPopupDelayTimer::Notify()
00102 {
00103
00104
00105 fPopup->HandleTimer(0);
00106 Reset();
00107 return kFALSE;
00108 }
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118 TGMenuBar::TGMenuBar(const TGWindow *p, UInt_t w, UInt_t h, UInt_t options)
00119 : TGHorizontalFrame(p, w, h, options | kHorizontalFrame)
00120 {
00121
00122
00123 fCurrent = 0;
00124 fTitles = new TList;
00125 fStick = kTRUE;
00126 fDefaultCursor = fClient->GetResourcePool()->GetGrabCursor();
00127 fTrash = new TList();
00128
00129 gVirtualX->GrabButton(fId, kButton1, kAnyModifier,
00130 kButtonPressMask | kButtonReleaseMask | kEnterWindowMask,
00131 kNone, kNone);
00132
00133 fKeyNavigate = kFALSE;
00134
00135 fMenuMore = new TGPopupMenu(gClient->GetDefaultRoot());
00136 fMenuMore->AddLabel("Hidden Menus");
00137 fMenuMore->AddSeparator();
00138 fMenuBarMoreLayout = new TGLayoutHints(kLHintsTop | kLHintsRight);
00139
00140 fWithExt = kFALSE;
00141 fOutLayouts = new TList();
00142 fNeededSpace = new TList();
00143 }
00144
00145
00146 TGMenuBar::~TGMenuBar()
00147 {
00148
00149
00150
00151 TGFrameElement *el;
00152 TGMenuTitle *t;
00153 Int_t keycode;
00154
00155 if (!MustCleanup()) {
00156 fTrash->Delete();
00157 }
00158 delete fTrash;
00159
00160 const TGMainFrame *main = (TGMainFrame *)GetMainFrame();
00161
00162 if (!MustCleanup()) {
00163 TIter next(fList);
00164 while ((el = (TGFrameElement *) next())) {
00165 t = (TGMenuTitle *) el->fFrame;
00166 if ((keycode = t->GetHotKeyCode()) != 0 && main) {
00167 main->RemoveBind(this, keycode, kKeyMod1Mask);
00168 }
00169 }
00170 }
00171
00172
00173 if (fTitles && !MustCleanup()) fTitles->Delete();
00174 delete fTitles;
00175
00176 delete fOutLayouts;
00177 fNeededSpace->Delete();
00178 delete fNeededSpace;
00179 delete fMenuMore;
00180 delete fMenuBarMoreLayout;
00181 }
00182
00183
00184 void TGMenuBar::Layout()
00185 {
00186
00187
00188
00189 if (GetDefaultWidth() > GetWidth()) {
00190 while (!(GetDefaultWidth() < GetWidth() ||
00191 GetList()->GetSize() <= 1)) {
00192 TGFrameElement* entry = GetLastOnLeft();
00193 TGMenuTitle* menuTitle = (TGMenuTitle*) entry->fFrame;
00194 fNeededSpace->AddLast(new TParameter<Int_t>("", menuTitle->GetWidth() +
00195 entry->fLayout->GetPadLeft() +
00196 entry->fLayout->GetPadRight() ) );
00197 fOutLayouts->AddLast( entry->fLayout );
00198 fMenuMore->AddPopup( menuTitle->GetName(), menuTitle->GetMenu() );
00199 menuTitle->GetMenu()->Connect("PoppedUp()", "TGMenuBar", this, "PopupConnection()");
00200 RemovePopup( menuTitle->GetName() );
00201 }
00202 }
00203
00204 if (fNeededSpace->GetSize() > 0) {
00205 Int_t neededWidth = ((TParameter<Int_t>*) fNeededSpace->Last())->GetVal();
00206 Bool_t fit = kFALSE;
00207 if (fNeededSpace->GetSize() > 1)
00208 fit = GetDefaultWidth() + neededWidth + 5 < GetWidth();
00209 else
00210 fit = GetDefaultWidth() + neededWidth - 7 < GetWidth();
00211 while (fit) {
00212 TGMenuEntry* menu = (TGMenuEntry*) fMenuMore->GetListOfEntries()->Last();
00213 TGLayoutHints* layout = (TGLayoutHints*) fOutLayouts->Last();
00214 ULong_t hints = layout->GetLayoutHints();
00215 TGPopupMenu* beforeMenu = 0;
00216 if (hints & kLHintsRight) {
00217 TGFrameElement* entry = GetLastOnLeft();
00218 TGMenuTitle* beforeMenuTitle = (TGMenuTitle*) entry->fFrame;
00219 beforeMenu = beforeMenuTitle->GetMenu();
00220 }
00221
00222 menu->GetPopup()->Disconnect("PoppedUp()", this, "PopupConnection()");
00223 AddPopup( menu->GetName(), menu->GetPopup(), layout, beforeMenu );
00224 fOutLayouts->Remove( fOutLayouts->Last() );
00225 fNeededSpace->Remove( fNeededSpace->Last() );
00226 fMenuMore->DeleteEntry(menu);
00227
00228 if (fNeededSpace->GetSize() > 0) {
00229 neededWidth = ((TParameter<Int_t>*)fNeededSpace->Last())->GetVal();
00230 if (fNeededSpace->GetSize() > 1)
00231 fit = GetDefaultWidth() + neededWidth + 5 < GetWidth();
00232 else
00233 fit = GetDefaultWidth() + neededWidth - 7 < GetWidth();
00234 } else
00235 fit = kFALSE;
00236 }
00237 }
00238
00239 if (fNeededSpace->GetSize() > 0) {
00240 if (!fWithExt) {
00241 AddPopup(">>", fMenuMore, fMenuBarMoreLayout,
00242 ((TGMenuTitle*)((TGFrameElement*)GetList()->First())->fFrame)->GetMenu());
00243 fWithExt = kTRUE;
00244 }
00245 } else {
00246 RemovePopup(">>");
00247 fWithExt = kFALSE;
00248 }
00249
00250 MapSubwindows();
00251 TGHorizontalFrame::Layout();
00252 }
00253
00254
00255 TGFrameElement* TGMenuBar::GetLastOnLeft()
00256 {
00257
00258
00259
00260 TIter next(GetList());
00261 while (TGFrameElement *entry = (TGFrameElement*) next()) {
00262
00263 TGMenuTitle* menuTitle = (TGMenuTitle*) entry->fFrame;
00264 TGLayoutHints* tmpLayout = (TGLayoutHints*) entry->fLayout;
00265 ULong_t hints = tmpLayout->GetLayoutHints();
00266
00267 if (hints & kLHintsRight && menuTitle->GetMenu() != fMenuMore) {
00268 return entry;
00269 }
00270 }
00271
00272 return ((TGFrameElement*)GetList()->Last());
00273 }
00274
00275
00276 void TGMenuBar::PopupConnection()
00277 {
00278
00279
00280
00281
00282 TList* slots = fMenuMore->GetListOfSignals();
00283 TIter next (slots);
00284 while (TList* connlist = (TList*) next()) {
00285
00286 const char* signal_name = connlist->GetName();
00287 TIter next2(connlist);
00288 while (TQConnection* conn = (TQConnection*) next2()) {
00289 const char* slot_name = conn->GetName();
00290 void* receiver = conn->GetReceiver();
00291 fMenuMore->Disconnect(signal_name, receiver, slot_name);
00292 }
00293 }
00294 fMenuMore->fMsgWindow = 0;
00295
00296
00297 TGMenuEntry* currentEntry = fMenuMore->GetCurrent();
00298 if (currentEntry->GetType() != kMenuPopup) return;
00299
00300
00301 TGPopupMenu* currentMenu = currentEntry->GetPopup();
00302
00303 slots = currentMenu->GetListOfSignals();
00304 TIter next3 (slots);
00305 while (TList* connlist = (TList*) next3()) {
00306
00307 const char* signal_name = connlist->GetName();
00308 if (strcmp(signal_name, "Activated(int)") == 0) {
00309 TIter next2(connlist);
00310 while (TQConnection* conn = (TQConnection*) next2()) {
00311
00312 const char* slot_name = conn->GetName();
00313 const char* class_name = conn->GetClassName();
00314 void* receiver = conn->GetReceiver();
00315 fMenuMore->Connect(signal_name, class_name, receiver, slot_name);
00316 }
00317 }
00318 }
00319
00320 fMenuMore->fMsgWindow = currentMenu->fMsgWindow;
00321 }
00322
00323
00324 void TGMenuBar::BindKeys(Bool_t on)
00325 {
00326
00327
00328
00329 gVirtualX->GrabKey(fId, gVirtualX->KeysymToKeycode(kKey_Left), kAnyModifier, on);
00330 gVirtualX->GrabKey(fId, gVirtualX->KeysymToKeycode(kKey_Right), kAnyModifier, on);
00331 gVirtualX->GrabKey(fId, gVirtualX->KeysymToKeycode(kKey_Up), kAnyModifier, on);
00332 gVirtualX->GrabKey(fId, gVirtualX->KeysymToKeycode(kKey_Down), kAnyModifier, on);
00333 gVirtualX->GrabKey(fId, gVirtualX->KeysymToKeycode(kKey_Enter), kAnyModifier, on);
00334 gVirtualX->GrabKey(fId, gVirtualX->KeysymToKeycode(kKey_Return), kAnyModifier, on);
00335 gVirtualX->GrabKey(fId, gVirtualX->KeysymToKeycode(kKey_Escape), kAnyModifier, on);
00336
00337 if (fCurrent && fCurrent->GetMenu()) {
00338 BindMenu(fCurrent->GetMenu(), on);
00339 }
00340 }
00341
00342
00343 void TGMenuBar::BindMenu(TGPopupMenu* subMenu, Bool_t on)
00344 {
00345
00346
00347 TGMenuEntry *e;
00348 TIter next(subMenu->GetListOfEntries());
00349
00350 while ((e = (TGMenuEntry*)next())) {
00351 Int_t hot = 0;
00352 if ( e->GetType() == kMenuPopup )
00353 BindMenu(e->GetPopup(), on);
00354 if (e->GetLabel()) {
00355 hot = e->GetLabel()->GetHotChar();
00356 }
00357 if (!hot) continue;
00358 gVirtualX->GrabKey(fId, gVirtualX->KeysymToKeycode(hot), 0, on);
00359 gVirtualX->GrabKey(fId, gVirtualX->KeysymToKeycode(hot), kKeyShiftMask, on);
00360 gVirtualX->GrabKey(fId, gVirtualX->KeysymToKeycode(hot), kKeyLockMask, on);
00361 gVirtualX->GrabKey(fId, gVirtualX->KeysymToKeycode(hot), kKeyMod2Mask, on);
00362 gVirtualX->GrabKey(fId, gVirtualX->KeysymToKeycode(hot), kKeyShiftMask | kKeyLockMask, on);
00363 gVirtualX->GrabKey(fId, gVirtualX->KeysymToKeycode(hot), kKeyShiftMask | kKeyMod2Mask, on);
00364 gVirtualX->GrabKey(fId, gVirtualX->KeysymToKeycode(hot), kKeyLockMask | kKeyMod2Mask, on);
00365 gVirtualX->GrabKey(fId, gVirtualX->KeysymToKeycode(hot), kKeyShiftMask | kKeyLockMask | kKeyMod2Mask, on);
00366 }
00367 }
00368
00369
00370
00371 void TGMenuBar::BindHotKey(Int_t keycode, Bool_t on)
00372 {
00373
00374
00375 const TGMainFrame *main = (TGMainFrame *) GetMainFrame();
00376
00377 if (!main || !main->InheritsFrom("TGMainFrame")) return;
00378
00379 if (on) {
00380
00381 main->BindKey(this, keycode, kKeyMod1Mask);
00382 main->BindKey(this, keycode, kKeyMod1Mask | kKeyShiftMask);
00383 main->BindKey(this, keycode, kKeyMod1Mask | kKeyLockMask);
00384 main->BindKey(this, keycode, kKeyMod1Mask | kKeyShiftMask | kKeyLockMask);
00385
00386 main->BindKey(this, keycode, kKeyMod1Mask | kKeyMod2Mask);
00387 main->BindKey(this, keycode, kKeyMod1Mask | kKeyShiftMask | kKeyMod2Mask);
00388 main->BindKey(this, keycode, kKeyMod1Mask | kKeyMod2Mask | kKeyLockMask);
00389 main->BindKey(this, keycode, kKeyMod1Mask | kKeyShiftMask | kKeyMod2Mask | kKeyLockMask);
00390 } else {
00391 main->RemoveBind(this, keycode, kKeyMod1Mask);
00392 main->RemoveBind(this, keycode, kKeyMod1Mask | kKeyShiftMask);
00393 main->RemoveBind(this, keycode, kKeyMod1Mask | kKeyLockMask);
00394 main->RemoveBind(this, keycode, kKeyMod1Mask | kKeyShiftMask | kKeyLockMask);
00395
00396 main->RemoveBind(this, keycode, kKeyMod1Mask | kKeyMod2Mask);
00397 main->RemoveBind(this, keycode, kKeyMod1Mask | kKeyShiftMask | kKeyMod2Mask);
00398 main->RemoveBind(this, keycode, kKeyMod1Mask | kKeyMod2Mask | kKeyLockMask);
00399 main->RemoveBind(this, keycode, kKeyMod1Mask | kKeyShiftMask | kKeyMod2Mask | kKeyLockMask);
00400 }
00401 }
00402
00403
00404 void TGMenuBar::AddPopup(TGHotString *s, TGPopupMenu *menu, TGLayoutHints *l,
00405 TGPopupMenu *before)
00406 {
00407
00408
00409
00410
00411 TGMenuTitle *t;
00412 Int_t keycode;
00413
00414 AddFrameBefore(t = new TGMenuTitle(this, s, menu), l, before);
00415 fTitles->Add(t);
00416
00417 if ((keycode = t->GetHotKeyCode()) != 0) {
00418 BindHotKey(keycode, kTRUE);
00419 }
00420 }
00421
00422
00423 void TGMenuBar::AddTitle(TGMenuTitle *title, TGLayoutHints *l, TGPopupMenu *before)
00424 {
00425
00426
00427 Int_t keycode;
00428
00429 AddFrameBefore(title, l, before);
00430 fTitles->Add(title);
00431
00432 if ((keycode = title->GetHotKeyCode()) != 0) {
00433 BindHotKey(keycode, kTRUE);
00434 }
00435 }
00436
00437
00438 void TGMenuBar::AddPopup(const char *s, TGPopupMenu *menu, TGLayoutHints *l,
00439 TGPopupMenu *before)
00440 {
00441
00442
00443
00444 AddPopup(new TGHotString(s), menu, l, before);
00445 }
00446
00447
00448 TGPopupMenu *TGMenuBar::AddPopup(const TString &s, Int_t padleft, Int_t padright,
00449 Int_t padtop, Int_t padbottom)
00450 {
00451
00452
00453
00454
00455
00456
00457
00458
00459
00460
00461
00462
00463
00464
00465
00466
00467
00468
00469
00470 ULong_t hints = kLHintsTop;
00471
00472 if (padleft) {
00473 hints |= kLHintsLeft;
00474 } else {
00475 hints |= kLHintsRight;
00476 }
00477
00478 TGLayoutHints *l = new TGLayoutHints(hints, padleft, padright,
00479 padtop, padbottom);
00480 fTrash->Add(l);
00481
00482 TGPopupMenu *menu = new TGPopupMenu(fClient->GetDefaultRoot());
00483 AddPopup(new TGHotString(s), menu, l, 0);
00484 fTrash->Add(menu);
00485 return menu;
00486 }
00487
00488
00489 void TGMenuBar::AddFrameBefore(TGFrame *f, TGLayoutHints *l,
00490 TGPopupMenu *before)
00491 {
00492
00493
00494
00495
00496 if (!f->InheritsFrom("TGMenuTitle")) {
00497 Error("AddFrameBefore", "may only add TGMenuTitle objects to a menu bar");
00498 return;
00499 }
00500
00501 if (!before) {
00502 AddFrame(f, l);
00503 return;
00504 }
00505
00506 TGFrameElement *nw;
00507
00508 nw = new TGFrameElement;
00509 nw->fFrame = f;
00510 nw->fLayout = l ? l : fgDefaultHints;
00511 nw->fState = 1;
00512
00513 TGFrameElement *el;
00514 TIter next(fList);
00515 while ((el = (TGFrameElement *) next())) {
00516 TGMenuTitle *t = (TGMenuTitle *) el->fFrame;
00517 if (t->GetMenu() == before) {
00518 fList->AddBefore(el, nw);
00519 return;
00520 }
00521 }
00522 fList->Add(nw);
00523 }
00524
00525
00526 TGPopupMenu *TGMenuBar::GetPopup(const char *s)
00527 {
00528
00529
00530
00531
00532 if (!GetList()) return 0;
00533
00534 TGFrameElement *el;
00535 TIter next(GetList());
00536 TString str = s;
00537
00538 while ((el = (TGFrameElement *) next())) {
00539 TGMenuTitle *t = (TGMenuTitle *) el->fFrame;
00540 if (str == t->GetName())
00541 return t->GetMenu();
00542 }
00543 return 0;
00544 }
00545
00546
00547 TGPopupMenu *TGMenuBar::RemovePopup(const char *s)
00548 {
00549
00550
00551
00552
00553 if (!GetList()) return 0;
00554
00555 TGFrameElement *el;
00556 TIter next(GetList());
00557 TString str = s;
00558
00559 while ((el = (TGFrameElement *) next())) {
00560 TGMenuTitle *t = (TGMenuTitle *) el->fFrame;
00561 if (str == t->GetName()) {
00562 Int_t keycode;
00563 if ((keycode = t->GetHotKeyCode())) {
00564 BindHotKey(keycode, kFALSE);
00565 }
00566 TGPopupMenu *m = t->GetMenu();
00567 fTitles->Remove(t);
00568 t->DestroyWindow();
00569 RemoveFrame(t);
00570 delete t;
00571 return m;
00572 }
00573 }
00574 return 0;
00575 }
00576
00577
00578 Bool_t TGMenuBar::HandleMotion(Event_t *event)
00579 {
00580
00581
00582 if (fKeyNavigate) return kTRUE;
00583
00584 Int_t dummy;
00585 Window_t wtarget;
00586 TGMenuTitle *target = 0;
00587
00588 if (!(event->fState & kButton1Mask))
00589 fStick = kFALSE;
00590
00591 gVirtualX->TranslateCoordinates(fId, fId, event->fX, event->fY,
00592 dummy, dummy, wtarget);
00593 if (wtarget) target = (TGMenuTitle*) fClient->GetWindowById(wtarget);
00594
00595 if (fCurrent && target && (target != fCurrent)) {
00596
00597 TGFrameElement *el;
00598 TIter next(fList);
00599 while ((el = (TGFrameElement *) next()))
00600 ((TGMenuTitle*)el->fFrame)->SetState(kFALSE);
00601
00602 fStick = kTRUE;
00603 fCurrent = target;
00604 target->SetState(kTRUE);
00605 }
00606
00607 return kTRUE;
00608 }
00609
00610
00611 Bool_t TGMenuBar::HandleButton(Event_t *event)
00612 {
00613
00614
00615 Int_t dummy;
00616 Window_t wtarget;
00617 TGMenuTitle *target;
00618
00619
00620
00621
00622 if (event->fType == kButtonPress) {
00623
00624 gVirtualX->TranslateCoordinates(fId, fId, event->fX, event->fY,
00625 dummy, dummy, wtarget);
00626 target = (TGMenuTitle*) fClient->GetWindowById(wtarget);
00627
00628 if (target != 0) {
00629 fStick = kTRUE;
00630
00631 if (target != fCurrent) {
00632
00633 TGFrameElement *el;
00634 TIter next(fList);
00635 while ((el = (TGFrameElement *) next()))
00636 ((TGMenuTitle*)el->fFrame)->SetState(kFALSE);
00637
00638 fStick = kTRUE;
00639 fCurrent = target;
00640 target->SetState(kTRUE);
00641
00642 gVirtualX->GrabPointer(fId, kButtonPressMask | kButtonReleaseMask |
00643 kPointerMotionMask, kNone, fDefaultCursor);
00644 }
00645 }
00646 }
00647
00648 if (event->fType == kButtonRelease) {
00649 if (fStick) {
00650 fStick = kFALSE;
00651 return kTRUE;
00652 }
00653
00654 TGFrameElement *el;
00655 TIter next(fList);
00656 while ((el = (TGFrameElement *) next()))
00657 ((TGMenuTitle*)el->fFrame)->SetState(kFALSE);
00658
00659 gVirtualX->GrabPointer(0, 0, 0, 0, kFALSE);
00660
00661 if (fCurrent != 0) {
00662 target = fCurrent;
00663 fCurrent = 0;
00664 if (!fKeyNavigate)
00665 target->DoSendMessage();
00666 }
00667 fKeyNavigate = kFALSE;
00668 }
00669
00670 return kTRUE;
00671 }
00672
00673
00674 Bool_t TGMenuBar::HandleKey(Event_t *event)
00675 {
00676
00677
00678 TGMenuTitle *target = 0;
00679 TGFrameElement *el;
00680 void *dummy;
00681 Int_t ax, ay;
00682 Window_t wdummy;
00683 TIter next(fList);
00684
00685 if (event->fType == kGKeyPress) {
00686 UInt_t keysym;
00687 char tmp[2];
00688
00689 gVirtualX->LookupString(event, tmp, sizeof(tmp), keysym);
00690
00691 if (event->fState & kKeyMod1Mask) {
00692 while ((el = (TGFrameElement *) next())) {
00693 target = (TGMenuTitle *) el->fFrame;
00694 if ((Int_t)event->fCode == target->GetHotKeyCode()) {
00695 RequestFocus();
00696 fKeyNavigate = kTRUE;
00697 break;
00698 }
00699 }
00700 if (el == 0) target = 0;
00701 } else {
00702 fKeyNavigate = kTRUE;
00703
00704 if (fCurrent) {
00705 TGFrameElement *cur = 0;
00706 TGPopupMenu *menu = 0;
00707 next.Reset();
00708 el = 0;
00709 while ((el = (TGFrameElement *) next())) {
00710 if (el->fFrame == fCurrent) {
00711 cur = el;
00712 menu = ((TGMenuTitle*)el->fFrame)->GetMenu();
00713 break;
00714 }
00715 }
00716
00717 if (!menu || !menu->fPoppedUp) return kFALSE;
00718
00719 TGMenuEntry *ce = 0;
00720
00721 TGPopupMenu* currentMenu = fCurrent->GetMenu();
00722 TGMenuEntry* currentEntry = currentMenu->GetCurrent();
00723 while ( currentEntry ) {
00724 if ( currentEntry->GetType() == kMenuPopup )
00725 currentMenu = currentEntry->GetPopup();
00726 if ( currentEntry != currentMenu->GetCurrent() )
00727 currentEntry = currentMenu->GetCurrent();
00728 else
00729 currentEntry = 0;
00730 }
00731
00732 TIter next2(currentMenu->GetListOfEntries());
00733
00734 while ((ce = (TGMenuEntry*)next2())) {
00735 UInt_t hot = 0;
00736 if (ce->GetLabel()) hot = ce->GetLabel()->GetHotChar();
00737 if (!hot || (hot != keysym)) continue;
00738
00739 currentMenu->Activate(ce);
00740 if (ce->GetType() != kMenuPopup) {
00741 gVirtualX->GrabPointer(0, 0, 0, 0, kFALSE);
00742 fCurrent->SetState(kFALSE);
00743 currentMenu->fStick = kFALSE;
00744 Event_t ev;
00745 ev.fType = kButtonRelease;
00746 ev.fWindow = currentMenu->GetId();
00747 fCurrent = 0;
00748 return currentMenu->HandleButton(&ev);
00749 }
00750 else {
00751 gVirtualX->TranslateCoordinates(currentMenu->fId,
00752 (ce->fPopup->GetParent())->GetId(),
00753 ce->fEx+currentMenu->fMenuWidth, ce->fEy,
00754 ax, ay, wdummy);
00755 ce->fPopup->PlaceMenu(ax-5, ay-1, kFALSE, kFALSE);
00756 }
00757 }
00758
00759 ce = menu->GetCurrent();
00760 TGPopupMenu *submenu = 0;
00761
00762 while (ce && (ce->GetType() == kMenuPopup)) {
00763 submenu = ce->GetPopup();
00764 if (!submenu->fPoppedUp) break;
00765 ce = submenu->GetCurrent();
00766 menu = submenu;
00767 }
00768 switch ((EKeySym)keysym) {
00769 case kKey_Left:
00770 if ((submenu) && (submenu->fPoppedUp)) {
00771 submenu->EndMenu(dummy);
00772 break;
00773 }
00774 el = (TGFrameElement*)fList->Before(cur);
00775 if (!el) el = (TGFrameElement*)fList->Last();
00776 break;
00777 case kKey_Right:
00778 if (submenu) {
00779 if (submenu->fPoppedUp) {
00780 if (!submenu->GetCurrent()) {
00781 ce = (TGMenuEntry*)submenu->GetListOfEntries()->First();
00782 } else {
00783 submenu->EndMenu(dummy);
00784 }
00785 }
00786 else {
00787 gVirtualX->TranslateCoordinates(menu->fId,
00788 (submenu->GetParent())->GetId(),
00789 ce->fEx+menu->fMenuWidth, ce->fEy,
00790 ax, ay, wdummy);
00791
00792 submenu->PlaceMenu(ax-5, ay-1, kFALSE, kFALSE);
00793 }
00794 break;
00795 }
00796 el = (TGFrameElement*)fList->After(cur);
00797 if (!el) el = (TGFrameElement*)fList->First();
00798 break;
00799 case kKey_Up:
00800 if (ce) ce = (TGMenuEntry*)menu->GetListOfEntries()->Before(ce);
00801 while (ce && ((ce->GetType() == kMenuSeparator) ||
00802 (ce->GetType() == kMenuLabel) ||
00803 !(ce->GetStatus() & kMenuEnableMask))) {
00804 ce = (TGMenuEntry*)menu->GetListOfEntries()->Before(ce);
00805 }
00806 if (!ce) ce = (TGMenuEntry*)menu->GetListOfEntries()->Last();
00807 break;
00808 case kKey_Down:
00809 if (ce) ce = (TGMenuEntry*)menu->GetListOfEntries()->After(ce);
00810 while (ce && ((ce->GetType() == kMenuSeparator) ||
00811 (ce->GetType() == kMenuLabel) ||
00812 !(ce->GetStatus() & kMenuEnableMask))) {
00813 ce = (TGMenuEntry*)menu->GetListOfEntries()->After(ce);
00814 }
00815 if (!ce) ce = (TGMenuEntry*)menu->GetListOfEntries()->First();
00816 break;
00817 case kKey_Enter:
00818 case kKey_Return: {
00819 gVirtualX->GrabPointer(0, 0, 0, 0, kFALSE);
00820 fCurrent->SetState(kFALSE);
00821 menu->fStick = kFALSE;
00822 Event_t ev;
00823 ev.fType = kButtonRelease;
00824 ev.fWindow = menu->GetId();
00825 fCurrent = 0;
00826 return menu->HandleButton(&ev);
00827 }
00828 case kKey_Escape:
00829 gVirtualX->GrabPointer(0, 0, 0, 0, kFALSE);
00830 fCurrent->SetState(kFALSE);
00831 fStick = kFALSE;
00832 fCurrent = 0;
00833 return menu->EndMenu(dummy);
00834 default:
00835 break;
00836 }
00837 if (ce) menu->Activate(ce);
00838
00839 el = el ? el : cur;
00840 if (el) target = (TGMenuTitle*)el->fFrame;
00841 } else {
00842 return kFALSE;
00843 }
00844 }
00845
00846 if (target != 0) {
00847 fStick = kTRUE;
00848
00849 if (target != fCurrent) {
00850
00851 next.Reset();
00852 while ((el = (TGFrameElement *) next()))
00853 ((TGMenuTitle*)el->fFrame)->SetState(kFALSE);
00854
00855 fCurrent = target;
00856 target->SetState(kTRUE);
00857 fStick = kTRUE;
00858
00859 gVirtualX->GrabPointer(fId, kButtonPressMask | kButtonReleaseMask |
00860 kPointerMotionMask, kNone, fDefaultCursor);
00861
00862 TGMenuEntry *ptr;
00863 TIter nexte(target->GetMenu()->GetListOfEntries());
00864
00865 while ((ptr = (TGMenuEntry *) nexte())) {
00866 if ((ptr->GetStatus() & kMenuEnableMask) &&
00867 !(ptr->GetStatus() & kMenuHideMask) &&
00868 (ptr->GetType() != kMenuSeparator) &&
00869 (ptr->GetType() != kMenuLabel)) break;
00870 }
00871 if (ptr)
00872 target->GetMenu()->Activate(ptr);
00873
00874 return kTRUE;
00875 }
00876 } else {
00877 return kFALSE;
00878 }
00879 }
00880
00881 if (event->fType == kKeyRelease) {
00882 if (fStick) {
00883 fStick = kFALSE;
00884 return kTRUE;
00885 }
00886 gVirtualX->GrabPointer(0, 0, 0, 0, kFALSE);
00887
00888 next.Reset();
00889 while ((el = (TGFrameElement *) next()))
00890 ((TGMenuTitle*)el->fFrame)->SetState(kFALSE);
00891
00892 if (fCurrent != 0) {
00893 target = fCurrent;
00894 fCurrent = 0;
00895 target->DoSendMessage();
00896 }
00897 }
00898
00899 return kTRUE;
00900 }
00901
00902
00903
00904
00905
00906
00907
00908
00909
00910 TGPopupMenu::TGPopupMenu(const TGWindow *p, UInt_t w, UInt_t h, UInt_t options)
00911 : TGFrame(p, w, h, options | kOwnBackground)
00912 {
00913
00914
00915 fNormGC = GetDefaultGC()();
00916 fSelGC = GetDefaultSelectedGC()();
00917 fSelbackGC = GetDefaultSelectedBackgroundGC()();
00918 fFontStruct = GetDefaultFontStruct();
00919 fHifontStruct = GetHilightFontStruct();
00920 fDefaultCursor = fClient->GetResourcePool()->GetGrabCursor();
00921
00922
00923
00924 GCValues_t gcval;
00925 gcval.fMask = kGCFont;
00926 gcval.fFont = gVirtualX->GetFontHandle(fFontStruct);
00927 gVirtualX->ChangeGC(fNormGC, &gcval);
00928 gVirtualX->ChangeGC(fSelGC, &gcval);
00929
00930 fDelay = 0;
00931 fEntryList = new TList;
00932
00933
00934 fBorderWidth = 3;
00935 fMenuHeight = 6;
00936 fMenuWidth = 8;
00937 fXl = 16;
00938 fMsgWindow = p;
00939 fStick = kTRUE;
00940 fCurrent = 0;
00941 fHasGrab = kFALSE;
00942 fPoppedUp = kFALSE;
00943 fMenuBar = 0;
00944 fSplitButton = 0;
00945 fEntrySep = 3;
00946
00947 SetWindowAttributes_t wattr;
00948 wattr.fMask = kWAOverrideRedirect | kWASaveUnder;
00949 wattr.fOverrideRedirect = kTRUE;
00950 wattr.fSaveUnder = kTRUE;
00951
00952 gVirtualX->ChangeWindowAttributes(fId, &wattr);
00953
00954 AddInput(kPointerMotionMask | kEnterWindowMask | kLeaveWindowMask);
00955 }
00956
00957
00958 TGPopupMenu::~TGPopupMenu()
00959 {
00960
00961
00962 if (fEntryList) fEntryList->Delete();
00963 delete fEntryList;
00964 delete fDelay;
00965 }
00966
00967
00968 void TGPopupMenu::AddEntry(TGHotString *s, Int_t id, void *ud,
00969 const TGPicture *p, TGMenuEntry *before)
00970 {
00971
00972
00973
00974
00975
00976 if (!s) return;
00977 TGMenuEntry *nw = new TGMenuEntry;
00978 Ssiz_t tab = s->Index('\t');
00979 if (tab > 0) {
00980 TString ts(s->Data());
00981 TString shortcut = ts(tab+1, s->Length());
00982 nw->fShortcut = new TGString(shortcut.Data());
00983 nw->fLabel = new TGHotString(*s);
00984 nw->fLabel->Remove(tab);
00985 }
00986 else {
00987 nw->fLabel = s;
00988 }
00989 nw->fPic = p;
00990 nw->fType = kMenuEntry;
00991 nw->fEntryId = id;
00992 nw->fUserData = ud;
00993 nw->fPopup = 0;
00994 nw->fStatus = kMenuEnableMask;
00995 nw->fEx = 2;
00996 nw->fEy = fMenuHeight-2;
00997
00998 if (before)
00999 fEntryList->AddBefore(before, nw);
01000 else
01001 fEntryList->Add(nw);
01002
01003 UInt_t tw, ph = 0, pw = 0;
01004 tw = gVirtualX->TextWidth(fHifontStruct, s->GetString(), s->GetLength());
01005 if (p) {
01006 ph = p->GetHeight();
01007 pw = p->GetWidth();
01008 if (pw+12 > fXl) { fMenuWidth += pw+12-fXl; fXl = pw+12; }
01009 }
01010 if (nw->fShortcut) {
01011 tw += 10;
01012 delete s;
01013 }
01014
01015 Int_t max_ascent, max_descent;
01016 nw->fEw = tw + pw +18+12;
01017 fMenuWidth = TMath::Max(fMenuWidth, nw->fEw);
01018 gVirtualX->GetFontProperties(fHifontStruct, max_ascent, max_descent);
01019 nw->fEh = max_ascent + max_descent + fEntrySep;
01020 if (nw->fEh < ph+fEntrySep) nw->fEh = ph+fEntrySep;
01021 fMenuHeight += nw->fEh;
01022
01023 if (before)
01024 Reposition();
01025 else
01026 Resize(fMenuWidth, fMenuHeight);
01027 }
01028
01029
01030 void TGPopupMenu::AddEntry(const char *s, Int_t id, void *ud,
01031 const TGPicture *p, TGMenuEntry *before)
01032 {
01033
01034
01035
01036 AddEntry(new TGHotString(s), id, ud, p, before);
01037 }
01038
01039
01040 void TGPopupMenu::AddSeparator(TGMenuEntry *before)
01041 {
01042
01043
01044
01045 TGMenuEntry *nw = new TGMenuEntry;
01046
01047 nw->fLabel = 0;
01048 nw->fPic = 0;
01049 nw->fType = kMenuSeparator;
01050 nw->fEntryId = -1;
01051 nw->fUserData = 0;
01052 nw->fPopup = 0;
01053 nw->fStatus = kMenuEnableMask;
01054 nw->fEx = 2;
01055 nw->fEy = fMenuHeight-2;
01056
01057 if (before)
01058 fEntryList->AddBefore(before, nw);
01059 else
01060 fEntryList->Add(nw);
01061
01062 nw->fEw = 0;
01063 nw->fEh = 4;
01064 fMenuHeight += nw->fEh;
01065
01066 if (before)
01067 Reposition();
01068 else
01069 Resize(fMenuWidth, fMenuHeight);
01070 }
01071
01072
01073 void TGPopupMenu::AddLabel(TGHotString *s, const TGPicture *p,
01074 TGMenuEntry *before)
01075 {
01076
01077
01078
01079
01080
01081 TGMenuEntry *nw = new TGMenuEntry;
01082
01083 nw->fLabel = s;
01084 nw->fPic = p;
01085 nw->fType = kMenuLabel;
01086 nw->fEntryId = -1;
01087 nw->fUserData = 0;
01088 nw->fPopup = 0;
01089 nw->fStatus = kMenuEnableMask | kMenuDefaultMask;
01090 nw->fEx = 2;
01091 nw->fEy = fMenuHeight-2;
01092
01093 if (before)
01094 fEntryList->AddBefore(before, nw);
01095 else
01096 fEntryList->Add(nw);
01097
01098 UInt_t tw, ph = 0, pw = 0;
01099 tw = gVirtualX->TextWidth(fHifontStruct, s->GetString(), s->GetLength());
01100 if (p) {
01101 ph = p->GetHeight();
01102 pw = p->GetWidth();
01103 if (pw+12 > fXl) { fMenuWidth += pw+12-fXl; fXl = pw+12; }
01104 }
01105
01106 Int_t max_ascent, max_descent;
01107 nw->fEw = tw + pw +18+12;
01108 fMenuWidth = TMath::Max(fMenuWidth, nw->fEw);
01109 gVirtualX->GetFontProperties(fHifontStruct, max_ascent, max_descent);
01110 nw->fEh = max_ascent + max_descent + fEntrySep;
01111 if (nw->fEh < ph+fEntrySep) nw->fEh = ph+fEntrySep;
01112 fMenuHeight += nw->fEh;
01113
01114 if (before)
01115 Reposition();
01116 else
01117 Resize(fMenuWidth, fMenuHeight);
01118 }
01119
01120
01121 void TGPopupMenu::AddLabel(const char *s, const TGPicture *p,
01122 TGMenuEntry *before)
01123 {
01124
01125
01126
01127 AddLabel(new TGHotString(s), p, before);
01128 }
01129
01130
01131 void TGPopupMenu::AddPopup(TGHotString *s, TGPopupMenu *popup,
01132 TGMenuEntry *before, const TGPicture *p)
01133 {
01134
01135
01136
01137
01138 TGMenuEntry *nw = new TGMenuEntry;
01139
01140 nw->fLabel = s;
01141 nw->fPic = p;
01142 nw->fType = kMenuPopup;
01143 nw->fEntryId = -2;
01144 nw->fUserData = 0;
01145 nw->fPopup = popup;
01146 nw->fStatus = kMenuEnableMask;
01147 nw->fEx = 2;
01148 nw->fEy = fMenuHeight-2;
01149
01150 if (before)
01151 fEntryList->AddBefore(before, nw);
01152 else
01153 fEntryList->Add(nw);
01154
01155 UInt_t tw = gVirtualX->TextWidth(fHifontStruct, s->GetString(),
01156 s->GetLength());
01157
01158 UInt_t ph = 0, pw = 8;
01159 if (p) {
01160 ph = p->GetHeight();
01161 pw = p->GetWidth();
01162 if (pw+12 > fXl) { fMenuWidth += pw+12-fXl; fXl = pw+12; }
01163 }
01164 Int_t max_ascent, max_descent;
01165 nw->fEw = tw + pw+18+12;
01166 fMenuWidth = TMath::Max(fMenuWidth, nw->fEw);
01167 gVirtualX->GetFontProperties(fHifontStruct, max_ascent, max_descent);
01168 nw->fEh = max_ascent + max_descent + fEntrySep;
01169 if (nw->fEh < ph+fEntrySep) nw->fEh = ph+fEntrySep;
01170 fMenuHeight += nw->fEh;
01171
01172 if (before)
01173 Reposition();
01174 else
01175 Resize(fMenuWidth, fMenuHeight);
01176 }
01177
01178
01179 void TGPopupMenu::AddPopup(const char *s, TGPopupMenu *popup,
01180 TGMenuEntry *before, const TGPicture *p)
01181 {
01182
01183
01184
01185 AddPopup(new TGHotString(s), popup, before, p);
01186 }
01187
01188
01189 void TGPopupMenu::Reposition()
01190 {
01191
01192
01193
01194
01195 fMenuHeight = 6;
01196 fMenuWidth = 8;
01197 fXl = 16;
01198
01199 TGMenuEntry *ptr;
01200 TIter next(fEntryList);
01201
01202 while ((ptr = (TGMenuEntry *) next())) {
01203
01204 if (ptr->fStatus & kMenuHideMask) continue;
01205
01206 if (ptr->fPic) {
01207 UInt_t pw = ptr->fPic->GetWidth();
01208 if (pw+12 > fXl) { fMenuWidth += pw+12-fXl; fXl = pw+12; }
01209 }
01210 ptr->fEx = 2;
01211 ptr->fEy = fMenuHeight-2;
01212 fMenuWidth = TMath::Max(fMenuWidth, ptr->fEw);
01213 fMenuHeight += ptr->fEh;
01214 }
01215 Resize(fMenuWidth, fMenuHeight);
01216 }
01217
01218
01219 void TGPopupMenu::PlaceMenu(Int_t x, Int_t y, Bool_t stick_mode, Bool_t grab_pointer)
01220 {
01221
01222
01223
01224
01225
01226 void *ud;
01227 EndMenu(ud);
01228
01229 Int_t rx, ry;
01230 UInt_t rw, rh;
01231
01232 fStick = stick_mode;
01233 fCurrent = 0;
01234
01235
01236 gVirtualX->GetWindowSize(fParent->GetId(), rx, ry, rw, rh);
01237
01238 if (x < 0) x = 0;
01239 if (x + fMenuWidth > rw) x = rw - fMenuWidth;
01240 if (y < 0) y = 0;
01241 if (y + fMenuHeight > rh) y = rh - fMenuHeight;
01242
01243 Move(x, y);
01244 MapRaised();
01245
01246 if (grab_pointer) {
01247 gVirtualX->GrabPointer(fId, kButtonPressMask | kButtonReleaseMask |
01248 kPointerMotionMask, kNone, fDefaultCursor);
01249 fHasGrab = kTRUE;
01250 } else {
01251 fHasGrab = kFALSE;
01252 }
01253
01254 fPoppedUp = kTRUE;
01255 PoppedUp();
01256 if (fMenuBar) fMenuBar->BindKeys(kTRUE);
01257
01258 fClient->RegisterPopup(this);
01259 }
01260
01261
01262 Int_t TGPopupMenu::EndMenu(void *&userData)
01263 {
01264
01265
01266
01267 Int_t id;
01268
01269 if (fDelay) fDelay->Remove();
01270
01271
01272
01273 if (fCurrent != 0) {
01274
01275
01276 fCurrent->fStatus &= ~kMenuActiveMask;
01277
01278 if ((fCurrent->fType == kMenuPopup) && fCurrent->fPopup) {
01279 id = fCurrent->fPopup->EndMenu(userData);
01280 } else {
01281
01282 if (fCurrent->fStatus & kMenuEnableMask) {
01283 id = fCurrent->fEntryId;
01284 userData = fCurrent->fUserData;
01285 } else {
01286 id = -1;
01287 userData = 0;
01288 }
01289 }
01290
01291 } else {
01292
01293 id = -1;
01294 userData = 0;
01295 }
01296
01297
01298 UnmapWindow();
01299
01300 gClient->UnregisterPopup(this);
01301 if (fMenuBar) fMenuBar->BindKeys(kFALSE);
01302
01303 if (fPoppedUp) {
01304 fPoppedUp = kFALSE;
01305 PoppedDown();
01306 }
01307
01308 return id;
01309 }
01310
01311
01312 Bool_t TGPopupMenu::HandleButton(Event_t *event)
01313 {
01314
01315
01316 int id;
01317 void *ud;
01318
01319 if (event->fType == kButtonRelease) {
01320 if (fStick) {
01321 fStick = kFALSE;
01322 return kTRUE;
01323 }
01324
01325
01326 id = EndMenu(ud);
01327 if (fHasGrab) gVirtualX->GrabPointer(0, 0, 0, 0, kFALSE);
01328 if (fCurrent != 0) {
01329 fCurrent->fStatus &= ~kMenuActiveMask;
01330 if (fCurrent->fStatus & kMenuEnableMask) {
01331 SendMessage(fMsgWindow, MK_MSG(kC_COMMAND, kCM_MENU), id,
01332 (Long_t)ud);
01333 Activated(id);
01334 }
01335 }
01336 }
01337 return kTRUE;
01338 }
01339
01340
01341 Bool_t TGPopupMenu::HandleCrossing(Event_t *event)
01342 {
01343
01344
01345 if (event->fType == kEnterNotify) {
01346
01347 TGMenuEntry *ptr;
01348 TIter next(fEntryList);
01349
01350 while ((ptr = (TGMenuEntry *) next())) {
01351 if (ptr->fStatus & kMenuHideMask) continue;
01352
01353 if ((event->fX >= ptr->fEx) && (event->fX <= ptr->fEx+(Int_t)fMenuWidth-10) &&
01354 (event->fY >= ptr->fEy) && (event->fY <= ptr->fEy+(Int_t)ptr->fEh))
01355 break;
01356 }
01357 Activate(ptr);
01358 } else {
01359 Activate((TGMenuEntry*)0);
01360 }
01361 if (fMenuBar) fMenuBar->fKeyNavigate = kFALSE;
01362 if (fSplitButton) fSplitButton->fKeyNavigate = kFALSE;
01363
01364 return kTRUE;
01365 }
01366
01367
01368 Bool_t TGPopupMenu::HandleMotion(Event_t *event)
01369 {
01370
01371
01372 TGFrame::HandleMotion(event);
01373
01374 TGMenuEntry *ptr;
01375 TIter next(fEntryList);
01376
01377 fStick = kFALSE;
01378 while ((ptr = (TGMenuEntry *) next())) {
01379 if (ptr->fStatus & kMenuHideMask) continue;
01380
01381 if ((event->fX >= ptr->fEx) && (event->fX <= ptr->fEx+(Int_t)fMenuWidth-4) &&
01382 (event->fY >= ptr->fEy) && (event->fY <= ptr->fEy+(Int_t)ptr->fEh))
01383 break;
01384 }
01385 Activate(ptr);
01386
01387 return kTRUE;
01388 }
01389
01390
01391 void TGPopupMenu::Activate(TGMenuEntry *entry)
01392 {
01393
01394
01395 if (entry == fCurrent) return;
01396
01397
01398
01399 if (fCurrent != 0) {
01400 void *ud;
01401 if (entry == 0 && fCurrent->fType == kMenuPopup) return;
01402 if ((fCurrent->fType == kMenuPopup) && fCurrent->fPopup)
01403 fCurrent->fPopup->EndMenu(ud);
01404 fCurrent->fStatus &= ~kMenuActiveMask;
01405 DrawEntry(fCurrent);
01406 }
01407
01408 if (fDelay) fDelay->Remove();
01409
01410
01411
01412 if (entry) {
01413 entry->fStatus |= kMenuActiveMask;
01414 DrawEntry(entry);
01415 if (entry->fType == kMenuPopup) {
01416 if (!fDelay) fDelay = new TPopupDelayTimer(this, 350);
01417 fDelay->Reset();
01418 gSystem->AddTimer(fDelay);
01419
01420
01421 } else if (entry->fType == kMenuEntry) {
01422
01423 SendMessage(fMsgWindow, MK_MSG(kC_COMMAND, kCM_MENUSELECT),
01424 entry->fEntryId, (Long_t)entry->fUserData);
01425 Highlighted(entry->fEntryId);
01426 }
01427 }
01428 fCurrent = entry;
01429 }
01430
01431
01432 Bool_t TGPopupMenu::HandleTimer(TTimer *)
01433 {
01434
01435
01436
01437 if (fCurrent != 0) {
01438 if ((fCurrent->fType == kMenuPopup) && fCurrent->fPopup) {
01439 Int_t ax, ay;
01440 Window_t wdummy;
01441
01442 gVirtualX->TranslateCoordinates(fId,
01443 (fCurrent->fPopup->GetParent())->GetId(),
01444 fCurrent->fEx+fMenuWidth, fCurrent->fEy,
01445 ax, ay, wdummy);
01446
01447 fCurrent->fPopup->PlaceMenu(ax-5, ay-1, kFALSE, kFALSE);
01448 }
01449 }
01450 fDelay->Remove();
01451
01452 return kTRUE;
01453 }
01454
01455
01456 void TGPopupMenu::DoRedraw()
01457 {
01458
01459
01460 TGFrame::DoRedraw();
01461
01462 TGMenuEntry *ptr;
01463 TIter next(fEntryList);
01464
01465 while ((ptr = (TGMenuEntry *) next()))
01466 DrawEntry(ptr);
01467 }
01468
01469
01470 void TGPopupMenu::DrawEntry(TGMenuEntry *entry)
01471 {
01472
01473
01474 FontStruct_t font;
01475 GCValues_t gcval;
01476
01477 if (entry->fStatus & kMenuHideMask)
01478 return;
01479
01480 if (entry->fStatus & kMenuDefaultMask) {
01481 font = fHifontStruct;
01482 gcval.fMask = kGCFont;
01483 gcval.fFont = gVirtualX->GetFontHandle(font);
01484 gVirtualX->ChangeGC(fNormGC, &gcval);
01485 gVirtualX->ChangeGC(fSelGC, &gcval);
01486 } else {
01487 font = fFontStruct;
01488 }
01489
01490 UInt_t tw = 0;
01491 int max_ascent, max_descent;
01492 gVirtualX->GetFontProperties(font, max_ascent, max_descent);
01493 int tx = entry->fEx + fXl;
01494
01495 int offset = (entry->fEh - (max_ascent + max_descent)) / 2;
01496 int ty = entry->fEy + max_ascent + offset - 1;
01497 if (entry->fShortcut)
01498 tw = 7 + gVirtualX->TextWidth(fFontStruct, entry->fShortcut->Data(), entry->fShortcut->Length());
01499
01500 switch (entry->fType) {
01501 case kMenuPopup:
01502 case kMenuLabel:
01503 case kMenuEntry:
01504 if ((entry->fStatus & kMenuActiveMask) && entry->fType != kMenuLabel) {
01505 gVirtualX->FillRectangle(fId, fSelbackGC, entry->fEx+1, entry->fEy-1,
01506 fMenuWidth-6, entry->fEh);
01507 if (entry->fType == kMenuPopup)
01508 DrawTrianglePattern(fSelGC, fMenuWidth-10, entry->fEy+fEntrySep, fMenuWidth-6, entry->fEy+11);
01509 if (entry->fStatus & kMenuCheckedMask)
01510 DrawCheckMark(fSelGC, 6, entry->fEy+fEntrySep, 14, entry->fEy+11);
01511 if (entry->fStatus & kMenuRadioMask)
01512 DrawRCheckMark(fSelGC, 6, entry->fEy+fEntrySep, 14, entry->fEy+11);
01513 if (entry->fPic != 0)
01514 entry->fPic->Draw(fId, fSelGC, 8, entry->fEy+1);
01515 entry->fLabel->Draw(fId,
01516 (entry->fStatus & kMenuEnableMask) ? fSelGC : GetShadowGC()(),
01517 tx, ty);
01518 if (entry->fShortcut)
01519 entry->fShortcut->Draw(fId, (entry->fStatus & kMenuEnableMask) ? fSelGC : GetShadowGC()(),
01520 fMenuWidth - tw, ty);
01521 } else {
01522 gVirtualX->FillRectangle(fId, GetBckgndGC()(), entry->fEx+1, entry->fEy-1,
01523 fMenuWidth-6, entry->fEh);
01524 if (entry->fType == kMenuPopup)
01525 DrawTrianglePattern(fNormGC, fMenuWidth-10, entry->fEy+fEntrySep, fMenuWidth-6, entry->fEy+11);
01526 if (entry->fStatus & kMenuCheckedMask)
01527 DrawCheckMark(fNormGC, 6, entry->fEy+fEntrySep, 14, entry->fEy+11);
01528 if (entry->fStatus & kMenuRadioMask)
01529 DrawRCheckMark(fNormGC, 6, entry->fEy+fEntrySep, 14, entry->fEy+11);
01530 if (entry->fPic != 0)
01531 entry->fPic->Draw(fId, fNormGC, 8, entry->fEy+1);
01532 if (entry->fStatus & kMenuEnableMask) {
01533 entry->fLabel->Draw(fId, fNormGC, tx, ty);
01534 if (entry->fShortcut)
01535 entry->fShortcut->Draw(fId, fNormGC, fMenuWidth - tw, ty);
01536 } else {
01537 entry->fLabel->Draw(fId, GetHilightGC()(), tx+1, ty+1);
01538 entry->fLabel->Draw(fId, GetShadowGC()(), tx, ty);
01539 if (entry->fShortcut) {
01540 entry->fShortcut->Draw(fId, GetHilightGC()(), fMenuWidth - tw+1, ty+1);
01541 entry->fShortcut->Draw(fId, GetShadowGC()(), fMenuWidth - tw, ty);
01542 }
01543 }
01544 }
01545 break;
01546
01547 case kMenuSeparator:
01548 gVirtualX->DrawLine(fId, GetShadowGC()(), 2, entry->fEy, fMenuWidth-fEntrySep, entry->fEy);
01549 gVirtualX->DrawLine(fId, GetHilightGC()(), 2, entry->fEy+1, fMenuWidth-fEntrySep, entry->fEy+1);
01550 break;
01551 }
01552
01553
01554 if (entry->fStatus & kMenuDefaultMask) {
01555 gcval.fFont = gVirtualX->GetFontHandle(fFontStruct);
01556 gVirtualX->ChangeGC(fNormGC, &gcval);
01557 gVirtualX->ChangeGC(fSelGC, &gcval);
01558 }
01559 }
01560
01561
01562 void TGPopupMenu::DrawBorder()
01563 {
01564
01565
01566 gVirtualX->DrawLine(fId, GetBckgndGC()(), 0, 0, fMenuWidth-2, 0);
01567 gVirtualX->DrawLine(fId, GetBckgndGC()(), 0, 0, 0, fMenuHeight-2);
01568 gVirtualX->DrawLine(fId, GetHilightGC()(), 1, 1, fMenuWidth-fEntrySep, 1);
01569 gVirtualX->DrawLine(fId, GetHilightGC()(), 1, 1, 1, fMenuHeight-fEntrySep);
01570
01571 gVirtualX->DrawLine(fId, GetShadowGC()(), 1, fMenuHeight-2, fMenuWidth-2, fMenuHeight-2);
01572 gVirtualX->DrawLine(fId, GetShadowGC()(), fMenuWidth-2, fMenuHeight-2, fMenuWidth-2, 1);
01573 gVirtualX->DrawLine(fId, GetBlackGC()(), 0, fMenuHeight-1, fMenuWidth-1, fMenuHeight-1);
01574 gVirtualX->DrawLine(fId, GetBlackGC()(), fMenuWidth-1, fMenuHeight-1, fMenuWidth-1, 0);
01575 }
01576
01577
01578 void TGPopupMenu::DrawTrianglePattern(GContext_t gc, Int_t l, Int_t t,
01579 Int_t r, Int_t b)
01580 {
01581
01582
01583
01584 Point_t points[3];
01585
01586 int m = (t + b) >> 1;
01587
01588 points[0].fX = l;
01589 points[0].fY = t;
01590 points[1].fX = l;
01591 points[1].fY = b;
01592 points[2].fX = r;
01593 points[2].fY = m;
01594
01595 gVirtualX->FillPolygon(fId, gc, points, 3);
01596 }
01597
01598
01599 void TGPopupMenu::DrawCheckMark(GContext_t gc, Int_t l, Int_t t, Int_t, Int_t b)
01600 {
01601
01602
01603 Segment_t seg[6];
01604
01605 t = (t + b - 8) >> 1; ++t;
01606
01607 seg[0].fX1 = 1+l; seg[0].fY1 = 3+t; seg[0].fX2 = 3+l; seg[0].fY2 = 5+t;
01608 seg[1].fX1 = 1+l; seg[1].fY1 = 4+t; seg[1].fX2 = 3+l; seg[1].fY2 = 6+t;
01609 seg[2].fX1 = 1+l; seg[2].fY1 = 5+t; seg[2].fX2 = 3+l; seg[2].fY2 = 7+t;
01610 seg[3].fX1 = 3+l; seg[3].fY1 = 5+t; seg[3].fX2 = 7+l; seg[3].fY2 = 1+t;
01611 seg[4].fX1 = 3+l; seg[4].fY1 = 6+t; seg[4].fX2 = 7+l; seg[4].fY2 = 2+t;
01612 seg[5].fX1 = 3+l; seg[5].fY1 = 7+t; seg[5].fX2 = 7+l; seg[5].fY2 = 3+t;
01613
01614 gVirtualX->DrawSegments(fId, gc, seg, 6);
01615 }
01616
01617
01618 void TGPopupMenu::DrawRCheckMark(GContext_t gc, Int_t l, Int_t t, Int_t r, Int_t b)
01619 {
01620
01621
01622 Segment_t seg[5];
01623
01624 t = (t + b - 5) >> 1; ++t;
01625 l = (l + r - 5) >> 1; ++l;
01626
01627 seg[0].fX1 = 1+l; seg[0].fY1 = 0+t; seg[0].fX2 = 3+l; seg[0].fY2 = 0+t;
01628 seg[1].fX1 = 0+l; seg[1].fY1 = 1+t; seg[1].fX2 = 4+l; seg[1].fY2 = 1+t;
01629 seg[2].fX1 = 0+l; seg[2].fY1 = 2+t; seg[2].fX2 = 4+l; seg[2].fY2 = 2+t;
01630 seg[3].fX1 = 0+l; seg[3].fY1 = 3+t; seg[3].fX2 = 4+l; seg[3].fY2 = 3+t;
01631 seg[4].fX1 = 1+l; seg[4].fY1 = 4+t; seg[4].fX2 = 3+l; seg[4].fY2 = 4+t;
01632
01633 gVirtualX->DrawSegments(fId, gc, seg, 5);
01634 }
01635
01636
01637 void TGPopupMenu::DefaultEntry(Int_t id)
01638 {
01639
01640
01641 TGMenuEntry *ptr;
01642 TIter next(fEntryList);
01643
01644 while ((ptr = (TGMenuEntry *) next())) {
01645 if (ptr->fEntryId == id)
01646 ptr->fStatus |= kMenuDefaultMask;
01647 else
01648 ptr->fStatus &= ~kMenuDefaultMask;
01649 }
01650 }
01651
01652
01653 void TGPopupMenu::EnableEntry(Int_t id)
01654 {
01655
01656
01657 TGMenuEntry *ptr;
01658 TIter next(fEntryList);
01659
01660 while ((ptr = (TGMenuEntry *) next()))
01661 if (ptr->fEntryId == id) {
01662 ptr->fStatus |= kMenuEnableMask;
01663 if (ptr->fStatus & kMenuHideMask) {
01664 ptr->fStatus &= ~kMenuHideMask;
01665 Reposition();
01666 }
01667 break;
01668 }
01669 }
01670
01671
01672 void TGPopupMenu::DisableEntry(Int_t id)
01673 {
01674
01675
01676 TGMenuEntry *ptr;
01677 TIter next(fEntryList);
01678
01679 while ((ptr = (TGMenuEntry *) next()))
01680 if (ptr->fEntryId == id) { ptr->fStatus &= ~kMenuEnableMask; break; }
01681 }
01682
01683
01684 Bool_t TGPopupMenu::IsEntryEnabled(Int_t id)
01685 {
01686
01687
01688 TGMenuEntry *ptr;
01689 TIter next(fEntryList);
01690
01691 while ((ptr = (TGMenuEntry *) next()))
01692 if (ptr->fEntryId == id)
01693 return (ptr->fStatus & kMenuEnableMask) ? kTRUE : kFALSE;
01694 return kFALSE;
01695 }
01696
01697
01698 void TGPopupMenu::HideEntry(Int_t id)
01699 {
01700
01701
01702
01703 TGMenuEntry *ptr;
01704 TIter next(fEntryList);
01705
01706 while ((ptr = (TGMenuEntry *) next()))
01707 if (ptr->fEntryId == id) {
01708 ptr->fStatus |= kMenuHideMask;
01709 ptr->fStatus &= ~kMenuEnableMask;
01710 Reposition();
01711 break;
01712 }
01713 }
01714
01715
01716 Bool_t TGPopupMenu::IsEntryHidden(Int_t id)
01717 {
01718
01719
01720 TGMenuEntry *ptr;
01721 TIter next(fEntryList);
01722
01723 while ((ptr = (TGMenuEntry *) next()))
01724 if (ptr->fEntryId == id)
01725 return (ptr->fStatus & kMenuHideMask) ? kTRUE : kFALSE;
01726 return kFALSE;
01727 }
01728
01729
01730 void TGPopupMenu::CheckEntry(Int_t id)
01731 {
01732
01733
01734 TGMenuEntry *ptr;
01735 TIter next(fEntryList);
01736
01737 while ((ptr = (TGMenuEntry *) next()))
01738 if (ptr->fEntryId == id) { ptr->fStatus |= kMenuCheckedMask; break; }
01739 }
01740
01741
01742 void TGPopupMenu::CheckEntryByData(void *user_data)
01743 {
01744
01745
01746
01747 TGMenuEntry *ptr;
01748 TIter next(fEntryList);
01749
01750 while ((ptr = (TGMenuEntry *) next()))
01751 if (ptr->fUserData == user_data) { ptr->fStatus |= kMenuCheckedMask; break; }
01752 }
01753
01754
01755 void TGPopupMenu::UnCheckEntry(Int_t id)
01756 {
01757
01758
01759 TGMenuEntry *ptr;
01760 TIter next(fEntryList);
01761
01762 while ((ptr = (TGMenuEntry *) next()))
01763 if (ptr->fEntryId == id) { ptr->fStatus &= ~kMenuCheckedMask; break; }
01764 }
01765
01766
01767 void TGPopupMenu::UnCheckEntries()
01768 {
01769
01770
01771 TGMenuEntry *ptr;
01772 TIter next(fEntryList);
01773
01774 while ((ptr = (TGMenuEntry *) next())) {
01775 ptr->fStatus &= ~kMenuCheckedMask;
01776 }
01777 }
01778
01779
01780 void TGPopupMenu::UnCheckEntryByData(void *user_data)
01781 {
01782
01783
01784
01785 TGMenuEntry *ptr;
01786 TIter next(fEntryList);
01787
01788 while ((ptr = (TGMenuEntry *) next()))
01789 if (ptr->fUserData == user_data) { ptr->fStatus &= ~kMenuCheckedMask; break; }
01790 }
01791
01792
01793 Bool_t TGPopupMenu::IsEntryChecked(Int_t id)
01794 {
01795
01796
01797 TGMenuEntry *ptr;
01798 TIter next(fEntryList);
01799
01800 while ((ptr = (TGMenuEntry *) next()))
01801 if (ptr->fEntryId == id)
01802 return (ptr->fStatus & kMenuCheckedMask) ? kTRUE : kFALSE;
01803 return kFALSE;
01804 }
01805
01806
01807 void TGPopupMenu::RCheckEntry(Int_t id, Int_t IDfirst, Int_t IDlast)
01808 {
01809
01810
01811
01812 TGMenuEntry *ptr;
01813 TIter next(fEntryList);
01814
01815 while ((ptr = (TGMenuEntry *) next()))
01816 if (ptr->fEntryId == id)
01817 ptr->fStatus |= kMenuRadioMask | kMenuRadioEntryMask;
01818 else
01819 if (ptr->fEntryId >= IDfirst && ptr->fEntryId <= IDlast) {
01820 ptr->fStatus &= ~kMenuRadioMask;
01821 ptr->fStatus |= kMenuRadioEntryMask;
01822 }
01823 }
01824
01825
01826 Bool_t TGPopupMenu::IsEntryRChecked(Int_t id)
01827 {
01828
01829
01830 TGMenuEntry *ptr;
01831 TIter next(fEntryList);
01832
01833 while ((ptr = (TGMenuEntry *) next()))
01834 if (ptr->fEntryId == id)
01835 return (ptr->fStatus & kMenuRadioMask) ? kTRUE : kFALSE;
01836 return kFALSE;
01837 }
01838
01839
01840 TGMenuEntry *TGPopupMenu::GetEntry(Int_t id)
01841 {
01842
01843
01844
01845
01846
01847
01848
01849 TGMenuEntry *ptr;
01850 TIter next(fEntryList);
01851
01852 while ((ptr = (TGMenuEntry *) next()))
01853 if (ptr->fEntryId == id)
01854 return ptr;
01855 return 0;
01856 }
01857
01858
01859 TGMenuEntry *TGPopupMenu::GetEntry(const char *s)
01860 {
01861
01862
01863
01864
01865
01866
01867
01868
01869
01870 return (TGMenuEntry*) fEntryList->FindObject(s);
01871 }
01872
01873
01874 void TGPopupMenu::DeleteEntry(Int_t id)
01875 {
01876
01877
01878 TGMenuEntry *ptr;
01879 TIter next(fEntryList);
01880
01881 while ((ptr = (TGMenuEntry *) next()))
01882 if (ptr->fEntryId == id) {
01883 fEntryList->Remove(ptr);
01884 delete ptr;
01885 Reposition();
01886 if (fCurrent == ptr)
01887 fCurrent = 0;
01888 return;
01889 }
01890 }
01891
01892
01893 void TGPopupMenu::DeleteEntry(TGMenuEntry *entry)
01894 {
01895
01896
01897 TGMenuEntry *ptr;
01898 TIter next(fEntryList);
01899
01900 while ((ptr = (TGMenuEntry *) next()))
01901 if (ptr == entry) {
01902 fEntryList->Remove(ptr);
01903 delete ptr;
01904 Reposition();
01905 if (fCurrent == ptr)
01906 fCurrent = 0;
01907 return;
01908 }
01909 }
01910
01911
01912 const TGGC &TGPopupMenu::GetDefaultGC()
01913 {
01914
01915
01916 if (!fgDefaultGC)
01917 fgDefaultGC = gClient->GetResourcePool()->GetFrameGC();
01918 return *fgDefaultGC;
01919 }
01920
01921
01922 const TGGC &TGPopupMenu::GetDefaultSelectedGC()
01923 {
01924
01925
01926 if (!fgDefaultSelectedGC)
01927 fgDefaultSelectedGC = gClient->GetResourcePool()->GetSelectedGC();
01928 return *fgDefaultSelectedGC;
01929 }
01930
01931
01932 const TGGC &TGPopupMenu::GetDefaultSelectedBackgroundGC()
01933 {
01934
01935
01936 if (!fgDefaultSelectedBackgroundGC)
01937 fgDefaultSelectedBackgroundGC = gClient->GetResourcePool()->GetSelectedBckgndGC();
01938 return *fgDefaultSelectedBackgroundGC;
01939 }
01940
01941
01942 FontStruct_t TGPopupMenu::GetDefaultFontStruct()
01943 {
01944
01945
01946 if (!fgDefaultFont)
01947 fgDefaultFont = gClient->GetResourcePool()->GetMenuFont();
01948 return fgDefaultFont->GetFontStruct();
01949 }
01950
01951
01952 FontStruct_t TGPopupMenu::GetHilightFontStruct()
01953 {
01954
01955
01956 if (!fgHilightFont)
01957 fgHilightFont = gClient->GetResourcePool()->GetMenuHiliteFont();
01958 return fgHilightFont->GetFontStruct();
01959 }
01960
01961
01962
01963
01964
01965
01966
01967
01968
01969 TGMenuTitle::TGMenuTitle(const TGWindow *p, TGHotString *s, TGPopupMenu *menu,
01970 GContext_t norm, FontStruct_t font, UInt_t options)
01971 : TGFrame(p, 1, 1, options)
01972 {
01973
01974
01975
01976 fLabel = s;
01977 fMenu = menu;
01978 fFontStruct = font;
01979 fSelGC = GetDefaultSelectedGC()();
01980 fNormGC = norm;
01981 fState = kFALSE;
01982 fTitleId = -1;
01983 fTextColor = GetForeground();
01984
01985 Int_t hotchar;
01986 if (s && (hotchar = s->GetHotChar()) != 0)
01987 fHkeycode = gVirtualX->KeysymToKeycode(hotchar);
01988 else
01989 fHkeycode = 0;
01990
01991 UInt_t tw = 0;
01992 Int_t max_ascent, max_descent;
01993 if (fLabel)
01994 tw = gVirtualX->TextWidth(fFontStruct, fLabel->GetString(), fLabel->GetLength());
01995 gVirtualX->GetFontProperties(fFontStruct, max_ascent, max_descent);
01996
01997 Resize(tw + 8, max_ascent + max_descent + 7);
01998
01999 if (p && p->InheritsFrom(TGMenuBar::Class())) {
02000 TGMenuBar *bar = (TGMenuBar*)p;
02001 fMenu->SetMenuBar(bar);
02002 }
02003 }
02004
02005
02006 void TGMenuTitle::SetState(Bool_t state)
02007 {
02008
02009
02010 fState = state;
02011 if (state) {
02012 if (fMenu != 0) {
02013 Int_t ax, ay;
02014 Window_t wdummy;
02015
02016 gVirtualX->TranslateCoordinates(fId, (fMenu->GetParent())->GetId(),
02017 0, 0, ax, ay, wdummy);
02018
02019
02020 fMenu->PlaceMenu(ax-1, ay+fHeight, kTRUE, kFALSE);
02021 }
02022 } else {
02023 if (fMenu != 0) {
02024 fTitleId = fMenu->EndMenu(fTitleData);
02025 }
02026 }
02027 fOptions &= ~(kSunkenFrame | kRaisedFrame);
02028 fClient->NeedRedraw(this);
02029 }
02030
02031
02032 void TGMenuTitle::DoRedraw()
02033 {
02034
02035
02036 TGFrame::DoRedraw();
02037
02038 int x, y, max_ascent, max_descent;
02039 x = y = 4;
02040
02041 gVirtualX->GetFontProperties(fFontStruct, max_ascent, max_descent);
02042
02043 if (fState) {
02044 gVirtualX->SetForeground(fNormGC, GetDefaultSelectedBackground());
02045 gVirtualX->FillRectangle(fId,fNormGC, 0, 0, fWidth, fHeight);
02046 gVirtualX->SetForeground(fNormGC, GetForeground());
02047 fLabel->Draw(fId, fSelGC, x, y + max_ascent);
02048 } else {
02049
02050 Pixel_t back = GetDefaultFrameBackground();
02051 if (fMenu && fMenu->fMenuBar && fMenu->fMenuBar->GetBackground() != back)
02052 back = fMenu->fMenuBar->GetBackground();
02053 gVirtualX->SetForeground(fNormGC, back);
02054 gVirtualX->FillRectangle(fId,fNormGC, 0, 0, fWidth, fHeight);
02055 gVirtualX->SetForeground(fNormGC, fTextColor);
02056 fLabel->Draw(fId, fNormGC, x, y + max_ascent);
02057 if (fTextColor != GetForeground())
02058 gVirtualX->SetForeground(fNormGC, GetForeground());
02059 }
02060 }
02061
02062
02063 void TGMenuTitle::DoSendMessage()
02064 {
02065
02066
02067 if (fMenu)
02068 if (fTitleId != -1) {
02069 SendMessage(fMenu->fMsgWindow, MK_MSG(kC_COMMAND, kCM_MENU), fTitleId,
02070 (Long_t)fTitleData);
02071 fMenu->Activated(fTitleId);
02072 }
02073 }
02074
02075
02076 FontStruct_t TGMenuTitle::GetDefaultFontStruct()
02077 {
02078
02079
02080 if (!fgDefaultFont)
02081 fgDefaultFont = gClient->GetResourcePool()->GetMenuFont();
02082 return fgDefaultFont->GetFontStruct();
02083 }
02084
02085
02086 const TGGC &TGMenuTitle::GetDefaultGC()
02087 {
02088
02089
02090 if (!fgDefaultGC)
02091 fgDefaultGC = gClient->GetResourcePool()->GetFrameGC();
02092 return *fgDefaultGC;
02093 }
02094
02095
02096 const TGGC &TGMenuTitle::GetDefaultSelectedGC()
02097 {
02098
02099
02100 if (!fgDefaultSelectedGC)
02101 fgDefaultSelectedGC = gClient->GetResourcePool()->GetSelectedGC();
02102 return *fgDefaultSelectedGC;
02103 }
02104
02105
02106 void TGPopupMenu::SavePrimitive(ostream &out, Option_t *option )
02107 {
02108
02109
02110 char quote = '"';
02111
02112 out << " TGPopupMenu *";
02113 out << GetName() << " = new TGPopupMenu(gClient->GetDefaultRoot()"
02114 << "," << GetWidth() << "," << GetHeight() << "," << GetOptionString() << ");" << endl;
02115
02116 Bool_t hasradio = kFALSE;
02117 Int_t r_first, r_last, r_active;
02118 r_active = r_first = r_last = -1;
02119
02120 TGMenuEntry *mentry;
02121 TIter next(GetListOfEntries());
02122
02123 while ((mentry = (TGMenuEntry *) next())) {
02124 const char *text;
02125 Int_t i, lentext, hotpos;
02126 char shortcut[80];
02127 char *outext;
02128
02129 switch (mentry->GetType()) {
02130 case kMenuEntry:
02131 text = mentry->GetName();
02132 lentext = mentry->fLabel->GetLength();
02133 hotpos = mentry->fLabel->GetHotPos();
02134 outext = new char[lentext+2];
02135 i=0;
02136 while (lentext) {
02137 if (i == hotpos-1) {
02138 outext[i] = '&';
02139 i++;
02140 }
02141 outext[i] = *text;
02142 i++; text++; lentext--;
02143 }
02144 outext[i]=0;
02145 if (mentry->fShortcut) {
02146 snprintf(shortcut, 80, "\\t%s", mentry->GetShortcutText());
02147 }
02148 else {
02149 memset(shortcut, 0, 80);
02150 }
02151
02152 out << " " << GetName() << "->AddEntry(" << quote
02153 << gSystem->ExpandPathName(gSystem->UnixPathName(outext))
02154 << shortcut
02155 << quote << "," << mentry->GetEntryId();
02156 if (mentry->fUserData) {
02157 out << "," << mentry->fUserData;
02158 }
02159 if (mentry->fPic) {
02160 out << ",gClient->GetPicture(" << quote
02161 << gSystem->ExpandPathName(gSystem->UnixPathName(mentry->fPic->GetName()))
02162 << quote << ")";
02163 }
02164 out << ");" << endl;
02165 delete [] outext;
02166 break;
02167 case kMenuPopup:
02168 out << endl;
02169 out << " // cascaded menu " << quote << mentry->GetName() << quote <<endl;
02170 mentry->fPopup->SavePrimitive(out, option);
02171 text = mentry->GetName();
02172 lentext = mentry->fLabel->GetLength();
02173 hotpos = mentry->fLabel->GetHotPos();
02174 outext = new char[lentext+2];
02175 i=0;
02176 while (lentext) {
02177 if (i == hotpos-1) {
02178 outext[i] = '&';
02179 i++;
02180 }
02181 outext[i] = *text;
02182 i++; text++; lentext--;
02183 }
02184 outext[i]=0;
02185
02186 out << " " << GetName() << "->AddPopup(" << quote
02187 << outext << quote << "," << mentry->fPopup->GetName()
02188 << ");" << endl;
02189 delete [] outext;
02190 break;
02191 case kMenuLabel:
02192 out << " " << GetName() << "->AddLabel(" << quote
02193 << mentry->GetName() << quote;
02194 if (mentry->fPic) {
02195 out << ",gClient->GetPicture(" << quote
02196 << mentry->fPic->GetName()
02197 << quote << ")";
02198 }
02199 out << ");" << endl;
02200 break;
02201 case kMenuSeparator:
02202 out << " " << GetName() << "->AddSeparator();" << endl;
02203 break;
02204 }
02205
02206 if (!(mentry->GetStatus() & kMenuEnableMask)) {
02207 out<< " " << GetName() << "->DisableEntry(" << mentry->GetEntryId()
02208 << ");" << endl;
02209 }
02210 if (mentry->GetStatus() & kMenuHideMask) {
02211 out<< " " << GetName() << "->HideEntry(" << mentry->GetEntryId()
02212 << ");" << endl;
02213 }
02214 if (mentry->GetStatus() & kMenuCheckedMask) {
02215 out<< " " << GetName() << "->CheckEntry(" << mentry->GetEntryId()
02216 << ");" << endl;
02217 }
02218 if (mentry->GetStatus() & kMenuDefaultMask) {
02219 out<< " "<< GetName() << "->DefaultEntry(" << mentry->GetEntryId()
02220 << ");" << endl;
02221 }
02222 if (mentry->GetStatus() & kMenuRadioEntryMask) {
02223 if (hasradio) {
02224 r_last = mentry->GetEntryId();
02225 if (IsEntryRChecked(mentry->GetEntryId())) r_active = mentry->GetEntryId();
02226 }
02227 else {
02228 r_first = mentry->GetEntryId();
02229 hasradio = kTRUE;
02230 if (IsEntryRChecked(mentry->GetEntryId())) r_active = mentry->GetEntryId();
02231 }
02232 } else if (hasradio) {
02233 out << " " << GetName() << "->RCheckEntry(" << r_active << "," << r_first
02234 << "," << r_last << ");" << endl;
02235 hasradio = kFALSE;
02236 r_active = r_first = r_last = -1;
02237 }
02238 }
02239 }
02240
02241
02242 void TGMenuTitle::SavePrimitive(ostream &out, Option_t *option )
02243 {
02244
02245
02246 char quote = '"';
02247
02248 out << endl;
02249 out << " // " << quote << fLabel->GetString() << quote <<" menu" << endl;
02250
02251 fMenu->SavePrimitive(out, option);
02252
02253 const char *text = fLabel->GetString();
02254 Int_t lentext = fLabel->GetLength();
02255 Int_t hotpos = fLabel->GetHotPos();
02256 char *outext = new char[lentext+2];
02257 Int_t i=0;
02258 while (lentext) {
02259 if (i == hotpos-1) {
02260 outext[i] = '&';
02261 i++;
02262 }
02263 outext[i] = *text;
02264 i++; text++; lentext--;
02265 }
02266 outext[i]=0;
02267 out << " " << fParent->GetName() << "->AddPopup(" << quote << outext
02268 << quote << "," << fMenu->GetName();
02269
02270 delete [] outext;
02271 }
02272
02273
02274 void TGMenuBar::SavePrimitive(ostream &out, Option_t *option )
02275 {
02276
02277
02278 out << endl;
02279 out << " // menu bar" << endl;
02280
02281 out << " TGMenuBar *";
02282 out << GetName() << " = new TGMenuBar(" << fParent->GetName()
02283 << "," << GetWidth() << "," << GetHeight() << "," << GetOptionString() << ");" << endl;
02284 if (option && strstr(option, "keep_names"))
02285 out << " " << GetName() << "->SetName(\"" << GetName() << "\");" << endl;
02286
02287 if (!fList) return;
02288
02289 TGFrameElement *el;
02290 TIter next(fList);
02291
02292 while ((el = (TGFrameElement *)next())) {
02293 el->fFrame->SavePrimitive(out, option);
02294 el->fLayout->SavePrimitive(out, option);
02295 out << ");" << endl;
02296 }
02297 }