Logo ROOT   6.12/07
Reference Guide
TGMenu.cxx
Go to the documentation of this file.
1 // @(#)root/gui:$Id$
2 // Author: Fons Rademakers 09/01/98
3 
4 /*************************************************************************
5  * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers. *
6  * All rights reserved. *
7  * *
8  * For the licensing terms see $ROOTSYS/LICENSE. *
9  * For the list of contributors see $ROOTSYS/README/CREDITS. *
10  *************************************************************************/
11 /**************************************************************************
12 
13  This source is based on Xclass95, a Win95-looking GUI toolkit.
14  Copyright (C) 1996, 1997 David Barth, Ricky Ralston, Hector Peraza.
15 
16  Xclass95 is free software; you can redistribute it and/or
17  modify it under the terms of the GNU Library General Public
18  License as published by the Free Software Foundation; either
19  version 2 of the License, or (at your option) any later version.
20 
21 **************************************************************************/
22 
23 //////////////////////////////////////////////////////////////////////////
24 // //
25 // TGMenuBar, TGPopupMenu, TGMenuTitle and TGMenuEntry //
26 // //
27 // The TGMenu.h header contains all different menu classes. //
28 // //
29 // The TGMenuBar class implements a menu bar widget. It is used to //
30 // specify and provide access to common and frequently used application //
31 // actions grouped under menu titles (TGMenuTitle class). The menu bar //
32 // takes the highest-level of the menu system and it is a starting //
33 // point for many interactions. It is always visible and allows using //
34 // the keyboard equivalents. The geometry of the menu bar is //
35 // automatically set to the parent widget, i.e. the menu bar //
36 // automatically resizes itself so that it has the same width as its //
37 // parent (typically TGMainFrame). A menu bar contains one or more //
38 // popup menus and usually is placed along the top of the application //
39 // window. Any popup menu is invisible until the user invokes it by //
40 // using the mouse pointer or the keyboard. //
41 // //
42 // Popup menus implemented by TGPopupMenu class are unique in that, //
43 // by convention, they are not placed with the other GUI components in //
44 // the user interfaces. Instead, a popup menu usually appears either in //
45 // a menu bar or as a context menu on the TOP of the GUI. For that //
46 // reason it needs gClient->GetDefaultRoot() as a parent to get the //
47 // pointer to the root (i.e. desktop) window. This way a popup menu //
48 // will never be embedded. //
49 // NOTE: Using gClient->GetRoot() as a parent of TGPopupMenu will not //
50 // avoid the possibility of embedding the corresponding popup menu //
51 // because the current window hierarchy can be changed by using //
52 // gClient->SetRoot() method. //
53 // //
54 // As a context menus TGPopupMenu shows up after pressing the right //
55 // mouse button, over a popup-enabled component. The popup menu then //
56 // appears under the mouse pointer. //
57 // //
58 // Selecting a menu item will generate the event: //
59 // kC_COMMAND, kCM_MENU, menu id, user data. //
60 // //
61 //////////////////////////////////////////////////////////////////////////
62 
63 #include "TGMenu.h"
64 #include "TGResourcePool.h"
65 #include "TTimer.h"
66 #include "TMath.h"
67 #include "TSystem.h"
68 #include "TList.h"
69 #include "Riostream.h"
70 #include "KeySymbols.h"
71 #include "TGButton.h"
72 #include "TQConnection.h"
73 #include "TParameter.h"
74 #include "RConfigure.h"
75 #include "TEnv.h"
76 
82 
86 
87 
91 
92 
93 ////////////////////////////////////////////////////////////////////////////////
94 
95 class TPopupDelayTimer : public TTimer {
96 private:
97  TGPopupMenu *fPopup; // popup menu
98 public:
99  TPopupDelayTimer(TGPopupMenu *p, Long_t ms) : TTimer(ms, kTRUE) { fPopup = p; }
100  Bool_t Notify();
101 };
102 
103 ////////////////////////////////////////////////////////////////////////////////
104 /// Notify when timer times out and reset the timer.
105 
106 Bool_t TPopupDelayTimer::Notify()
107 {
108  fPopup->HandleTimer(0);
109  Reset();
110  return kFALSE;
111 }
112 
113 
114 //////////////////////////////////////////////////////////////////////////
115 // //
116 // TGMenuBar member functions. //
117 // //
118 //////////////////////////////////////////////////////////////////////////
119 
120 ////////////////////////////////////////////////////////////////////////////////
121 /// Create a menu bar object.
122 
124  : TGHorizontalFrame(p, w, h, options | kHorizontalFrame)
125 {
126  fCurrent = 0;
127  fTitles = new TList;
128  fStick = kTRUE;
130  fTrash = new TList();
131 
132  gVirtualX->GrabButton(fId, kButton1, kAnyModifier,
134  kNone, kNone);
135 
137 
138  fMenuMore = new TGPopupMenu(gClient->GetDefaultRoot());
139  fMenuMore->AddLabel("Hidden Menus");
142 
143  fWithExt = kFALSE;
144  fOutLayouts = new TList();
145  fNeededSpace = new TList();
146 }
147 
148 ////////////////////////////////////////////////////////////////////////////////
149 /// Delete menu bar object. Removes also the hot keys from the main frame,
150 /// so hitting them will not cause the menus to popup.
151 
153 {
154  TGFrameElement *el;
155  TGMenuTitle *t;
156  Int_t keycode;
157 
158  if (!MustCleanup()) {
159  fTrash->Delete();
160  }
161  delete fTrash;
162 
164 
165  if (!MustCleanup()) {
166  TIter next(fList);
167  while ((el = (TGFrameElement *) next())) {
168  t = (TGMenuTitle *) el->fFrame;
169  if ((keycode = t->GetHotKeyCode()) != 0 && main) {
170  main->RemoveBind(this, keycode, kKeyMod1Mask);
171  }
172  }
173  }
174 
175  // delete TGMenuTitles
176  if (fTitles && !MustCleanup()) fTitles->Delete();
177  delete fTitles;
178 
179  delete fOutLayouts;
180  fNeededSpace->Delete();
181  delete fNeededSpace;
182  delete fMenuMore;
183  delete fMenuBarMoreLayout;
184 }
185 
186 ////////////////////////////////////////////////////////////////////////////////
187 /// Calculates whether the >> menu must be shown or not and
188 /// which menu titles are hidden.
189 
191 {
192  if (GetDefaultWidth() > GetWidth()) {
193  while (!(GetDefaultWidth() < GetWidth() ||
194  GetList()->GetSize() <= 1)) {
195  TGFrameElement* entry = GetLastOnLeft();
196  if (!entry) break;
197  TGMenuTitle* menuTitle = (TGMenuTitle*) entry->fFrame;
198  fNeededSpace->AddLast(new TParameter<Int_t>("", menuTitle->GetWidth() +
199  entry->fLayout->GetPadLeft() +
200  entry->fLayout->GetPadRight() ) );
201  fOutLayouts->AddLast( entry->fLayout );
202  fMenuMore->AddPopup( menuTitle->GetName(), menuTitle->GetMenu() );
203  menuTitle->GetMenu()->Connect("PoppedUp()", "TGMenuBar", this, "PopupConnection()");
204  RemovePopup( menuTitle->GetName() );
205  }
206  }
207 
208  if (fNeededSpace->GetSize() > 0) {
209  Int_t neededWidth = ((TParameter<Int_t>*) fNeededSpace->Last())->GetVal();
210  Bool_t fit = kFALSE;
211  if (fNeededSpace->GetSize() > 1)
212  fit = GetDefaultWidth() + neededWidth + 5 < GetWidth();
213  else
214  fit = GetDefaultWidth() + neededWidth - 7 < GetWidth();
215  while (fit) {
218  ULong_t hints = (layout) ? layout->GetLayoutHints() : 0;
219  TGPopupMenu* beforeMenu = 0;
220  if (hints & kLHintsRight) {
221  TGFrameElement* entry = GetLastOnLeft();
222  if (entry) {
223  TGMenuTitle* beforeMenuTitle = (TGMenuTitle*) entry->fFrame;
224  beforeMenu = beforeMenuTitle->GetMenu();
225  }
226  }
227  if (menu && menu->GetPopup()) {
228  menu->GetPopup()->Disconnect("PoppedUp()", this, "PopupConnection()");
229  AddPopup( menu->GetName(), menu->GetPopup(), layout, beforeMenu );
230  }
233  fMenuMore->DeleteEntry(menu);
234 
235  if (fNeededSpace->GetSize() > 0) {
236  neededWidth = ((TParameter<Int_t>*)fNeededSpace->Last())->GetVal();
237  if (fNeededSpace->GetSize() > 1)
238  fit = GetDefaultWidth() + neededWidth + 5 < GetWidth();
239  else
240  fit = GetDefaultWidth() + neededWidth - 7 < GetWidth();
241  } else
242  fit = kFALSE;
243  }
244  }
245 
246  if (fNeededSpace->GetSize() > 0) {
247  if (!fWithExt) {
249  ((TGMenuTitle*)((TGFrameElement*)GetList()->First())->fFrame)->GetMenu());
250  fWithExt = kTRUE;
251  }
252  } else {
253  RemovePopup(">>");
254  fWithExt = kFALSE;
255  }
256 
257  MapSubwindows();
259 }
260 
261 ////////////////////////////////////////////////////////////////////////////////
262 /// Returns the last visible menu title on the left of the '>>'
263 /// in the menu bar.
264 
266 {
267  TIter next(GetList());
268  while (TGFrameElement *entry = (TGFrameElement*) next()) {
269 
270  TGMenuTitle* menuTitle = (TGMenuTitle*) entry->fFrame;
271  TGLayoutHints* tmpLayout = (TGLayoutHints*) entry->fLayout;
272  ULong_t hints = tmpLayout->GetLayoutHints();
273 
274  if (hints & kLHintsRight && menuTitle->GetMenu() != fMenuMore) {
275  return entry;
276  }
277  }
278 
279  return ((TGFrameElement*)GetList()->Last());
280 }
281 
282 ////////////////////////////////////////////////////////////////////////////////
283 /// Connects the corresponding cascaded menu to the proper slots,
284 /// according to the highlighted menu entry in '>>' menu.
285 
287 {
288  // Disconnect all previous signals
289  TList* slots = fMenuMore->GetListOfSignals();
290  TIter next (slots);
291  while (TList* connlist = (TList*) next()) {
292 
293  const char* signal_name = connlist->GetName();
294  TIter next2(connlist);
295  while (TQConnection* conn = (TQConnection*) next2()) {
296  const char* slot_name = conn->GetName();
297  void* receiver = conn->GetReceiver();
298  fMenuMore->Disconnect(signal_name, receiver, slot_name);
299  }
300  }
301  fMenuMore->fMsgWindow = 0;
302 
303  // Check wheter the current entry is a menu or not (just in case)
304  TGMenuEntry* currentEntry = fMenuMore->GetCurrent();
305  if (currentEntry->GetType() != kMenuPopup) return;
306 
307  // Connect the corresponding active signals to the >> menu
308  TGPopupMenu* currentMenu = currentEntry->GetPopup();
309 
310  slots = currentMenu->GetListOfSignals();
311  TIter next3 (slots);
312  while (TList* connlist = (TList*) next3()) {
313 
314  const char* signal_name = connlist->GetName();
315  if (strcmp(signal_name, "Activated(int)") == 0) {
316  TIter next2(connlist);
317  while (TQConnection* conn = (TQConnection*) next2()) {
318 
319  const char* slot_name = conn->GetName();
320  const char* class_name = conn->GetClassName();
321  void* receiver = conn->GetReceiver();
322  fMenuMore->Connect(signal_name, class_name, receiver, slot_name);
323  }
324  }
325  }
326 
327  fMenuMore->fMsgWindow = currentMenu->fMsgWindow;
328 }
329 
330 ////////////////////////////////////////////////////////////////////////////////
331 /// If on kTRUE bind arrow, popup menu hot keys, otherwise
332 /// remove key bindings.
333 
335 {
336  gVirtualX->GrabKey(fId, gVirtualX->KeysymToKeycode(kKey_Left), kAnyModifier, on);
337  gVirtualX->GrabKey(fId, gVirtualX->KeysymToKeycode(kKey_Right), kAnyModifier, on);
338  gVirtualX->GrabKey(fId, gVirtualX->KeysymToKeycode(kKey_Up), kAnyModifier, on);
339  gVirtualX->GrabKey(fId, gVirtualX->KeysymToKeycode(kKey_Down), kAnyModifier, on);
340  gVirtualX->GrabKey(fId, gVirtualX->KeysymToKeycode(kKey_Enter), kAnyModifier, on);
341  gVirtualX->GrabKey(fId, gVirtualX->KeysymToKeycode(kKey_Return), kAnyModifier, on);
342  gVirtualX->GrabKey(fId, gVirtualX->KeysymToKeycode(kKey_Escape), kAnyModifier, on);
343 
344  if (fCurrent && fCurrent->GetMenu()) {
345  BindMenu(fCurrent->GetMenu(), on);
346  }
347 }
348 
349 ////////////////////////////////////////////////////////////////////////////////
350 /// If on kTRUE bind subMenu hot keys, otherwise remove key bindings.
351 
353 {
354  TGMenuEntry *e;
355  TIter next(subMenu->GetListOfEntries());
356 
357  while ((e = (TGMenuEntry*)next())) {
358  Int_t hot = 0;
359  if ( e->GetType() == kMenuPopup )
360  BindMenu(e->GetPopup(), on);
361  if (e->GetLabel()) {
362  hot = e->GetLabel()->GetHotChar();
363  }
364  if (!hot) continue;
365  gVirtualX->GrabKey(fId, gVirtualX->KeysymToKeycode(hot), 0, on);
366  gVirtualX->GrabKey(fId, gVirtualX->KeysymToKeycode(hot), kKeyShiftMask, on);
367  gVirtualX->GrabKey(fId, gVirtualX->KeysymToKeycode(hot), kKeyLockMask, on);
368  gVirtualX->GrabKey(fId, gVirtualX->KeysymToKeycode(hot), kKeyMod2Mask, on);
369  gVirtualX->GrabKey(fId, gVirtualX->KeysymToKeycode(hot), kKeyShiftMask | kKeyLockMask, on);
370  gVirtualX->GrabKey(fId, gVirtualX->KeysymToKeycode(hot), kKeyShiftMask | kKeyMod2Mask, on);
371  gVirtualX->GrabKey(fId, gVirtualX->KeysymToKeycode(hot), kKeyLockMask | kKeyMod2Mask, on);
372  gVirtualX->GrabKey(fId, gVirtualX->KeysymToKeycode(hot), kKeyShiftMask | kKeyLockMask | kKeyMod2Mask, on);
373  }
374 }
375 
376 
377 ////////////////////////////////////////////////////////////////////////////////
378 /// If on kTRUE bind hot keys, otherwise remove key binding.
379 
381 {
382  const TGMainFrame *main = (TGMainFrame *) GetMainFrame();
383 
384  if (!main || !main->InheritsFrom("TGMainFrame")) return;
385 
386  if (on) {
387  // case unsensitive bindings
388  main->BindKey(this, keycode, kKeyMod1Mask);
389  main->BindKey(this, keycode, kKeyMod1Mask | kKeyShiftMask);
390  main->BindKey(this, keycode, kKeyMod1Mask | kKeyLockMask);
391  main->BindKey(this, keycode, kKeyMod1Mask | kKeyShiftMask | kKeyLockMask);
392 
393  main->BindKey(this, keycode, kKeyMod1Mask | kKeyMod2Mask);
394  main->BindKey(this, keycode, kKeyMod1Mask | kKeyShiftMask | kKeyMod2Mask);
395  main->BindKey(this, keycode, kKeyMod1Mask | kKeyMod2Mask | kKeyLockMask);
396  main->BindKey(this, keycode, kKeyMod1Mask | kKeyShiftMask | kKeyMod2Mask | kKeyLockMask);
397  } else {
398  main->RemoveBind(this, keycode, kKeyMod1Mask);
399  main->RemoveBind(this, keycode, kKeyMod1Mask | kKeyShiftMask);
400  main->RemoveBind(this, keycode, kKeyMod1Mask | kKeyLockMask);
401  main->RemoveBind(this, keycode, kKeyMod1Mask | kKeyShiftMask | kKeyLockMask);
402 
403  main->RemoveBind(this, keycode, kKeyMod1Mask | kKeyMod2Mask);
404  main->RemoveBind(this, keycode, kKeyMod1Mask | kKeyShiftMask | kKeyMod2Mask);
405  main->RemoveBind(this, keycode, kKeyMod1Mask | kKeyMod2Mask | kKeyLockMask);
406  main->RemoveBind(this, keycode, kKeyMod1Mask | kKeyShiftMask | kKeyMod2Mask | kKeyLockMask);
407  }
408 }
409 
410 ////////////////////////////////////////////////////////////////////////////////
411 /// Add popup menu to menu bar. The hot string will be adopted by the
412 /// menubar (actually the menu title) and deleted when possible.
413 /// If before is not 0 the menu will be added before it.
414 
416  TGPopupMenu *before)
417 {
418  TGMenuTitle *t;
419  Int_t keycode;
420 
421  AddFrameBefore(t = new TGMenuTitle(this, s, menu), l, before);
422  fTitles->Add(t); // keep track of menu titles for later cleanup in dtor
423 
424  if ((keycode = t->GetHotKeyCode()) != 0) {
425  BindHotKey(keycode, kTRUE);
426  }
427 }
428 
429 ////////////////////////////////////////////////////////////////////////////////
430 /// Add popup via created before menu title.
431 
433 {
434  Int_t keycode;
435 
436  AddFrameBefore(title, l, before);
437  fTitles->Add(title); // keep track of menu titles for later cleanup in dtor
438 
439  if ((keycode = title->GetHotKeyCode()) != 0) {
440  BindHotKey(keycode, kTRUE);
441  }
442 }
443 
444 ////////////////////////////////////////////////////////////////////////////////
445 /// Add popup menu to menu bar. If before is not 0 the menu will be
446 /// added before it.
447 
448 void TGMenuBar::AddPopup(const char *s, TGPopupMenu *menu, TGLayoutHints *l,
449  TGPopupMenu *before)
450 {
451  AddPopup(new TGHotString(s), menu, l, before);
452 }
453 
454 ////////////////////////////////////////////////////////////////////////////////
455 /// Add popup menu to menu bar.
456 ///
457 /// Comment:
458 /// This method is valid only for horizontal menu bars.
459 /// The most common case is menu bar containing equidistant titles padding left side.
460 /// TGMenuBar *bar;
461 /// bar->AddPopup("title1", 10);
462 /// bar->AddPopup("title2", 10);
463 /// ...
464 ///
465 /// To add equidistant titles padding right side padleft must be 0.
466 /// TGMenuBar *bar;
467 /// bar->AddPopup("title1", 0, 10);
468 /// bar->AddPopup("title2", 0, 10);
469 /// ...
470 ///
471 /// This method guarantee automatic cleanup when menu bar is destroyed.
472 /// Do not delete returned popup-menu
473 
474 TGPopupMenu *TGMenuBar::AddPopup(const TString &s, Int_t padleft, Int_t padright,
475  Int_t padtop, Int_t padbottom)
476 {
477  ULong_t hints = kLHintsTop;
478 
479  if (padleft) {
480  hints |= kLHintsLeft;
481  } else {
482  hints |= kLHintsRight;
483  }
484 
485  TGLayoutHints *l = new TGLayoutHints(hints, padleft, padright,
486  padtop, padbottom);
487  fTrash->Add(l);
488 
490  AddPopup(new TGHotString(s), menu, l, 0);
491  fTrash->Add(menu);
492  return menu;
493 }
494 
495 ////////////////////////////////////////////////////////////////////////////////
496 /// Private version of AddFrame for menubar, to make sure that we
497 /// indeed only add TGMenuTitle objects to it. If before is not 0
498 /// the menu will be added before it.
499 
501  TGPopupMenu *before)
502 {
503  if (!f->InheritsFrom("TGMenuTitle")) {
504  Error("AddFrameBefore", "may only add TGMenuTitle objects to a menu bar");
505  return;
506  }
507 
508  if (!before) {
509  AddFrame(f, l);
510  return;
511  }
512 
513  TGFrameElement *nw;
514 
515  nw = new TGFrameElement;
516  nw->fFrame = f;
517  nw->fLayout = l ? l : fgDefaultHints;
518  nw->fState = 1;
519 
520  TGFrameElement *el;
521  TIter next(fList);
522  while ((el = (TGFrameElement *) next())) {
523  TGMenuTitle *t = (TGMenuTitle *) el->fFrame;
524  if (t->GetMenu() == before) {
525  fList->AddBefore(el, nw);
526  return;
527  }
528  }
529  fList->Add(nw);
530 }
531 
532 ////////////////////////////////////////////////////////////////////////////////
533 /// Return popup menu with the specified name. Returns 0 if menu is
534 /// not found. Returnes menu can be used as "before" in AddPopup().
535 /// Don't use hot key (&) in name.
536 
538 {
539  if (!GetList()) return 0;
540 
541  TGFrameElement *el;
542  TIter next(GetList());
543  TString str = s;
544 
545  while ((el = (TGFrameElement *) next())) {
546  TGMenuTitle *t = (TGMenuTitle *) el->fFrame;
547  if (str == t->GetName())
548  return t->GetMenu();
549  }
550  return 0;
551 }
552 
553 ////////////////////////////////////////////////////////////////////////////////
554 /// Remove popup menu from menu bar. Returned menu has to be deleted by
555 /// the user, or can be re-used in another AddPopup(). Returns 0 if
556 /// menu is not found. Don't use hot key (&) in name.
557 
559 {
560  if (!GetList()) return 0;
561 
562  TGFrameElement *el;
563  TIter next(GetList());
564  TString str = s;
565 
566  while ((el = (TGFrameElement *) next())) {
567  TGMenuTitle *t = (TGMenuTitle *) el->fFrame;
568  if (str == t->GetName()) {
569  Int_t keycode;
570  if ((keycode = t->GetHotKeyCode())) {
571  BindHotKey(keycode, kFALSE); // remove bind
572  }
573  TGPopupMenu *m = t->GetMenu();
574  fTitles->Remove(t);
575  t->DestroyWindow();
576  RemoveFrame(t);
577  delete t;
578  return m;
579  }
580  }
581  return 0;
582 }
583 
584 ////////////////////////////////////////////////////////////////////////////////
585 /// Handle a mouse motion event in a menu bar.
586 
588 {
589  if (fKeyNavigate) return kTRUE;
590 
591  Int_t dummy;
592  Window_t wtarget;
593  TGMenuTitle *target = 0;
594 
595  if (!(event->fState & kButton1Mask))
596  fStick = kFALSE; // use some threshold!
597 
598  gVirtualX->TranslateCoordinates(fId, fId, event->fX, event->fY,
599  dummy, dummy, wtarget);
600  if (wtarget) target = (TGMenuTitle*) fClient->GetWindowById(wtarget);
601 
602  if (fCurrent && target && (target != fCurrent)) {
603  // deactivate all others
604  TGFrameElement *el;
605  TIter next(fList);
606  while ((el = (TGFrameElement *) next()))
607  ((TGMenuTitle*)el->fFrame)->SetState(kFALSE);
608 
609  fStick = kTRUE;
610  fCurrent = target;
611  target->SetState(kTRUE);
612  }
613 
614  return kTRUE;
615 }
616 
617 ////////////////////////////////////////////////////////////////////////////////
618 /// Handle a mouse button event in a menubar.
619 
621 {
622  Int_t dummy;
623  Window_t wtarget;
624  TGMenuTitle *target;
625 
626  // We don't need to check the button number as GrabButton will
627  // only allow button1 events
628 
629  if (event->fType == kButtonPress) {
630 
631  gVirtualX->TranslateCoordinates(fId, fId, event->fX, event->fY,
632  dummy, dummy, wtarget);
633  target = (TGMenuTitle*) fClient->GetWindowById(wtarget);
634 
635  if (target != 0) {
636  fStick = kTRUE;
637 
638  if (target != fCurrent) {
639  // deactivate all others
640  TGFrameElement *el;
641  TIter next(fList);
642  while ((el = (TGFrameElement *) next()))
643  ((TGMenuTitle*)el->fFrame)->SetState(kFALSE);
644 
645  fStick = kTRUE;
646  fCurrent = target;
647  target->SetState(kTRUE);
648 
651  }
652  }
653  }
654 
655  if (event->fType == kButtonRelease) {
656  if (fStick) {
657  fStick = kFALSE;
658  return kTRUE;
659  }
660 
661  TGFrameElement *el;
662  TIter next(fList);
663  while ((el = (TGFrameElement *) next()))
664  ((TGMenuTitle*)el->fFrame)->SetState(kFALSE);
665 
666  gVirtualX->GrabPointer(0, 0, 0, 0, kFALSE); // ungrab pointer
667 
668  if (fCurrent != 0) {
669  target = fCurrent; // tricky, because WaitFor
670  fCurrent = 0;
671  if (!fKeyNavigate)
672  target->DoSendMessage();
673  }
675  }
676 
677  return kTRUE;
678 }
679 
680 ////////////////////////////////////////////////////////////////////////////////
681 /// Handle keyboard events in a menu bar.
682 
684 {
685  TGMenuTitle *target = 0;
686  TGFrameElement *el;
687  void *dummy;
688  Int_t ax, ay;
689  Window_t wdummy;
690  TIter next(fList);
691 
692  if (event->fType == kGKeyPress) {
693  UInt_t keysym;
694  char tmp[2];
695 
696  gVirtualX->LookupString(event, tmp, sizeof(tmp), keysym);
697 
698  if (event->fState & kKeyMod1Mask) {
699  while ((el = (TGFrameElement *) next())) {
700  target = (TGMenuTitle *) el->fFrame;
701  if ((Int_t)event->fCode == target->GetHotKeyCode()) {
702  RequestFocus();
704  break;
705  }
706  }
707  if (el == 0) target = 0;
708  } else {
710 
711  if (fCurrent) {
712  TGFrameElement *cur = 0;
713  TGPopupMenu *menu = 0;
714  next.Reset();
715  el = 0;
716  while ((el = (TGFrameElement *) next())) {
717  if (el->fFrame == fCurrent) {
718  cur = el;
719  menu = ((TGMenuTitle*)el->fFrame)->GetMenu();
720  break;
721  }
722  }
723 
724  if (!menu || !menu->fPoppedUp) return kFALSE;
725 
726  TGMenuEntry *ce = 0;
727 
728  TGPopupMenu* currentMenu = fCurrent->GetMenu();
729  TGMenuEntry* currentEntry = currentMenu->GetCurrent();
730  while ( currentEntry ) {
731  if ( currentEntry->GetType() == kMenuPopup )
732  currentMenu = currentEntry->GetPopup();
733  if ( currentEntry != currentMenu->GetCurrent() )
734  currentEntry = currentMenu->GetCurrent();
735  else
736  currentEntry = 0;
737  }
738 
739  TIter next2(currentMenu->GetListOfEntries());
740 
741  while ((ce = (TGMenuEntry*)next2())) {
742  UInt_t hot = 0;
743  if (ce->GetLabel()) hot = ce->GetLabel()->GetHotChar();
744  if (!hot || (hot != keysym)) continue;
745 
746  currentMenu->Activate(ce);
747  if (ce->GetType() != kMenuPopup) {
748  gVirtualX->GrabPointer(0, 0, 0, 0, kFALSE);
750  currentMenu->fStick = kFALSE;
751  Event_t ev;
752  ev.fType = kButtonRelease;
753  ev.fWindow = currentMenu->GetId();
754  fCurrent = 0;
755  return currentMenu->HandleButton(&ev);
756  }
757  else {
758  gVirtualX->TranslateCoordinates(currentMenu->fId,
759  (ce->fPopup->GetParent())->GetId(),
760  ce->fEx+currentMenu->fMenuWidth, ce->fEy,
761  ax, ay, wdummy);
762 #ifdef R__HAS_COCOA
763  gVirtualX->SetWMTransientHint(ce->fPopup->GetId(), GetId());
764 #endif
765  ce->fPopup->PlaceMenu(ax-5, ay-1, kFALSE, kFALSE);
766  }
767  }
768 
769  ce = menu->GetCurrent();
770  TGPopupMenu *submenu = 0;
771 
772  while (ce && (ce->GetType() == kMenuPopup)) {
773  submenu = ce->GetPopup();
774  if (!submenu->fPoppedUp) break;
775  ce = submenu->GetCurrent();
776  menu = submenu;
777  }
778  switch ((EKeySym)keysym) {
779  case kKey_Left:
780  if ((submenu) && (submenu->fPoppedUp)) {
781  submenu->EndMenu(dummy);
782  break;
783  }
784  el = (TGFrameElement*)fList->Before(cur);
785  if (!el) el = (TGFrameElement*)fList->Last();
786  break;
787  case kKey_Right:
788  if (submenu) {
789  if (submenu->fPoppedUp) {
790  if (!submenu->GetCurrent()) {
791  ce = (TGMenuEntry*)submenu->GetListOfEntries()->First();
792  } else {
793  submenu->EndMenu(dummy);
794  }
795  }
796  else {
797  gVirtualX->TranslateCoordinates(menu->fId,
798  (submenu->GetParent())->GetId(),
799  ce->fEx+menu->fMenuWidth, ce->fEy,
800  ax, ay, wdummy);
801 #ifdef R__HAS_COCOA
802  gVirtualX->SetWMTransientHint(submenu->GetId(), GetId());
803 #endif
804  submenu->PlaceMenu(ax-5, ay-1, kFALSE, kFALSE);
805  }
806  break;
807  }
808  el = (TGFrameElement*)fList->After(cur);
809  if (!el) el = (TGFrameElement*)fList->First();
810  break;
811  case kKey_Up:
812  if (ce) ce = (TGMenuEntry*)menu->GetListOfEntries()->Before(ce);
813  while (ce && ((ce->GetType() == kMenuSeparator) ||
814  (ce->GetType() == kMenuLabel) ||
815  !(ce->GetStatus() & kMenuEnableMask))) {
816  ce = (TGMenuEntry*)menu->GetListOfEntries()->Before(ce);
817  }
818  if (!ce) ce = (TGMenuEntry*)menu->GetListOfEntries()->Last();
819  break;
820  case kKey_Down:
821  if (ce) ce = (TGMenuEntry*)menu->GetListOfEntries()->After(ce);
822  while (ce && ((ce->GetType() == kMenuSeparator) ||
823  (ce->GetType() == kMenuLabel) ||
824  !(ce->GetStatus() & kMenuEnableMask))) {
825  ce = (TGMenuEntry*)menu->GetListOfEntries()->After(ce);
826  }
827  if (!ce) ce = (TGMenuEntry*)menu->GetListOfEntries()->First();
828  break;
829  case kKey_Enter:
830  case kKey_Return: {
831  gVirtualX->GrabPointer(0, 0, 0, 0, kFALSE);
833  menu->fStick = kFALSE;
834  Event_t ev;
835  ev.fType = kButtonRelease;
836  ev.fWindow = menu->GetId();
837  fCurrent = 0;
838  return menu->HandleButton(&ev);
839  }
840  case kKey_Escape:
841  gVirtualX->GrabPointer(0, 0, 0, 0, kFALSE);
843  fStick = kFALSE;
844  fCurrent = 0;
845  return menu->EndMenu(dummy);
846  default:
847  break;
848  }
849  if (ce) menu->Activate(ce);
850 
851  el = el ? el : cur;
852  if (el) target = (TGMenuTitle*)el->fFrame;
853  } else {
854  return kFALSE;
855  }
856  }
857 
858  if (target != 0) {
859  fStick = kTRUE;
860 
861  if (target != fCurrent) {
862  // deactivate all others
863  next.Reset();
864  while ((el = (TGFrameElement *) next()))
865  ((TGMenuTitle*)el->fFrame)->SetState(kFALSE);
866 
867  fCurrent = target;
868  target->SetState(kTRUE);
869  fStick = kTRUE;
870 
873 
874  TGMenuEntry *ptr;
875  TIter nexte(target->GetMenu()->GetListOfEntries());
876 
877  while ((ptr = (TGMenuEntry *) nexte())) {
878  if ((ptr->GetStatus() & kMenuEnableMask) &&
879  !(ptr->GetStatus() & kMenuHideMask) &&
880  (ptr->GetType() != kMenuSeparator) &&
881  (ptr->GetType() != kMenuLabel)) break;
882  }
883  if (ptr)
884  target->GetMenu()->Activate(ptr);
885 
886  return kTRUE;
887  }
888  } else {
889  return kFALSE;
890  }
891  }
892 
893  if (event->fType == kKeyRelease) {
894  if (fStick) {
895  fStick = kFALSE;
896  return kTRUE;
897  }
898  gVirtualX->GrabPointer(0, 0, 0, 0, kFALSE); // ungrab pointer
899 
900  next.Reset();
901  while ((el = (TGFrameElement *) next()))
902  ((TGMenuTitle*)el->fFrame)->SetState(kFALSE);
903 
904  if (fCurrent != 0) {
905  target = fCurrent; // tricky, because WaitFor
906  fCurrent = 0;
907  target->DoSendMessage();
908  }
909  }
910 
911  return kTRUE;
912 }
913 
914 
915 //////////////////////////////////////////////////////////////////////////
916 // //
917 // TGPopupMenu member functions. //
918 // //
919 //////////////////////////////////////////////////////////////////////////
920 
921 ////////////////////////////////////////////////////////////////////////////////
922 /// Create a popup menu.
923 
925  : TGFrame(p, w, h, options | kOwnBackground)
926 {
927  fNormGC = GetDefaultGC()();
933 
934  // We need to change the default context to actually use the
935  // Menu Fonts. [Are we actually changing the global settings?]
936  GCValues_t gcval;
937  gcval.fMask = kGCFont;
938  gcval.fFont = gVirtualX->GetFontHandle(fFontStruct);
939  gVirtualX->ChangeGC(fNormGC, &gcval);
940  gVirtualX->ChangeGC(fSelGC, &gcval);
941 
942  fDelay = 0;
943  fEntryList = new TList;
944 
945  // in case any of these magic values is changes, check also Reposition()
946  fBorderWidth = 3;
947  fMenuHeight = 6;
948  fMenuWidth = 8;
949  fXl = 16;
950  fMsgWindow = p;
951  fStick = kTRUE;
952  fCurrent = 0;
953  fHasGrab = kFALSE;
954  fPoppedUp = kFALSE;
955  fMenuBar = 0;
956  fSplitButton = 0;
957  fEntrySep = 3;
958 
959  SetWindowAttributes_t wattr;
961  wattr.fOverrideRedirect = kTRUE;
962  wattr.fSaveUnder = kTRUE;
963 
964  gVirtualX->ChangeWindowAttributes(fId, &wattr);
965 
967 }
968 
969 ////////////////////////////////////////////////////////////////////////////////
970 /// Delete a popup menu.
971 
973 {
974  gClient->UnregisterPopup(this);
975 
976  if (fEntryList) fEntryList->Delete();
977  delete fEntryList;
978  delete fDelay;
979 }
980 
981 ////////////////////////////////////////////////////////////////////////////////
982 /// Add a menu entry. The hotstring is adopted by the menu (actually by
983 /// the TGMenuEntry) and deleted when possible. A possible picture is
984 /// borrowed from the picture pool and therefore not adopted.
985 /// If before is not 0, the entry will be added before it.
986 
988  const TGPicture *p, TGMenuEntry *before)
989 {
990  if (!s) return;
991  TGMenuEntry *nw = new TGMenuEntry;
992  Ssiz_t tab = s->Index('\t');
993  if (tab > 0) {
994  TString ts(s->Data());
995  TString shortcut = ts(tab+1, s->Length());
996  nw->fShortcut = new TGString(shortcut.Data());
997  nw->fLabel = new TGHotString(*s);
998  nw->fLabel->Remove(tab);
999  }
1000  else {
1001  nw->fLabel = s;
1002  }
1003  nw->fPic = p;
1004  nw->fType = kMenuEntry;
1005  nw->fEntryId = id;
1006  nw->fUserData = ud;
1007  nw->fPopup = 0;
1008  nw->fStatus = kMenuEnableMask;
1009  nw->fEx = 2;
1010  nw->fEy = fMenuHeight-2;
1011 
1012  if (before)
1013  fEntryList->AddBefore(before, nw);
1014  else
1015  fEntryList->Add(nw);
1016 
1017  UInt_t tw, ph = 0, pw = 0;
1018  tw = gVirtualX->TextWidth(fHifontStruct, s->GetString(), s->GetLength());
1019  if (p) {
1020  ph = p->GetHeight();
1021  pw = p->GetWidth();
1022  if (pw+12 > fXl) { fMenuWidth += pw+12-fXl; fXl = pw+12; }
1023  }
1024  if (nw->fShortcut) {
1025  tw += 10;
1026  delete s;
1027  }
1028 
1029  Int_t max_ascent, max_descent;
1030  nw->fEw = tw + pw /*+8*/+18+12;
1032  gVirtualX->GetFontProperties(fHifontStruct, max_ascent, max_descent);
1033  nw->fEh = max_ascent + max_descent + fEntrySep;
1034  if (nw->fEh < ph+fEntrySep) nw->fEh = ph+fEntrySep;
1035  fMenuHeight += nw->fEh;
1036 
1037  if (before)
1038  Reposition();
1039  else
1041 }
1042 
1043 ////////////////////////////////////////////////////////////////////////////////
1044 /// Add a menu entry. The string s in not adopted.
1045 /// If before is not 0, the entry will be added before it.
1046 
1047 void TGPopupMenu::AddEntry(const char *s, Int_t id, void *ud,
1048  const TGPicture *p, TGMenuEntry *before)
1049 {
1050  AddEntry(new TGHotString(s), id, ud, p, before);
1051 }
1052 
1053 ////////////////////////////////////////////////////////////////////////////////
1054 /// Add a menu separator to the menu.
1055 /// If before is not 0, the entry will be added before it.
1056 
1058 {
1059  TGMenuEntry *nw = new TGMenuEntry;
1060 
1061  nw->fLabel = 0;
1062  nw->fPic = 0;
1063  nw->fType = kMenuSeparator;
1064  nw->fEntryId = -1;
1065  nw->fUserData = 0;
1066  nw->fPopup = 0;
1067  nw->fStatus = kMenuEnableMask;
1068  nw->fEx = 2;
1069  nw->fEy = fMenuHeight-2;
1070 
1071  if (before)
1072  fEntryList->AddBefore(before, nw);
1073  else
1074  fEntryList->Add(nw);
1075 
1076  nw->fEw = 0;
1077  nw->fEh = 4;
1078  fMenuHeight += nw->fEh;
1079 
1080  if (before)
1081  Reposition();
1082  else
1084 }
1085 
1086 ////////////////////////////////////////////////////////////////////////////////
1087 /// Add a menu label to the menu. The hotstring is adopted by the menu
1088 /// (actually by the TGMenuEntry) and deleted when possible. A possible
1089 /// picture is borrowed from the picture pool and therefore not adopted.
1090 /// If before is not 0, the entry will be added before it.
1091 
1093  TGMenuEntry *before)
1094 {
1095  TGMenuEntry *nw = new TGMenuEntry;
1096 
1097  nw->fLabel = s;
1098  nw->fPic = p;
1099  nw->fType = kMenuLabel;
1100  nw->fEntryId = -1;
1101  nw->fUserData = 0;
1102  nw->fPopup = 0;
1104  nw->fEx = 2;
1105  nw->fEy = fMenuHeight-2;
1106 
1107  if (before)
1108  fEntryList->AddBefore(before, nw);
1109  else
1110  fEntryList->Add(nw);
1111 
1112  UInt_t tw, ph = 0, pw = 0;
1113  tw = gVirtualX->TextWidth(fHifontStruct, s->GetString(), s->GetLength());
1114  if (p) {
1115  ph = p->GetHeight();
1116  pw = p->GetWidth();
1117  if (pw+12 > fXl) { fMenuWidth += pw+12-fXl; fXl = pw+12; }
1118  }
1119 
1120  Int_t max_ascent, max_descent;
1121  nw->fEw = tw + pw /*+8*/+18+12;
1123  gVirtualX->GetFontProperties(fHifontStruct, max_ascent, max_descent);
1124  nw->fEh = max_ascent + max_descent + fEntrySep;
1125  if (nw->fEh < ph+fEntrySep) nw->fEh = ph+fEntrySep;
1126  fMenuHeight += nw->fEh;
1127 
1128  if (before)
1129  Reposition();
1130  else
1132 }
1133 
1134 ////////////////////////////////////////////////////////////////////////////////
1135 /// Add a menu label to the menu. The string s in not adopted.
1136 /// If before is not 0, the entry will be added before it.
1137 
1138 void TGPopupMenu::AddLabel(const char *s, const TGPicture *p,
1139  TGMenuEntry *before)
1140 {
1141  AddLabel(new TGHotString(s), p, before);
1142 }
1143 
1144 ////////////////////////////////////////////////////////////////////////////////
1145 /// Add a (cascading) popup menu to a popup menu. The hotstring is adopted
1146 /// by the menu (actually by the TGMenuEntry) and deleted when possible.
1147 /// If before is not 0, the entry will be added before it.
1148 
1150  TGMenuEntry *before, const TGPicture *p)
1151 {
1152  TGMenuEntry *nw = new TGMenuEntry;
1153 
1154  nw->fLabel = s;
1155  nw->fPic = p;
1156  nw->fType = kMenuPopup;
1157  nw->fEntryId = -2;
1158  nw->fUserData = 0;
1159  nw->fPopup = popup;
1160  nw->fStatus = kMenuEnableMask;
1161  nw->fEx = 2;
1162  nw->fEy = fMenuHeight-2;
1163 
1164  if (before)
1165  fEntryList->AddBefore(before, nw);
1166  else
1167  fEntryList->Add(nw);
1168 
1169  UInt_t tw = gVirtualX->TextWidth(fHifontStruct, s->GetString(),
1170  s->GetLength());
1171 
1172  UInt_t ph = 0, pw = 8;
1173  if (p) {
1174  ph = p->GetHeight();
1175  pw = p->GetWidth();
1176  if (pw+12 > fXl) { fMenuWidth += pw+12-fXl; fXl = pw+12; }
1177  }
1178  Int_t max_ascent, max_descent;
1179  nw->fEw = tw + pw+18+12;
1181  gVirtualX->GetFontProperties(fHifontStruct, max_ascent, max_descent);
1182  nw->fEh = max_ascent + max_descent + fEntrySep;
1183  if (nw->fEh < ph+fEntrySep) nw->fEh = ph+fEntrySep;
1184  fMenuHeight += nw->fEh;
1185 
1186  if (before)
1187  Reposition();
1188  else
1190 }
1191 
1192 ////////////////////////////////////////////////////////////////////////////////
1193 /// Add a (cascading) popup menu to a popup menu. The string s is not
1194 /// adopted. If before is not 0, the entry will be added before it.
1195 
1196 void TGPopupMenu::AddPopup(const char *s, TGPopupMenu *popup,
1197  TGMenuEntry *before, const TGPicture *p)
1198 {
1199  AddPopup(new TGHotString(s), popup, before, p);
1200 }
1201 
1202 ////////////////////////////////////////////////////////////////////////////////
1203 /// Reposition entries in popup menu. Called after menu item has been
1204 /// hidden or removed or inserted at a specified location.
1205 
1207 {
1208  // in case any of these magic values is changes, check also the ctor.
1209  fMenuHeight = 6;
1210  fMenuWidth = 8;
1211  fXl = 16;
1212 
1213  TGMenuEntry *ptr;
1214  TIter next(fEntryList);
1215 
1216  while ((ptr = (TGMenuEntry *) next())) {
1217 
1218  if (ptr->fStatus & kMenuHideMask) continue;
1219 
1220  if (ptr->fPic) {
1221  UInt_t pw = ptr->fPic->GetWidth();
1222  if (pw+12 > fXl) { fMenuWidth += pw+12-fXl; fXl = pw+12; }
1223  }
1224  ptr->fEx = 2;
1225  ptr->fEy = fMenuHeight-2;
1227  fMenuHeight += ptr->fEh;
1228  }
1230 }
1231 
1232 ////////////////////////////////////////////////////////////////////////////////
1233 /// Popup a popup menu. If stick mode is true keep the menu up. If
1234 /// grab_pointer is true the pointer will be grabbed, which means that
1235 /// all pointer events will go to the popup menu, independent of in
1236 /// which window the pointer is.
1237 
1238 void TGPopupMenu::PlaceMenu(Int_t x, Int_t y, Bool_t stick_mode, Bool_t grab_pointer)
1239 {
1240  void *ud;
1241  EndMenu(ud);
1242 
1243  Int_t rx, ry;
1244  UInt_t rw, rh;
1245 
1246  fStick = stick_mode;
1247  fCurrent = 0;
1248 
1249  // Parent is root window for a popup menu
1250  gVirtualX->GetWindowSize(fParent->GetId(), rx, ry, rw, rh);
1251 
1252  if (x < 0) x = 0;
1253  if (x + fMenuWidth > rw) x = rw - fMenuWidth;
1254  if (y < 0) y = 0;
1255  if (y + fMenuHeight > rh) y = rh - fMenuHeight;
1256 
1257  Move(x, y);
1258  MapRaised();
1259 
1260  if (grab_pointer) {
1263  fHasGrab = kTRUE;
1264  } else {
1265  fHasGrab = kFALSE;
1266  }
1267 
1268  fPoppedUp = kTRUE;
1269  PoppedUp();
1271 
1272  fClient->RegisterPopup(this);
1273 }
1274 
1275 ////////////////////////////////////////////////////////////////////////////////
1276 /// Close menu and return ID of selected menu item.
1277 /// In case of cascading menus, recursively close all menus.
1278 
1279 Int_t TGPopupMenu::EndMenu(void *&userData)
1280 {
1281  Int_t id;
1282 
1283  if (fDelay) fDelay->Remove();
1284 
1285  // destroy any cascaded children and get any ID
1286 
1287  if (fCurrent != 0) {
1288 
1289  // deactivate the entry
1291 
1292  if ((fCurrent->fType == kMenuPopup) && fCurrent->fPopup) {
1293  id = fCurrent->fPopup->EndMenu(userData);
1294  } else {
1295  // return the ID if the entry is enabled, otherwise -1
1296  if (fCurrent->fStatus & kMenuEnableMask) {
1297  id = fCurrent->fEntryId;
1298  userData = fCurrent->fUserData;
1299  } else {
1300  id = -1;
1301  userData = 0;
1302  }
1303  }
1304 
1305  } else {
1306  // if no entry selected...
1307  id = -1;
1308  userData = 0;
1309  }
1310 
1311  // then unmap itself
1312  UnmapWindow();
1313 
1314  gClient->UnregisterPopup(this);
1316 
1317  if (fPoppedUp) {
1318  fPoppedUp = kFALSE;
1319  PoppedDown();
1320  }
1321 
1322  return id;
1323 }
1324 
1325 ////////////////////////////////////////////////////////////////////////////////
1326 /// Handle button event in the popup menu.
1327 
1329 {
1330  int id;
1331  void *ud = 0;
1332 
1333  if (event->fType == kButtonRelease) {
1334  if (fStick) {
1335  fStick = kFALSE;
1336  return kTRUE;
1337  }
1338  //if (fCurrent != 0)
1339  // if (fCurrent->fType == kMenuPopup) return kTRUE;
1340  id = EndMenu(ud);
1341  if (fHasGrab) gVirtualX->GrabPointer(0, 0, 0, 0, kFALSE); // ungrab
1342  if (fCurrent != 0) {
1344  if (fCurrent->fStatus & kMenuEnableMask) {
1346  (Long_t)ud);
1347  Activated(id);
1348  }
1349  }
1350  }
1351  return kTRUE;
1352 }
1353 
1354 ////////////////////////////////////////////////////////////////////////////////
1355 /// Handle pointer crossing event in popup menu.
1356 
1358 {
1359  if (event->fType == kEnterNotify) {
1360 
1361  TGMenuEntry *ptr;
1362  TIter next(fEntryList);
1363 
1364  while ((ptr = (TGMenuEntry *) next())) {
1365  if (ptr->fStatus & kMenuHideMask) continue;
1366 
1367  if ((event->fX >= ptr->fEx) && (event->fX <= ptr->fEx+(Int_t)fMenuWidth-10) &&
1368  (event->fY >= ptr->fEy) && (event->fY <= ptr->fEy+(Int_t)ptr->fEh))
1369  break;
1370  }
1371  Activate(ptr);
1372  } else {
1373  Activate((TGMenuEntry*)0);
1374  }
1377 
1378  return kTRUE;
1379 }
1380 
1381 ////////////////////////////////////////////////////////////////////////////////
1382 /// Handle pointer motion event in popup menu.
1383 
1385 {
1386  TGFrame::HandleMotion(event);
1387  static Int_t twice = 0;
1388  TGMenuEntry *ptr;
1389  TIter next(fEntryList);
1390 
1391  if (twice < 2) {
1392  // hack to eat mouse move events generated by Windows when
1393  // pressing/releasing a mouse button
1394  ++twice;
1395  }
1396  else {
1397  twice = 0;
1398  fStick = kFALSE; // be careful with this, use some threshold
1399  }
1400  while ((ptr = (TGMenuEntry *) next())) {
1401  if (ptr->fStatus & kMenuHideMask) continue;
1402 
1403  if ((event->fX >= ptr->fEx) && (event->fX <= ptr->fEx+(Int_t)fMenuWidth-4) && //fMenuWidth-10??
1404  (event->fY >= ptr->fEy) && (event->fY <= ptr->fEy+(Int_t)ptr->fEh))
1405  break;
1406  }
1407  Activate(ptr);
1408 
1409  return kTRUE;
1410 }
1411 
1412 ////////////////////////////////////////////////////////////////////////////////
1413 /// Activate a menu entry in a popup menu.
1414 
1416 {
1417  if (entry == fCurrent) return;
1418 
1419  //-- Deactivate the current entry
1420 
1421  if (fCurrent != 0) {
1422  void *ud;
1423  if (entry == 0 && fCurrent->fType == kMenuPopup) return;
1424  if ((fCurrent->fType == kMenuPopup) && fCurrent->fPopup)
1425  fCurrent->fPopup->EndMenu(ud);
1428  }
1429 
1430  if (fDelay) fDelay->Remove();
1431 
1432  //-- Activate the new one
1433 
1434  if (entry) {
1435  entry->fStatus |= kMenuActiveMask;
1436  DrawEntry(entry);
1437  if (entry->fType == kMenuPopup) {
1438  if (!fDelay) fDelay = new TPopupDelayTimer(this, 350);
1439  fDelay->Reset();
1441  // after delay expires it will popup the cascading popup menu
1442  // iff it is still the current entry
1443  } else if (entry->fType == kMenuEntry) {
1444  // test...
1446  entry->fEntryId, (Long_t)entry->fUserData);
1447  Highlighted(entry->fEntryId);
1448  }
1449  }
1450  fCurrent = entry;
1451 }
1452 
1453 ////////////////////////////////////////////////////////////////////////////////
1454 /// If TPopupDelayTimer times out popup cascading popup menu (if it is
1455 /// still the current entry).
1456 
1458 {
1459  if (fCurrent != 0) {
1460  if ((fCurrent->fType == kMenuPopup) && fCurrent->fPopup) {
1461  Int_t ax, ay;
1462  Window_t wdummy;
1463 
1464  gVirtualX->TranslateCoordinates(fId,
1465  (fCurrent->fPopup->GetParent())->GetId(),
1467  ax, ay, wdummy);
1468 #ifdef R__HAS_COCOA
1469  gVirtualX->SetWMTransientHint(fCurrent->fPopup->GetId(), GetId());
1470 #endif
1471  fCurrent->fPopup->PlaceMenu(ax-5, ay-1, kFALSE, kFALSE);
1472  }
1473  }
1474  fDelay->Remove();
1475 
1476  return kTRUE;
1477 }
1478 
1479 ////////////////////////////////////////////////////////////////////////////////
1480 /// Draw popup menu.
1481 
1483 {
1485 
1486  TGMenuEntry *ptr;
1487  TIter next(fEntryList);
1488 
1489  while ((ptr = (TGMenuEntry *) next()))
1490  DrawEntry(ptr);
1491 }
1492 
1493 ////////////////////////////////////////////////////////////////////////////////
1494 /// Draw popup menu entry.
1495 
1497 {
1498  FontStruct_t font;
1499  GCValues_t gcval;
1500 
1501  if (entry->fStatus & kMenuHideMask)
1502  return;
1503 
1504  if (entry->fStatus & kMenuDefaultMask) {
1505  font = fHifontStruct;
1506  gcval.fMask = kGCFont;
1507  gcval.fFont = gVirtualX->GetFontHandle(font);
1508  gVirtualX->ChangeGC(fNormGC, &gcval);
1509  gVirtualX->ChangeGC(fSelGC, &gcval);
1510  } else {
1511  font = fFontStruct;
1512  }
1513 
1514  UInt_t tw = 0;
1515  int max_ascent, max_descent;
1516  gVirtualX->GetFontProperties(font, max_ascent, max_descent);
1517  int tx = entry->fEx + fXl;
1518  // center text
1519  int offset = (entry->fEh - (max_ascent + max_descent)) / 2;
1520  int ty = entry->fEy + max_ascent + offset - 1;
1521  if (entry->fShortcut)
1522  tw = 7 + gVirtualX->TextWidth(fFontStruct, entry->fShortcut->Data(), entry->fShortcut->Length());
1523 
1524  switch (entry->fType) {
1525  case kMenuPopup:
1526  case kMenuLabel:
1527  case kMenuEntry:
1528  if ((entry->fStatus & kMenuActiveMask) && entry->fType != kMenuLabel) {
1529  gVirtualX->FillRectangle(fId, fSelbackGC, entry->fEx+1, entry->fEy-1,
1530  fMenuWidth-6, entry->fEh);
1531  if (gClient->GetStyle() > 1)
1532  gVirtualX->DrawRectangle(fId, GetShadowGC()(), entry->fEx+1, entry->fEy-2,
1533  fMenuWidth-7, entry->fEh);
1534  if (entry->fType == kMenuPopup)
1535  DrawTrianglePattern(fSelGC, fMenuWidth-10, entry->fEy+fEntrySep, fMenuWidth-6, entry->fEy+11);
1536  if (entry->fStatus & kMenuCheckedMask)
1537  DrawCheckMark(fSelGC, 6, entry->fEy+fEntrySep, 14, entry->fEy+11);
1538  if (entry->fStatus & kMenuRadioMask)
1539  DrawRCheckMark(fSelGC, 6, entry->fEy+fEntrySep, 14, entry->fEy+11);
1540  if (entry->fPic != 0)
1541  entry->fPic->Draw(fId, fSelGC, 8, entry->fEy+1);
1542  entry->fLabel->Draw(fId,
1543  (entry->fStatus & kMenuEnableMask) ? fSelGC : GetShadowGC()(),
1544  tx, ty);
1545  if (entry->fShortcut)
1546  entry->fShortcut->Draw(fId, (entry->fStatus & kMenuEnableMask) ? fSelGC : GetShadowGC()(),
1547  fMenuWidth - tw, ty);
1548  } else {
1549  if (gClient->GetStyle() > 1)
1550  gVirtualX->DrawRectangle(fId, GetBckgndGC()(), entry->fEx+1, entry->fEy-2,
1551  fMenuWidth-7, entry->fEh);
1552  gVirtualX->FillRectangle(fId, GetBckgndGC()(), entry->fEx+1, entry->fEy-1,
1553  fMenuWidth-6, entry->fEh);
1554  if (entry->fType == kMenuPopup)
1555  DrawTrianglePattern(fNormGC, fMenuWidth-10, entry->fEy+fEntrySep, fMenuWidth-6, entry->fEy+11);
1556  if (entry->fStatus & kMenuCheckedMask)
1557  DrawCheckMark(fNormGC, 6, entry->fEy+fEntrySep, 14, entry->fEy+11);
1558  if (entry->fStatus & kMenuRadioMask)
1559  DrawRCheckMark(fNormGC, 6, entry->fEy+fEntrySep, 14, entry->fEy+11);
1560  if (entry->fPic != 0)
1561  entry->fPic->Draw(fId, fNormGC, 8, entry->fEy+1);
1562  if (entry->fStatus & kMenuEnableMask) {
1563  entry->fLabel->Draw(fId, fNormGC, tx, ty);
1564  if (entry->fShortcut)
1565  entry->fShortcut->Draw(fId, fNormGC, fMenuWidth - tw, ty);
1566  } else {
1567  entry->fLabel->Draw(fId, GetHilightGC()(), tx+1, ty+1);
1568  entry->fLabel->Draw(fId, GetShadowGC()(), tx, ty);
1569  if (entry->fShortcut) {
1570  entry->fShortcut->Draw(fId, GetHilightGC()(), fMenuWidth - tw+1, ty+1);
1571  entry->fShortcut->Draw(fId, GetShadowGC()(), fMenuWidth - tw, ty);
1572  }
1573  }
1574  }
1575  break;
1576 
1577  case kMenuSeparator:
1578  gVirtualX->DrawLine(fId, GetShadowGC()(), 2, entry->fEy, fMenuWidth-fEntrySep, entry->fEy);
1579  gVirtualX->DrawLine(fId, GetHilightGC()(), 2, entry->fEy+1, fMenuWidth-fEntrySep, entry->fEy+1);
1580  break;
1581  }
1582 
1583  // restore font
1584  if (entry->fStatus & kMenuDefaultMask) {
1585  gcval.fFont = gVirtualX->GetFontHandle(fFontStruct);
1586  gVirtualX->ChangeGC(fNormGC, &gcval);
1587  gVirtualX->ChangeGC(fSelGC, &gcval);
1588  }
1589 }
1590 
1591 ////////////////////////////////////////////////////////////////////////////////
1592 /// Draw border round popup menu.
1593 
1595 {
1596  if (gClient->GetStyle() > 0) {
1597  // new modern (flat) version
1598  gVirtualX->DrawLine(fId, GetShadowGC()(), 0, 0, 0, fMenuHeight-1);
1599  gVirtualX->DrawLine(fId, GetShadowGC()(), 0, fMenuHeight-1, fMenuWidth-1, fMenuHeight-1);
1600  gVirtualX->DrawLine(fId, GetShadowGC()(), fMenuWidth-1, fMenuHeight-1, fMenuWidth-1, 0);
1601  gVirtualX->DrawLine(fId, GetShadowGC()(), fMenuWidth-1, 0, 0, 0);
1602  }
1603  else {
1604  // old (raised frame) version
1605  gVirtualX->DrawLine(fId, GetBckgndGC()(), 0, 0, fMenuWidth-2, 0);
1606  gVirtualX->DrawLine(fId, GetBckgndGC()(), 0, 0, 0, fMenuHeight-2);
1607  gVirtualX->DrawLine(fId, GetHilightGC()(), 1, 1, fMenuWidth-fEntrySep, 1);
1608  gVirtualX->DrawLine(fId, GetHilightGC()(), 1, 1, 1, fMenuHeight-fEntrySep);
1609 
1610  gVirtualX->DrawLine(fId, GetShadowGC()(), 1, fMenuHeight-2, fMenuWidth-2, fMenuHeight-2);
1611  gVirtualX->DrawLine(fId, GetShadowGC()(), fMenuWidth-2, fMenuHeight-2, fMenuWidth-2, 1);
1612  gVirtualX->DrawLine(fId, GetBlackGC()(), 0, fMenuHeight-1, fMenuWidth-1, fMenuHeight-1);
1613  gVirtualX->DrawLine(fId, GetBlackGC()(), fMenuWidth-1, fMenuHeight-1, fMenuWidth-1, 0);
1614  }
1615 }
1616 
1617 ////////////////////////////////////////////////////////////////////////////////
1618 /// Draw triangle pattern. Used for menu entries that are of type
1619 /// kMenuPopup (i.e. cascading menus).
1620 
1622  Int_t r, Int_t b)
1623 {
1624  Point_t points[3];
1625 
1626  int m = (t + b) >> 1;
1627 
1628  points[0].fX = l;
1629  points[0].fY = t;
1630  points[1].fX = l;
1631  points[1].fY = b;
1632  points[2].fX = r;
1633  points[2].fY = m;
1634 
1635  gVirtualX->FillPolygon(fId, gc, points, 3);
1636 }
1637 
1638 ////////////////////////////////////////////////////////////////////////////////
1639 /// Draw check mark. Used for checked button type menu entries.
1640 
1642 {
1643  Segment_t seg[6];
1644 
1645  t = (t + b - 8) >> 1; ++t;
1646 
1647  seg[0].fX1 = 1+l; seg[0].fY1 = 3+t; seg[0].fX2 = 3+l; seg[0].fY2 = 5+t;
1648  seg[1].fX1 = 1+l; seg[1].fY1 = 4+t; seg[1].fX2 = 3+l; seg[1].fY2 = 6+t;
1649  seg[2].fX1 = 1+l; seg[2].fY1 = 5+t; seg[2].fX2 = 3+l; seg[2].fY2 = 7+t;
1650  seg[3].fX1 = 3+l; seg[3].fY1 = 5+t; seg[3].fX2 = 7+l; seg[3].fY2 = 1+t;
1651  seg[4].fX1 = 3+l; seg[4].fY1 = 6+t; seg[4].fX2 = 7+l; seg[4].fY2 = 2+t;
1652  seg[5].fX1 = 3+l; seg[5].fY1 = 7+t; seg[5].fX2 = 7+l; seg[5].fY2 = 3+t;
1653 
1654  gVirtualX->DrawSegments(fId, gc, seg, 6);
1655 }
1656 
1657 ////////////////////////////////////////////////////////////////////////////////
1658 /// Draw radio check mark. Used for radio button type menu entries.
1659 
1661 {
1662  Segment_t seg[5];
1663 
1664  t = (t + b - 5) >> 1; ++t;
1665  l = (l + r - 5) >> 1; ++l;
1666 
1667  seg[0].fX1 = 1+l; seg[0].fY1 = 0+t; seg[0].fX2 = 3+l; seg[0].fY2 = 0+t;
1668  seg[1].fX1 = 0+l; seg[1].fY1 = 1+t; seg[1].fX2 = 4+l; seg[1].fY2 = 1+t;
1669  seg[2].fX1 = 0+l; seg[2].fY1 = 2+t; seg[2].fX2 = 4+l; seg[2].fY2 = 2+t;
1670  seg[3].fX1 = 0+l; seg[3].fY1 = 3+t; seg[3].fX2 = 4+l; seg[3].fY2 = 3+t;
1671  seg[4].fX1 = 1+l; seg[4].fY1 = 4+t; seg[4].fX2 = 3+l; seg[4].fY2 = 4+t;
1672 
1673  gVirtualX->DrawSegments(fId, gc, seg, 5);
1674 }
1675 
1676 ////////////////////////////////////////////////////////////////////////////////
1677 /// Set default entry (default entries are drawn with bold text).
1678 
1680 {
1681  TGMenuEntry *ptr;
1682  TIter next(fEntryList);
1683 
1684  while ((ptr = (TGMenuEntry *) next())) {
1685  if (ptr->fEntryId == id)
1686  ptr->fStatus |= kMenuDefaultMask;
1687  else
1688  ptr->fStatus &= ~kMenuDefaultMask;
1689  }
1690 }
1691 
1692 ////////////////////////////////////////////////////////////////////////////////
1693 /// Enable entry. By default entries are enabled.
1694 
1696 {
1697  TGMenuEntry *ptr;
1698  TIter next(fEntryList);
1699 
1700  while ((ptr = (TGMenuEntry *) next()))
1701  if (ptr->fEntryId == id) {
1702  ptr->fStatus |= kMenuEnableMask;
1703  if (ptr->fStatus & kMenuHideMask) {
1704  ptr->fStatus &= ~kMenuHideMask;
1705  Reposition();
1706  }
1707  break;
1708  }
1709 }
1710 
1711 ////////////////////////////////////////////////////////////////////////////////
1712 /// Disable entry (disabled entries appear in a sunken relieve).
1713 
1715 {
1716  TGMenuEntry *ptr;
1717  TIter next(fEntryList);
1718 
1719  while ((ptr = (TGMenuEntry *) next()))
1720  if (ptr->fEntryId == id) { ptr->fStatus &= ~kMenuEnableMask; break; }
1721 }
1722 
1723 ////////////////////////////////////////////////////////////////////////////////
1724 /// Return true if menu entry is enabled.
1725 
1727 {
1728  TGMenuEntry *ptr;
1729  TIter next(fEntryList);
1730 
1731  while ((ptr = (TGMenuEntry *) next()))
1732  if (ptr->fEntryId == id)
1733  return (ptr->fStatus & kMenuEnableMask) ? kTRUE : kFALSE;
1734  return kFALSE;
1735 }
1736 
1737 ////////////////////////////////////////////////////////////////////////////////
1738 /// Hide entry (hidden entries are not shown in the menu).
1739 /// To enable a hidden entry call EnableEntry().
1740 
1742 {
1743  TGMenuEntry *ptr;
1744  TIter next(fEntryList);
1745 
1746  while ((ptr = (TGMenuEntry *) next()))
1747  if (ptr->fEntryId == id) {
1748  ptr->fStatus |= kMenuHideMask;
1749  ptr->fStatus &= ~kMenuEnableMask;
1750  Reposition();
1751  break;
1752  }
1753 }
1754 
1755 ////////////////////////////////////////////////////////////////////////////////
1756 /// Return true if menu entry is hidden.
1757 
1759 {
1760  TGMenuEntry *ptr;
1761  TIter next(fEntryList);
1762 
1763  while ((ptr = (TGMenuEntry *) next()))
1764  if (ptr->fEntryId == id)
1765  return (ptr->fStatus & kMenuHideMask) ? kTRUE : kFALSE;
1766  return kFALSE;
1767 }
1768 
1769 ////////////////////////////////////////////////////////////////////////////////
1770 /// Check a menu entry (i.e. add a check mark in front of it).
1771 
1773 {
1774  TGMenuEntry *ptr;
1775  TIter next(fEntryList);
1776 
1777  while ((ptr = (TGMenuEntry *) next()))
1778  if (ptr->fEntryId == id) { ptr->fStatus |= kMenuCheckedMask; break; }
1779 }
1780 
1781 ////////////////////////////////////////////////////////////////////////////////
1782 /// Check a menu entry (i.e. add a check mark in front of it).
1783 /// The input argument is user data associated with entry
1784 
1785 void TGPopupMenu::CheckEntryByData(void *user_data)
1786 {
1787  TGMenuEntry *ptr;
1788  TIter next(fEntryList);
1789 
1790  while ((ptr = (TGMenuEntry *) next()))
1791  if (ptr->fUserData == user_data) { ptr->fStatus |= kMenuCheckedMask; break; }
1792 }
1793 
1794 ////////////////////////////////////////////////////////////////////////////////
1795 /// Uncheck menu entry (i.e. remove check mark).
1796 
1798 {
1799  TGMenuEntry *ptr;
1800  TIter next(fEntryList);
1801 
1802  while ((ptr = (TGMenuEntry *) next()))
1803  if (ptr->fEntryId == id) { ptr->fStatus &= ~kMenuCheckedMask; break; }
1804 }
1805 
1806 ////////////////////////////////////////////////////////////////////////////////
1807 /// Uncheck all entries.
1808 
1810 {
1811  TGMenuEntry *ptr;
1812  TIter next(fEntryList);
1813 
1814  while ((ptr = (TGMenuEntry *) next())) {
1815  ptr->fStatus &= ~kMenuCheckedMask;
1816  }
1817 }
1818 
1819 ////////////////////////////////////////////////////////////////////////////////
1820 /// Uncheck a menu entry (i.e. remove check mark in front of it).
1821 /// The input argument is user data associated with entry
1822 
1823 void TGPopupMenu::UnCheckEntryByData(void *user_data)
1824 {
1825  TGMenuEntry *ptr;
1826  TIter next(fEntryList);
1827 
1828  while ((ptr = (TGMenuEntry *) next()))
1829  if (ptr->fUserData == user_data) { ptr->fStatus &= ~kMenuCheckedMask; break; }
1830 }
1831 
1832 ////////////////////////////////////////////////////////////////////////////////
1833 /// Return true if menu item is checked.
1834 
1836 {
1837  TGMenuEntry *ptr;
1838  TIter next(fEntryList);
1839 
1840  while ((ptr = (TGMenuEntry *) next()))
1841  if (ptr->fEntryId == id)
1842  return (ptr->fStatus & kMenuCheckedMask) ? kTRUE : kFALSE;
1843  return kFALSE;
1844 }
1845 
1846 ////////////////////////////////////////////////////////////////////////////////
1847 /// Radio-select entry (note that they cannot be unselected,
1848 /// the selection must be moved to another entry instead).
1849 
1850 void TGPopupMenu::RCheckEntry(Int_t id, Int_t IDfirst, Int_t IDlast)
1851 {
1852  TGMenuEntry *ptr;
1853  TIter next(fEntryList);
1854 
1855  while ((ptr = (TGMenuEntry *) next()))
1856  if (ptr->fEntryId == id)
1858  else
1859  if (ptr->fEntryId >= IDfirst && ptr->fEntryId <= IDlast) {
1860  ptr->fStatus &= ~kMenuRadioMask;
1861  ptr->fStatus |= kMenuRadioEntryMask;
1862  }
1863 }
1864 
1865 ////////////////////////////////////////////////////////////////////////////////
1866 /// Return true if menu item has radio check mark.
1867 
1869 {
1870  TGMenuEntry *ptr;
1871  TIter next(fEntryList);
1872 
1873  while ((ptr = (TGMenuEntry *) next()))
1874  if (ptr->fEntryId == id)
1875  return (ptr->fStatus & kMenuRadioMask) ? kTRUE : kFALSE;
1876  return kFALSE;
1877 }
1878 
1879 ////////////////////////////////////////////////////////////////////////////////
1880 /// Find entry with specified id. Use the returned entry in DeleteEntry()
1881 /// or as the "before" item in the AddXXXX() methods. Returns 0 if entry
1882 /// is not found. To find entries that don't have an id like the separators,
1883 /// use the GetListOfEntries() method to get the complete entry
1884 /// list and iterate over it and check the type of each entry
1885 /// to find the separators.
1886 
1888 {
1889  TGMenuEntry *ptr;
1890  TIter next(fEntryList);
1891 
1892  while ((ptr = (TGMenuEntry *) next()))
1893  if (ptr->fEntryId == id)
1894  return ptr;
1895  return 0;
1896 }
1897 
1898 ////////////////////////////////////////////////////////////////////////////////
1899 /// Find entry with specified name. Name must match the original
1900 /// name without hot key symbol, like "Print" and not "&Print".
1901 /// Use the returned entry in DeleteEntry() or as the "before" item
1902 /// in the AddXXXX() methods. Returns 0 if entry is not found.
1903 /// To find entries that don't have a name like the separators,
1904 /// use the GetListOfEntries() method to get the complete entry
1905 /// list and iterate over it and check the type of each entry
1906 /// to find the separators.
1907 
1909 {
1910  return (TGMenuEntry*) fEntryList->FindObject(s);
1911 }
1912 
1913 ////////////////////////////////////////////////////////////////////////////////
1914 /// Delete entry with specified id from menu.
1915 
1917 {
1918  TGMenuEntry *ptr;
1919  TIter next(fEntryList);
1920 
1921  while ((ptr = (TGMenuEntry *) next()))
1922  if (ptr->fEntryId == id) {
1923  fEntryList->Remove(ptr);
1924  delete ptr;
1925  Reposition();
1926  if (fCurrent == ptr)
1927  fCurrent = 0;
1928  return;
1929  }
1930 }
1931 
1932 ////////////////////////////////////////////////////////////////////////////////
1933 /// Delete specified entry from menu.
1934 
1936 {
1937  TGMenuEntry *ptr;
1938  TIter next(fEntryList);
1939 
1940  while ((ptr = (TGMenuEntry *) next()))
1941  if (ptr == entry) {
1942  fEntryList->Remove(ptr);
1943  delete ptr;
1944  Reposition();
1945  if (fCurrent == ptr)
1946  fCurrent = 0;
1947  return;
1948  }
1949 }
1950 
1951 ////////////////////////////////////////////////////////////////////////////////
1952 /// Return default graphics context.
1953 
1955 {
1956  if (!fgDefaultGC)
1957  fgDefaultGC = gClient->GetResourcePool()->GetFrameGC();
1958  return *fgDefaultGC;
1959 }
1960 
1961 ////////////////////////////////////////////////////////////////////////////////
1962 /// Return the selection graphics context in use.
1963 
1965 {
1966  if (!fgDefaultSelectedGC)
1967  fgDefaultSelectedGC = gClient->GetResourcePool()->GetSelectedGC();
1968  return *fgDefaultSelectedGC;
1969 }
1970 
1971 ////////////////////////////////////////////////////////////////////////////////
1972 /// Return the selection background graphics context in use.
1973 
1975 {
1977  fgDefaultSelectedBackgroundGC = gClient->GetResourcePool()->GetSelectedBckgndGC();
1979 }
1980 
1981 ////////////////////////////////////////////////////////////////////////////////
1982 /// Return the default font structure in use.
1983 
1985 {
1986  if (!fgDefaultFont)
1987  fgDefaultFont = gClient->GetResourcePool()->GetMenuFont();
1988  return fgDefaultFont->GetFontStruct();
1989 }
1990 
1991 ////////////////////////////////////////////////////////////////////////////////
1992 /// Return the font structure in use for highlighted menu entries.
1993 
1995 {
1996  if (!fgHilightFont)
1997  fgHilightFont = gClient->GetResourcePool()->GetMenuHiliteFont();
1998  return fgHilightFont->GetFontStruct();
1999 }
2000 
2001 
2002 //////////////////////////////////////////////////////////////////////////
2003 // //
2004 // TGMenuTitle member functions. //
2005 // //
2006 //////////////////////////////////////////////////////////////////////////
2007 
2008 ////////////////////////////////////////////////////////////////////////////////
2009 /// Create a menu title. This object is created by a menu bar when adding
2010 /// a popup menu. The menu title adopts the hotstring.
2011 
2013  GContext_t norm, FontStruct_t font, UInt_t options)
2014  : TGFrame(p, 1, 1, options)
2015 {
2016  fLabel = s;
2017  fMenu = menu;
2018  fFontStruct = font;
2020  fNormGC = norm;
2021  fState = kFALSE;
2022  fTitleId = -1;
2024  fTitleData = 0;
2025 
2026  Int_t hotchar;
2027  if (s && (hotchar = s->GetHotChar()) != 0)
2028  fHkeycode = gVirtualX->KeysymToKeycode(hotchar);
2029  else
2030  fHkeycode = 0;
2031 
2032  UInt_t tw = 0;
2033  Int_t max_ascent, max_descent;
2034  if (fLabel)
2035  tw = gVirtualX->TextWidth(fFontStruct, fLabel->GetString(), fLabel->GetLength());
2036  gVirtualX->GetFontProperties(fFontStruct, max_ascent, max_descent);
2037 
2038  Resize(tw + 8, max_ascent + max_descent + 7);
2039 
2040  if (p && p->InheritsFrom(TGMenuBar::Class())) {
2041  TGMenuBar *bar = (TGMenuBar*)p;
2042  fMenu->SetMenuBar(bar);
2043  }
2044 }
2045 
2046 ////////////////////////////////////////////////////////////////////////////////
2047 /// Set state of menu title.
2048 
2050 {
2051  fState = state;
2052  if (state) {
2053  if (fMenu != 0) {
2054  Int_t ax, ay;
2055  Window_t wdummy;
2056 
2057  gVirtualX->TranslateCoordinates(fId, (fMenu->GetParent())->GetId(),
2058  0, 0, ax, ay, wdummy);
2059 
2060  // place the menu just under the window:
2061 #ifdef R__HAS_COCOA
2062  gVirtualX->SetWMTransientHint(fMenu->GetId(), GetId());
2063 #endif
2064  fMenu->PlaceMenu(ax-1, ay+fHeight, kTRUE, kFALSE); //kTRUE);
2065  }
2066  } else {
2067  if (fMenu != 0) {
2069  }
2070  }
2072  fClient->NeedRedraw(this);
2073 }
2074 
2075 ////////////////////////////////////////////////////////////////////////////////
2076 /// Draw a menu title.
2077 
2079 {
2081 
2082  int x, y, max_ascent, max_descent;
2083  x = y = 4;
2084 
2085  gVirtualX->GetFontProperties(fFontStruct, max_ascent, max_descent);
2086 
2087  if (fState) {
2088  gVirtualX->SetForeground(fNormGC, GetDefaultSelectedBackground());
2089  if (gClient->GetStyle() > 1) {
2090  gVirtualX->FillRectangle(fId, fNormGC, 1, 2, fWidth-3, fHeight-4);
2091  gVirtualX->DrawRectangle(fId, GetShadowGC()(), 1, 1, fWidth-3, fHeight-3);
2092  }
2093  else {
2094  gVirtualX->FillRectangle(fId, fNormGC, 0, 0, fWidth, fHeight);
2095  }
2096  gVirtualX->SetForeground(fNormGC, GetForeground());
2097  fLabel->Draw(fId, fSelGC, x, y + max_ascent);
2098  } else {
2099  // Use same background color than the menu bar
2101  if (fMenu && fMenu->fMenuBar && fMenu->fMenuBar->GetBackground() != back)
2102  back = fMenu->fMenuBar->GetBackground();
2103  gVirtualX->SetForeground(fNormGC, back);
2104  if (gClient->GetStyle() > 1) {
2105  gVirtualX->DrawRectangle(fId, fNormGC, 1, 1, fWidth-3, fHeight-3);
2106  gVirtualX->FillRectangle(fId, fNormGC, 1, 2, fWidth-3, fHeight-4);
2107  }
2108  else {
2109  gVirtualX->FillRectangle(fId, fNormGC, 0, 0, fWidth, fHeight);
2110  }
2111  gVirtualX->SetForeground(fNormGC, fTextColor);
2112  fLabel->Draw(fId, fNormGC, x, y + max_ascent);
2113  if (fTextColor != GetForeground())
2114  gVirtualX->SetForeground(fNormGC, GetForeground());
2115  }
2116 }
2117 
2118 ////////////////////////////////////////////////////////////////////////////////
2119 /// Send final selected menu item to be processed.
2120 
2122 {
2123  if (fMenu)
2124  if (fTitleId != -1) {
2126  (Long_t)fTitleData);
2128  }
2129 }
2130 
2131 ////////////////////////////////////////////////////////////////////////////////
2132 /// Return default font structure in use.
2133 
2135 {
2136  if (!fgDefaultFont)
2137  fgDefaultFont = gClient->GetResourcePool()->GetMenuFont();
2138  return fgDefaultFont->GetFontStruct();
2139 }
2140 
2141 ////////////////////////////////////////////////////////////////////////////////
2142 /// Return default graphics context in use.
2143 
2145 {
2146  if (!fgDefaultGC)
2147  fgDefaultGC = gClient->GetResourcePool()->GetFrameGC();
2148  return *fgDefaultGC;
2149 }
2150 
2151 ////////////////////////////////////////////////////////////////////////////////
2152 /// Return default selection graphics context in use.
2153 
2155 {
2156  if (!fgDefaultSelectedGC)
2157  fgDefaultSelectedGC = gClient->GetResourcePool()->GetSelectedGC();
2158  return *fgDefaultSelectedGC;
2159 }
2160 
2161 ////////////////////////////////////////////////////////////////////////////////
2162 /// Save a popup menu widget as a C++ statement(s) on output stream out.
2163 
2164 void TGPopupMenu::SavePrimitive(std::ostream &out, Option_t *option /*= ""*/)
2165 {
2166  char quote = '"';
2167 
2168  out << " TGPopupMenu *";
2169  out << GetName() << " = new TGPopupMenu(gClient->GetDefaultRoot()"
2170  << "," << GetWidth() << "," << GetHeight() << "," << GetOptionString() << ");" << std::endl;
2171 
2172  Bool_t hasradio = kFALSE;
2173  Int_t r_first, r_last, r_active;
2174  r_active = r_first = r_last = -1;
2175 
2176  TGMenuEntry *mentry;
2177  TIter next(GetListOfEntries());
2178 
2179  while ((mentry = (TGMenuEntry *) next())) {
2180  const char *text;
2181  Int_t i, lentext, hotpos;
2182  char shortcut[80];
2183  char *outext;
2184 
2185  switch (mentry->GetType()) {
2186  case kMenuEntry:
2187  text = mentry->GetName();
2188  lentext = mentry->fLabel->GetLength();
2189  hotpos = mentry->fLabel->GetHotPos();
2190  outext = new char[lentext+2];
2191  i=0;
2192  while (text && lentext) {
2193  if (i == hotpos-1) {
2194  outext[i] = '&';
2195  i++;
2196  }
2197  outext[i] = *text;
2198  i++; text++; lentext--;
2199  }
2200  outext[i]=0;
2201  if (mentry->fShortcut) {
2202  snprintf(shortcut, 80, "\\t%s", mentry->GetShortcutText());
2203  }
2204  else {
2205  memset(shortcut, 0, 80);
2206  }
2207 
2208  out << " " << GetName() << "->AddEntry(" << quote
2209  << gSystem->ExpandPathName(gSystem->UnixPathName(outext)) // can be a file name
2210  << shortcut
2211  << quote << "," << mentry->GetEntryId();
2212  if (mentry->fUserData) {
2213  out << "," << mentry->fUserData;
2214  }
2215  if (mentry->fPic) {
2216  out << ",gClient->GetPicture(" << quote
2218  << quote << ")";
2219  }
2220  out << ");" << std::endl;
2221  delete [] outext;
2222  break;
2223  case kMenuPopup:
2224  out << std::endl;
2225  out << " // cascaded menu " << quote << mentry->GetName() << quote <<std::endl;
2226  mentry->fPopup->SavePrimitive(out, option);
2227  text = mentry->GetName();
2228  lentext = mentry->fLabel->GetLength();
2229  hotpos = mentry->fLabel->GetHotPos();
2230  outext = new char[lentext+2];
2231  i=0;
2232  while (text && lentext) {
2233  if (i == hotpos-1) {
2234  outext[i] = '&';
2235  i++;
2236  }
2237  outext[i] = *text;
2238  i++; text++; lentext--;
2239  }
2240  outext[i]=0;
2241 
2242  out << " " << GetName() << "->AddPopup(" << quote
2243  << outext << quote << "," << mentry->fPopup->GetName()
2244  << ");" << std::endl;
2245  delete [] outext;
2246  break;
2247  case kMenuLabel:
2248  out << " " << GetName() << "->AddLabel(" << quote
2249  << mentry->GetName() << quote;
2250  if (mentry->fPic) {
2251  out << ",gClient->GetPicture(" << quote
2252  << mentry->fPic->GetName()
2253  << quote << ")";
2254  }
2255  out << ");" << std::endl;
2256  break;
2257  case kMenuSeparator:
2258  out << " " << GetName() << "->AddSeparator();" << std::endl;
2259  break;
2260  }
2261 
2262  if (!(mentry->GetStatus() & kMenuEnableMask)) {
2263  out<< " " << GetName() << "->DisableEntry(" << mentry->GetEntryId()
2264  << ");" << std::endl;
2265  }
2266  if (mentry->GetStatus() & kMenuHideMask) {
2267  out<< " " << GetName() << "->HideEntry(" << mentry->GetEntryId()
2268  << ");" << std::endl;
2269  }
2270  if (mentry->GetStatus() & kMenuCheckedMask) {
2271  out<< " " << GetName() << "->CheckEntry(" << mentry->GetEntryId()
2272  << ");" << std::endl;
2273  }
2274  if (mentry->GetStatus() & kMenuDefaultMask) {
2275  out<< " "<< GetName() << "->DefaultEntry(" << mentry->GetEntryId()
2276  << ");" << std::endl;
2277  }
2278  if (mentry->GetStatus() & kMenuRadioEntryMask) {
2279  if (hasradio) {
2280  r_last = mentry->GetEntryId();
2281  if (IsEntryRChecked(mentry->GetEntryId())) r_active = mentry->GetEntryId();
2282  }
2283  else {
2284  r_first = mentry->GetEntryId();
2285  hasradio = kTRUE;
2286  if (IsEntryRChecked(mentry->GetEntryId())) r_active = mentry->GetEntryId();
2287  }
2288  } else if (hasradio) {
2289  out << " " << GetName() << "->RCheckEntry(" << r_active << "," << r_first
2290  << "," << r_last << ");" << std::endl;
2291  hasradio = kFALSE;
2292  r_active = r_first = r_last = -1;
2293  }
2294  }
2295 }
2296 
2297 ////////////////////////////////////////////////////////////////////////////////
2298 /// Save a title menu widget as a C++ statement(s) on output stream out.
2299 
2300 void TGMenuTitle::SavePrimitive(std::ostream &out, Option_t *option /*= ""*/)
2301 {
2302  char quote = '"';
2303 
2304  out << std::endl;
2305  out << " // " << quote << fLabel->GetString() << quote <<" menu" << std::endl;
2306 
2307  fMenu->SavePrimitive(out, option);
2308 
2309  const char *text = fLabel->GetString();
2310  Int_t lentext = fLabel->GetLength();
2311  Int_t hotpos = fLabel->GetHotPos();
2312  char *outext = new char[lentext+2];
2313  Int_t i=0;
2314  while (lentext) {
2315  if (i == hotpos-1) {
2316  outext[i] = '&';
2317  i++;
2318  }
2319  outext[i] = *text;
2320  i++; text++; lentext--;
2321  }
2322  outext[i]=0;
2323  out << " " << fParent->GetName() << "->AddPopup(" << quote << outext
2324  << quote << "," << fMenu->GetName();
2325 
2326  delete [] outext;
2327 }
2328 
2329 ////////////////////////////////////////////////////////////////////////////////
2330 /// Save a menu bar widget as a C++ statement(s) on output stream out.
2331 
2332 void TGMenuBar::SavePrimitive(std::ostream &out, Option_t *option /*= ""*/)
2333 {
2334  out << std::endl;
2335  out << " // menu bar" << std::endl;
2336 
2337  out << " TGMenuBar *";
2338  out << GetName() << " = new TGMenuBar(" << fParent->GetName()
2339  << "," << GetWidth() << "," << GetHeight() << "," << GetOptionString() << ");" << std::endl;
2340  if (option && strstr(option, "keep_names"))
2341  out << " " << GetName() << "->SetName(\"" << GetName() << "\");" << std::endl;
2342 
2343  if (!fList) return;
2344 
2345  TGFrameElement *el;
2346  TIter next(fList);
2347 
2348  while ((el = (TGFrameElement *)next())) {
2349  el->fFrame->SavePrimitive(out, option);
2350  el->fLayout->SavePrimitive(out, option);
2351  out << ");" << std::endl;
2352  }
2353 }
TGFrameElement * GetLastOnLeft()
Returns the last visible menu title on the left of the &#39;>>&#39; in the menu bar.
Definition: TGMenu.cxx:265
virtual void AddTitle(TGMenuTitle *title, TGLayoutHints *l, TGPopupMenu *before=0)
Add popup via created before menu title.
Definition: TGMenu.cxx:432
EMenuEntryType fType
Definition: TGMenu.h:77
virtual Bool_t HandleCrossing(Event_t *event)
Handle pointer crossing event in popup menu.
Definition: TGMenu.cxx:1357
static const TGGC & GetDefaultSelectedGC()
Return the selection graphics context in use.
Definition: TGMenu.cxx:1964
Handle_t FontStruct_t
Definition: GuiTypes.h:38
const TGWindow * fParent
Definition: TGWindow.h:37
virtual void Resize(UInt_t w=0, UInt_t h=0)
Resize the frame.
Definition: TGFrame.cxx:587
Short_t fX1
Definition: GuiTypes.h:351
TGSplitButton * fSplitButton
Definition: TGMenu.h:147
UInt_t fMenuWidth
Definition: TGMenu.h:136
Bool_t fState
Definition: TGMenu.h:255
Cursor_t GetGrabCursor() const
virtual void Delete(Option_t *option="")
Remove all objects from the list AND delete all heap based objects.
Definition: TList.cxx:467
TGLayoutHints * fMenuBarMoreLayout
Definition: TGMenu.h:316
auto * m
Definition: textangle.C:8
const char * GetName() const
Returns name of object.
Definition: TGPicture.h:62
Int_t fBorderWidth
Definition: TGFrame.h:140
virtual void SetState(Bool_t state)
Set state of menu title.
Definition: TGMenu.cxx:2049
virtual TGMenuEntry * GetEntry(Int_t id)
Find entry with specified id.
Definition: TGMenu.cxx:1887
const Mask_t kKeyMod2Mask
Definition: GuiTypes.h:198
void Reset()
Reset the timer.
Definition: TTimer.cxx:157
ULong_t GetLayoutHints() const
Definition: TGLayout.h:89
static FontStruct_t GetDefaultFontStruct()
Return default font structure in use.
Definition: TGMenu.cxx:2134
TGString * fShortcut
Definition: TGMenu.h:82
virtual Bool_t HandleButton(Event_t *event)
Handle button event in the popup menu.
Definition: TGMenu.cxx:1328
FontH_t fFont
Definition: GuiTypes.h:241
void AddInput(UInt_t emask)
Add events specified in the emask to the events the frame should handle.
Definition: TGFrame.cxx:321
const char Option_t
Definition: RtypesCore.h:62
virtual void UnCheckEntries()
Uncheck all entries.
Definition: TGMenu.cxx:1809
const Mask_t kKeyShiftMask
Definition: GuiTypes.h:194
const Mask_t kKeyMod1Mask
Definition: GuiTypes.h:197
GContext_t fSelGC
Definition: TGMenu.h:259
TGPopupMenu * GetMenu() const
Definition: TGMenu.h:287
static const TGGC & GetHilightGC()
Get highlight color graphics context.
Definition: TGFrame.cxx:737
TGHotString * GetLabel() const
Definition: TGMenu.h:101
UInt_t GetHeight() const
Definition: TGFrame.h:272
TH1 * h
Definition: legend2.C:5
TList * fTitles
Definition: TGMenu.h:310
virtual void DisableEntry(Int_t id)
Disable entry (disabled entries appear in a sunken relieve).
Definition: TGMenu.cxx:1714
const Mask_t kLeaveWindowMask
Definition: GuiTypes.h:167
TList * fNeededSpace
Definition: TGMenu.h:319
virtual TObject * Last() const
Return the last object in the list. Returns 0 when list is empty.
Definition: TList.cxx:689
UInt_t fEh
Definition: TGMenu.h:80
Int_t fEx
Definition: TGMenu.h:79
UInt_t fEntrySep
Definition: TGMenu.h:148
virtual Bool_t IsEntryChecked(Int_t id)
Return true if menu item is checked.
Definition: TGMenu.cxx:1835
static const TGGC & GetDefaultSelectedBackgroundGC()
Return the selection background graphics context in use.
Definition: TGMenu.cxx:1974
virtual void UnCheckEntry(Int_t id)
Uncheck menu entry (i.e. remove check mark).
Definition: TGMenu.cxx:1797
const TGResourcePool * GetResourcePool() const
Definition: TGClient.h:133
static constexpr double bar
Ssiz_t Index(const char *pat, Ssiz_t i=0, ECaseCompare cmp=kExact) const
Definition: TString.h:585
Int_t fY
Definition: GuiTypes.h:177
Handle_t GContext_t
Definition: GuiTypes.h:37
virtual void Reposition()
Reposition entries in popup menu.
Definition: TGMenu.cxx:1206
Basic string class.
Definition: TString.h:125
#define gClient
Definition: TGClient.h:166
static const TGGC * fgDefaultSelectedGC
Definition: TGMenu.h:264
TGMenuTitle * fCurrent
Definition: TGMenu.h:309
TList * fTrash
Definition: TGMenu.h:313
Bool_t fKeyNavigate
Definition: TGButton.h:404
virtual void DoRedraw()
Draw a menu title.
Definition: TGMenu.cxx:2078
Short_t fX
Definition: GuiTypes.h:356
int Int_t
Definition: RtypesCore.h:41
bool Bool_t
Definition: RtypesCore.h:59
Short_t fY1
Definition: GuiTypes.h:351
Int_t MK_MSG(EWidgetMessageTypes msg, EWidgetMessageTypes submsg)
virtual void AddEntry(TGHotString *s, Int_t id, void *ud=0, const TGPicture *p=0, TGMenuEntry *before=0)
Add a menu entry.
Definition: TGMenu.cxx:987
TGMenuBar * fMenuBar
Definition: TGMenu.h:146
static const TGFont * fgDefaultFont
Definition: TGMenu.h:150
virtual void SavePrimitive(std::ostream &out, Option_t *option="")
Save a title menu widget as a C++ statement(s) on output stream out.
Definition: TGMenu.cxx:2300
virtual void Activated(Int_t id)
Definition: TGMenu.h:232
UInt_t fEw
Definition: TGMenu.h:80
UInt_t GetWidth() const
Definition: TGFrame.h:271
TGHotString * fLabel
Definition: TGMenu.h:252
virtual void MapRaised()
Definition: TGFrame.h:252
virtual void DrawEntry(TGMenuEntry *entry)
Draw popup menu entry.
Definition: TGMenu.cxx:1496
Window_t fWindow
Definition: GuiTypes.h:175
Int_t GetHotChar() const
Definition: TGString.h:67
UInt_t GetHeight() const
Definition: TGPicture.h:64
Bool_t fStick
Definition: TGMenu.h:312
Handle_t GetId() const
Definition: TGObject.h:47
virtual void AddSeparator(TGMenuEntry *before=0)
Add a menu separator to the menu.
Definition: TGMenu.cxx:1057
Int_t fState
Definition: TGLayout.h:120
virtual void Layout()
Layout the elements of the composite frame.
Definition: TGFrame.cxx:1239
const char * GetName() const
Return unique name, used in SavePrimitive methods.
Definition: TGMenu.h:288
TList * fEntryList
Definition: TGMenu.h:130
void Reset()
Definition: TCollection.h:250
FontStruct_t fFontStruct
Definition: TGMenu.h:257
virtual void AddLast(TObject *obj)
Add object at the end of the list.
Definition: TList.cxx:149
virtual TObject * FindObject(const char *name) const
Delete a TObjLink object.
Definition: TList.cxx:574
virtual void RemoveFrame(TGFrame *f)
Remove frame from composite frame.
Definition: TGFrame.cxx:1131
virtual const char * UnixPathName(const char *unixpathname)
Convert from a Unix pathname to a local pathname.
Definition: TSystem.cxx:1044
void Draw(Option_t *="")
Default Draw method for all objects.
Definition: TGPicture.h:57
virtual void Layout()
Calculates whether the >> menu must be shown or not and which menu titles are hidden.
Definition: TGMenu.cxx:190
Short_t fX2
Definition: GuiTypes.h:351
const Mask_t kPointerMotionMask
Definition: GuiTypes.h:162
virtual void DoRedraw()
Redraw the frame.
Definition: TGFrame.cxx:412
const TGPicture * fPic
Definition: TGMenu.h:83
TGLayoutHints * fLayout
Definition: TGLayout.h:121
virtual void DrawBorder()
Draw border round popup menu.
Definition: TGMenu.cxx:1594
virtual Bool_t IsEntryRChecked(Int_t id)
Return true if menu item has radio check mark.
Definition: TGMenu.cxx:1868
Int_t fStatus
Definition: TGMenu.h:78
void RegisterPopup(TGWindow *w)
Add a popup menu to the list of popups.
Definition: TGClient.cxx:530
virtual void Highlighted(Int_t id)
Definition: TGMenu.h:231
Double_t x[n]
Definition: legend1.C:17
ULong_t Pixel_t
Definition: GuiTypes.h:39
virtual void AddLabel(TGHotString *s, const TGPicture *p=0, TGMenuEntry *before=0)
Add a menu label to the menu.
Definition: TGMenu.cxx:1092
void Class()
Definition: Class.C:29
static Pixel_t GetDefaultFrameBackground()
Get default frame background.
Definition: TGFrame.cxx:665
Cursor_t fDefaultCursor
Definition: TGMenu.h:144
Int_t fEy
Definition: TGMenu.h:79
TList * fOutLayouts
Definition: TGMenu.h:318
Short_t fY2
Definition: GuiTypes.h:351
const TGWindow * fMsgWindow
Definition: TGMenu.h:145
TGPopupMenu * fPopup
Definition: TGMenu.h:84
virtual void UnCheckEntryByData(void *user_data)
Uncheck a menu entry (i.e.
Definition: TGMenu.cxx:1823
const Mask_t kGCFont
Definition: GuiTypes.h:299
virtual Pixel_t GetForeground() const
Return frame foreground color.
Definition: TGFrame.cxx:285
void DrawTrianglePattern(GContext_t gc, Int_t l, Int_t t, Int_t r, Int_t b)
Draw triangle pattern.
Definition: TGMenu.cxx:1621
const Mask_t kKeyLockMask
Definition: GuiTypes.h:195
static FontStruct_t GetDefaultFontStruct()
Return the default font structure in use.
Definition: TGMenu.cxx:1984
int main(int argc, char **argv)
virtual void SendMessage(const TGWindow *w, Long_t msg, Long_t parm1, Long_t parm2)
Send message (i.e.
Definition: TGFrame.cxx:627
virtual const TGWindow * GetMainFrame() const
Returns top level main frame.
Definition: TGWindow.cxx:133
void * fTitleData
Definition: TGMenu.h:254
virtual TList * GetList() const
Definition: TGFrame.h:369
virtual void SetMenuBar(TGMenuBar *bar)
Definition: TGMenu.h:220
virtual Int_t EndMenu(void *&userData)
Close menu and return ID of selected menu item.
Definition: TGMenu.cxx:1279
virtual Bool_t BindKey(const TGWindow *w, Int_t keycode, Int_t modifier) const
Bind key to a window.
Definition: TGFrame.cxx:1595
Bool_t fStick
Definition: TGMenu.h:132
XFontStruct * id
Definition: TGX11.cxx:108
Int_t GetHotPos() const
Definition: TGString.h:68
virtual void RequestFocus()
Definition: TGWindow.h:98
static const TGFont * fgHilightFont
Definition: TGMenu.h:151
virtual void EnableEntry(Int_t id)
Enable entry. By default entries are enabled.
Definition: TGMenu.cxx:1695
virtual Bool_t Notify()
Notify when timer times out.
Definition: TTimer.cxx:143
EMenuEntryType GetType() const
Definition: TGMenu.h:99
A doubly linked list.
Definition: TList.h:44
virtual void AddFrameBefore(TGFrame *f, TGLayoutHints *l=0, TGPopupMenu *before=0)
Private version of AddFrame for menubar, to make sure that we indeed only add TGMenuTitle objects to ...
Definition: TGMenu.cxx:500
point * points
Definition: X3DBuffer.c:20
virtual Bool_t HandleTimer(TTimer *t)
If TPopupDelayTimer times out popup cascading popup menu (if it is still the current entry)...
Definition: TGMenu.cxx:1457
const Mask_t kButtonPressMask
Definition: GuiTypes.h:160
Bool_t fOverrideRedirect
Definition: GuiTypes.h:106
void Remove()
Definition: TTimer.h:85
void DrawCheckMark(GContext_t gc, Int_t l, Int_t t, Int_t r, Int_t b)
Draw check mark. Used for checked button type menu entries.
Definition: TGMenu.cxx:1641
Bool_t Connect(const char *signal, const char *receiver_class, void *receiver, const char *slot)
Non-static method is used to connect from the signal of this object to the receiver slot...
Definition: TQObject.cxx:867
Named parameter, streamable and storable.
Definition: TParameter.h:37
void * fUserData
Definition: TGMenu.h:76
virtual void BindHotKey(Int_t keycode, Bool_t on=kTRUE)
If on kTRUE bind hot keys, otherwise remove key binding.
Definition: TGMenu.cxx:380
Bool_t fWithExt
Definition: TGMenu.h:317
TGPopupMenu * fMenu
Definition: TGMenu.h:251
FontStruct_t fFontStruct
Definition: TGMenu.h:142
virtual void SavePrimitive(std::ostream &out, Option_t *option="")
Save a frame widget as a C++ statement(s) on output stream out.
Definition: TGFrame.cxx:3187
Int_t fHkeycode
Definition: TGMenu.h:256
TList * fList
Definition: TGFrame.h:351
TGPopupMenu * fMenuMore
Definition: TGMenu.h:315
virtual TObject * First() const
Return the first object in the list. Returns 0 when list is empty.
Definition: TList.cxx:655
virtual Bool_t IsEntryEnabled(Int_t id)
Return true if menu entry is enabled.
Definition: TGMenu.cxx:1726
virtual Int_t GetStatus() const
Definition: TGMenu.h:98
UInt_t fOptions
Definition: TGFrame.h:141
ROOT::R::TRInterface & r
Definition: Object.C:4
TGMenuTitle(const TGMenuTitle &)
UInt_t fMenuHeight
Definition: TGMenu.h:137
virtual UInt_t GetDefaultWidth() const
Definition: TGFrame.h:371
R__EXTERN TSystem * gSystem
Definition: TSystem.h:540
const Mask_t kWASaveUnder
Definition: GuiTypes.h:149
Cursor_t fDefaultCursor
Definition: TGMenu.h:311
EGEventType fType
Definition: GuiTypes.h:174
virtual void HideEntry(Int_t id)
Hide entry (hidden entries are not shown in the menu).
Definition: TGMenu.cxx:1741
virtual Bool_t HandleMotion(Event_t *)
Definition: TGFrame.h:211
TQConnection class is an internal class, used in the object communication mechanism.
Definition: TQConnection.h:37
virtual Bool_t HandleKey(Event_t *event)
Handle keyboard events in a menu bar.
Definition: TGMenu.cxx:683
static const TGGC * fgDefaultGC
Definition: TGMenu.h:152
TTimer * fDelay
Definition: TGMenu.h:138
virtual void SavePrimitive(std::ostream &out, Option_t *option="")
Save a primitive as a C++ statement(s) on output stream "out".
Definition: TGLayout.cxx:1003
virtual TObject * Remove(TObject *obj)
Remove object from the list.
Definition: TList.cxx:818
Bool_t fHasGrab
Definition: TGMenu.h:133
UInt_t fXl
Definition: TGMenu.h:135
virtual Bool_t InheritsFrom(const char *classname) const
Returns kTRUE if object inherits from class "classname".
Definition: TObject.cxx:443
virtual const char * GetName() const
Return unique name, used in SavePrimitive methods.
Definition: TGWindow.cxx:221
Int_t GetPadLeft() const
Definition: TGLayout.h:92
virtual TObject * Before(const TObject *obj) const
Returns the object before object obj.
Definition: TList.cxx:368
static const TGGC & GetDefaultGC()
Return default graphics context in use.
Definition: TGMenu.cxx:2144
static TGLayoutHints * fgDefaultHints
Definition: TGFrame.h:356
GContext_t fNormGC
Definition: TGMenu.h:139
unsigned int UInt_t
Definition: RtypesCore.h:42
virtual void BindKeys(Bool_t on=kTRUE)
If on kTRUE bind arrow, popup menu hot keys, otherwise remove key bindings.
Definition: TGMenu.cxx:334
GContext_t fSelbackGC
Definition: TGMenu.h:141
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition: TObject.cxx:880
const Handle_t kNone
Definition: GuiTypes.h:87
Ssiz_t Length() const
Definition: TString.h:386
TGFrame * fFrame
Definition: TGLayout.h:119
virtual void Draw(Drawable_t id, GContext_t gc, Int_t x, Int_t y)
Draw a hot string and underline the hot character.
Definition: TGString.cxx:170
Handles synchronous and a-synchronous timer events.
Definition: TTimer.h:51
static const TGFont * fgDefaultFont
Definition: TGMenu.h:263
virtual Pixel_t GetBackground() const
Definition: TGFrame.h:239
TGPopupMenu * GetPopup() const
Definition: TGMenu.h:100
virtual TObject * After(const TObject *obj) const
Returns the object after object obj.
Definition: TList.cxx:327
virtual Bool_t HandleMotion(Event_t *event)
Handle pointer motion event in popup menu.
Definition: TGMenu.cxx:1384
static const TGGC & GetBlackGC()
Get black graphics context.
Definition: TGFrame.cxx:717
virtual void AddBefore(const TObject *before, TObject *obj)
Insert object before object before in the list.
Definition: TList.cxx:193
virtual Bool_t HandleButton(Event_t *event)
Handle a mouse button event in a menubar.
Definition: TGMenu.cxx:620
virtual void RCheckEntry(Int_t id, Int_t IDfirst, Int_t IDlast)
Radio-select entry (note that they cannot be unselected, the selection must be moved to another entry...
Definition: TGMenu.cxx:1850
static const TGGC * fgDefaultSelectedGC
Definition: TGMenu.h:153
static constexpr double ms
static const TGGC * fgDefaultSelectedBackgroundGC
Definition: TGMenu.h:154
#define gVirtualX
Definition: TVirtualX.h:350
UInt_t fWidth
Definition: TGFrame.h:134
virtual void Move(Int_t x, Int_t y)
Move frame.
Definition: TGFrame.cxx:575
virtual TGPopupMenu * RemovePopup(const char *s)
Remove popup menu from menu bar.
Definition: TGMenu.cxx:558
const char * GetString() const
Definition: TGString.h:40
const Bool_t kFALSE
Definition: RtypesCore.h:88
virtual void PoppedDown()
Definition: TGMenu.h:230
EKeySym
Definition: KeySymbols.h:25
TGDimension GetSize() const
Definition: TGFrame.h:277
Int_t fTitleId
Definition: TGMenu.h:253
TString & Remove(Ssiz_t pos)
Definition: TString.h:619
virtual void DoSendMessage()
Send final selected menu item to be processed.
Definition: TGMenu.cxx:2121
const Mask_t kEnterWindowMask
Definition: GuiTypes.h:166
long Long_t
Definition: RtypesCore.h:50
int Ssiz_t
Definition: RtypesCore.h:63
static const TGGC & GetDefaultSelectedGC()
Return default selection graphics context in use.
Definition: TGMenu.cxx:2154
Pixel_t fTextColor
Definition: TGMenu.h:258
virtual TGMenuEntry * GetCurrent() const
Definition: TGMenu.h:211
#define ClassImp(name)
Definition: Rtypes.h:359
virtual void CheckEntryByData(void *user_data)
Check a menu entry (i.e.
Definition: TGMenu.cxx:1785
TText * text
const Mask_t kButtonReleaseMask
Definition: GuiTypes.h:161
const char * GetName() const
Returns name of object.
Definition: TGMenu.h:96
Int_t GetPadRight() const
Definition: TGLayout.h:93
Definition: TGFont.h:149
const Mask_t kWAOverrideRedirect
Definition: GuiTypes.h:148
unsigned long ULong_t
Definition: RtypesCore.h:51
static RooMathCoreReg dummy
Int_t fEntryId
Definition: TGMenu.h:75
FontStruct_t GetFontStruct() const
Definition: TGFont.h:193
Double_t y[n]
Definition: legend1.C:17
FontStruct_t fHifontStruct
Definition: TGMenu.h:143
static constexpr double s
Bool_t Disconnect(const char *signal=0, void *receiver=0, const char *slot=0)
Disconnects signal of this object from slot of receiver.
Definition: TQObject.cxx:1025
UInt_t GetWidth() const
Definition: TGPicture.h:63
you should not use this method at all Int_t Int_t Double_t Double_t Double_t e
Definition: TRolke.cxx:630
UInt_t fHeight
Definition: TGFrame.h:135
virtual ~TGMenuBar()
Delete menu bar object.
Definition: TGMenu.cxx:152
virtual void AddFrame(TGFrame *f, TGLayoutHints *l=0)
Add frame to the composite frame using the specified layout hints.
Definition: TGFrame.cxx:1099
virtual Bool_t HandleMotion(Event_t *event)
Handle a mouse motion event in a menu bar.
Definition: TGMenu.cxx:587
const TGWindow * GetParent() const
Definition: TGWindow.h:85
virtual void MapSubwindows()
Map all sub windows that are part of the composite frame.
Definition: TGFrame.cxx:1146
TList * GetListOfSignals() const
Definition: TQObject.h:89
Handle_t fId
Definition: TGObject.h:36
static FontStruct_t GetHilightFontStruct()
Return the font structure in use for highlighted menu entries.
Definition: TGMenu.cxx:1994
virtual void DefaultEntry(Int_t id)
Set default entry (default entries are drawn with bold text).
Definition: TGMenu.cxx:1679
void PopupConnection()
Connects the corresponding cascaded menu to the proper slots, according to the highlighted menu entry...
Definition: TGMenu.cxx:286
virtual void RemoveBind(const TGWindow *w, Int_t keycode, Int_t modifier) const
Remove key binding.
Definition: TGFrame.cxx:1618
Handle_t Window_t
Definition: GuiTypes.h:28
virtual void UnmapWindow()
Definition: TGFrame.h:253
virtual TGPopupMenu * GetPopup(const char *s)
Return popup menu with the specified name.
Definition: TGMenu.cxx:537
Mask_t fMask
Definition: GuiTypes.h:250
virtual void DoRedraw()
Draw popup menu.
Definition: TGMenu.cxx:1482
virtual void CheckEntry(Int_t id)
Check a menu entry (i.e. add a check mark in front of it).
Definition: TGMenu.cxx:1772
Bool_t fKeyNavigate
Definition: TGMenu.h:314
virtual void PoppedUp()
Definition: TGMenu.h:229
Int_t GetEntryId() const
Definition: TGMenu.h:95
TGMenuEntry * fCurrent
Definition: TGMenu.h:131
Bool_t fPoppedUp
Definition: TGMenu.h:134
#define ClassImpQ(name)
Definition: TQObject.h:283
virtual void Add(TObject *obj)
Definition: TList.h:87
auto * l
Definition: textangle.C:4
virtual void AddTimer(TTimer *t)
Add timer to list of system timers.
Definition: TSystem.cxx:479
TGClient * fClient
Definition: TGObject.h:37
Short_t Max(Short_t a, Short_t b)
Definition: TMathBase.h:200
const TGWindow * GetDefaultRoot() const
Returns the root (i.e.
Definition: TGClient.cxx:232
you should not use this method at all Int_t Int_t Double_t Double_t Double_t Int_t Double_t Double_t Double_t Double_t b
Definition: TRolke.cxx:630
TGPopupMenu(const TGPopupMenu &)
void BindMenu(TGPopupMenu *subMenu, Bool_t on)
If on kTRUE bind subMenu hot keys, otherwise remove key bindings.
Definition: TGMenu.cxx:352
#define snprintf
Definition: civetweb.c:822
void NeedRedraw(TGWindow *w, Bool_t force=kFALSE)
Set redraw flags.
Definition: TGClient.cxx:370
GContext_t fNormGC
Definition: TGMenu.h:259
UInt_t fState
Definition: GuiTypes.h:180
TGHotString * fLabel
Definition: TGMenu.h:81
virtual void DeleteEntry(Int_t id)
Delete entry with specified id from menu.
Definition: TGMenu.cxx:1916
void DrawRCheckMark(GContext_t gc, Int_t l, Int_t t, Int_t r, Int_t b)
Draw radio check mark. Used for radio button type menu entries.
Definition: TGMenu.cxx:1660
virtual void Activate(Bool_t)
Definition: TGMenu.h:222
TString GetOptionString() const
Returns a frame option string - used in SavePrimitive().
Definition: TGFrame.cxx:2460
virtual void AddPopup(TGHotString *s, TGPopupMenu *popup, TGMenuEntry *before=0, const TGPicture *p=0)
Add a (cascading) popup menu to a popup menu.
Definition: TGMenu.cxx:1149
static const TGGC * fgDefaultGC
Definition: TGMenu.h:265
GContext_t fSelGC
Definition: TGMenu.h:140
virtual Bool_t ExpandPathName(TString &path)
Expand a pathname getting rid of special shell characters like ~.
Definition: TSystem.cxx:1254
Int_t GetHotKeyCode() const
Definition: TGMenu.h:286
const char * GetShortcutText() const
Definition: TGMenu.h:97
friend class TGPopupMenu
Definition: TGMenu.h:306
virtual Int_t GetSize() const
Definition: TCollection.h:180
const Mask_t kAnyModifier
Definition: GuiTypes.h:209
const TList * GetListOfEntries() const
Definition: TGMenu.h:213
const Bool_t kTRUE
Definition: RtypesCore.h:87
Int_t GetLength() const
Definition: TGString.h:39
const Mask_t kButton1Mask
Definition: GuiTypes.h:202
Definition: TGGC.h:31
static const TGGC & GetShadowGC()
Get shadow color graphics context.
Definition: TGFrame.cxx:747
Int_t fX
Definition: GuiTypes.h:177
virtual void AddPopup(TGHotString *s, TGPopupMenu *menu, TGLayoutHints *l, TGPopupMenu *before=0)
Add popup menu to menu bar.
Definition: TGMenu.cxx:415
static const TGGC & GetBckgndGC()
Get background color graphics context.
Definition: TGFrame.cxx:757
TGMenuBar(const TGMenuBar &)
static Pixel_t GetDefaultSelectedBackground()
Get default selected frame background.
Definition: TGFrame.cxx:678
virtual void PlaceMenu(Int_t x, Int_t y, Bool_t stick_mode, Bool_t grab_pointer)
Popup a popup menu.
Definition: TGMenu.cxx:1238
virtual void DestroyWindow()
Definition: TGWindow.h:92
virtual void SavePrimitive(std::ostream &out, Option_t *option="")
Save a popup menu widget as a C++ statement(s) on output stream out.
Definition: TGMenu.cxx:2164
static const TGGC & GetDefaultGC()
Return default graphics context.
Definition: TGMenu.cxx:1954
virtual Bool_t IsEntryHidden(Int_t id)
Return true if menu entry is hidden.
Definition: TGMenu.cxx:1758
virtual void Draw(Drawable_t id, GContext_t gc, Int_t x, Int_t y)
Draw string.
Definition: TGString.cxx:51
virtual void SavePrimitive(std::ostream &out, Option_t *option="")
Save a menu bar widget as a C++ statement(s) on output stream out.
Definition: TGMenu.cxx:2332
virtual ~TGPopupMenu()
Delete a popup menu.
Definition: TGMenu.cxx:972
virtual Int_t MustCleanup() const
Definition: TGFrame.h:420
const char * Data() const
Definition: TString.h:345
TGWindow * GetWindowById(Window_t sw) const
Find a TGWindow via its handle. If window is not found return 0.
Definition: TGClient.cxx:591
Short_t fY
Definition: GuiTypes.h:356