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 }