// @(#)root/gui:$Id$ // Author: Fons Rademakers 09/01/98 /************************************************************************* * Copyright (C) 1995-2021, Rene Brun and Fons Rademakers. * * All rights reserved. * * * * For the licensing terms see $ROOTSYS/LICENSE. * * For the list of contributors see $ROOTSYS/README/CREDITS. * *************************************************************************/ #ifndef ROOT_TGMenu #define ROOT_TGMenu #include "TGFrame.h" #include "TGString.h" #include "TGPicture.h" #include "TGWidget.h" //--- Menu entry status mask enum EMenuEntryState { kMenuActiveMask = BIT(0), kMenuEnableMask = BIT(1), kMenuDefaultMask = BIT(2), kMenuCheckedMask = BIT(3), kMenuRadioMask = BIT(4), kMenuHideMask = BIT(5), kMenuRadioEntryMask = BIT(6) }; //--- Menu entry types enum EMenuEntryType { kMenuSeparator, kMenuLabel, kMenuEntry, kMenuPopup }; class TGPopupMenu; class TGMenuBar; class TGMenuTitle; class TTimer; class TGSplitButton; /** \class TGMenuEntry This class contains all information about a menu entry. It is a fully protected class used internally by TGPopupMenu. */ class TGMenuEntry : public TObject { friend class TGPopupMenu; friend class TGMenuBar; protected: Int_t fEntryId; ///< the entry id (used for event processing) void *fUserData; ///< pointer to user data structure EMenuEntryType fType; ///< type of entry Int_t fStatus; ///< entry status (OR of EMenuEntryState) Int_t fEx, fEy; ///< position of entry UInt_t fEw, fEh; ///< width and height of entry TGHotString *fLabel; ///< menu entry label TGString *fShortcut; ///< menu entry shortcut const TGPicture *fPic; ///< menu entry icon TGPopupMenu *fPopup; ///< pointer to popup menu (in case of cascading menus) private: TGMenuEntry(const TGMenuEntry&) = delete; TGMenuEntry& operator=(const TGMenuEntry&) = delete; public: TGMenuEntry(): fEntryId(0), fUserData(nullptr), fType(), fStatus(0), fEx(0), fEy(0), fEw(0), fEh(0), fLabel(nullptr), fShortcut(nullptr), fPic(nullptr), fPopup(nullptr) { } ~TGMenuEntry() override { if (fLabel) delete fLabel; if (fShortcut) delete fShortcut; } Int_t GetEntryId() const { return fEntryId; } const char *GetName() const override { return fLabel ? fLabel->GetString() : nullptr; } const char *GetShortcutText() const { return fShortcut ? fShortcut->GetString() : nullptr; } virtual Int_t GetStatus() const { return fStatus; } EMenuEntryType GetType() const { return fType; } TGPopupMenu *GetPopup() const { return fPopup; } TGHotString *GetLabel() const { return fLabel; } TGString *GetShortcut() const { return fShortcut; } Int_t GetEx() const { return fEx; } Int_t GetEy() const { return fEy; } UInt_t GetEw() const { return fEw; } UInt_t GetEh() const { return fEh; } const TGPicture *GetPic() const { return fPic; } void *GetUserData() const { return fUserData; } ClassDefOverride(TGMenuEntry,0); // Menu entry class }; /** \class TGPopupMenu This class creates a popup menu object. Popup menu's are attached to TGMenuBar objects. */ class TGPopupMenu : public TGFrame { friend class TGMenuTitle; friend class TGMenuBar; friend class TGSplitButton; protected: TList *fEntryList; ///< list of menu entries TGMenuEntry *fCurrent; ///< currently selected menu entry Bool_t fStick; ///< stick mode (popup menu stays sticked on screen) Bool_t fHasGrab; ///< true if menu has grabbed pointer Bool_t fPoppedUp; ///< true if menu is currently popped up UInt_t fXl; ///< Max width of all menu entries UInt_t fMenuWidth; ///< width of popup menu UInt_t fMenuHeight; ///< height of popup menu TTimer *fDelay; ///< delay before popping up cascading menu GContext_t fNormGC; ///< normal drawing graphics context GContext_t fSelGC; ///< graphics context for drawing selections GContext_t fSelbackGC; ///< graphics context for drawing selection background FontStruct_t fFontStruct; ///< font to draw menu entries FontStruct_t fHifontStruct; ///< font to draw highlighted entries Cursor_t fDefaultCursor; ///< right pointing cursor const TGWindow *fMsgWindow; ///< window which handles menu events TGMenuBar *fMenuBar; ///< menu bar (if any) TGSplitButton *fSplitButton; ///< split button (if any) UInt_t fEntrySep; ///< separation distance between entries static const TGFont *fgDefaultFont; static const TGFont *fgHilightFont; static const TGGC *fgDefaultGC; static const TGGC *fgDefaultSelectedGC; static const TGGC *fgDefaultSelectedBackgroundGC; void DrawTrianglePattern(GContext_t gc, Int_t l, Int_t t, Int_t r, Int_t b); void DrawCheckMark(GContext_t gc, Int_t l, Int_t t, Int_t r, Int_t b); void DrawRCheckMark(GContext_t gc, Int_t l, Int_t t, Int_t r, Int_t b); void DoRedraw() override; virtual void DrawEntry(TGMenuEntry *entry); virtual void Reposition(); static FontStruct_t GetDefaultFontStruct(); static FontStruct_t GetHilightFontStruct(); static const TGGC &GetDefaultGC(); static const TGGC &GetDefaultSelectedGC(); static const TGGC &GetDefaultSelectedBackgroundGC(); private: TGPopupMenu(const TGPopupMenu&) = delete; TGPopupMenu& operator=(const TGPopupMenu&) = delete; public: TGPopupMenu(const TGWindow *p = nullptr, UInt_t w = 10, UInt_t h = 10, UInt_t options = 0); ~TGPopupMenu() override; virtual void AddEntry(TGHotString *s, Int_t id, void *ud = nullptr, const TGPicture *p = nullptr, TGMenuEntry *before = nullptr); virtual void AddEntry(const char *s, Int_t id, void *ud = nullptr, const TGPicture *p = nullptr, TGMenuEntry *before = nullptr); virtual void AddSeparator(TGMenuEntry *before = nullptr); virtual void AddLabel(TGHotString *s, const TGPicture *p = nullptr, TGMenuEntry *before = nullptr); virtual void AddLabel(const char *s, const TGPicture *p = nullptr, TGMenuEntry *before = nullptr); virtual void AddPopup(TGHotString *s, TGPopupMenu *popup, TGMenuEntry *before = nullptr, const TGPicture *p = nullptr); virtual void AddPopup(const char *s, TGPopupMenu *popup, TGMenuEntry *before = nullptr, const TGPicture *p = nullptr); virtual void EnableEntry(Int_t id); virtual void DisableEntry(Int_t id); virtual Bool_t IsEntryEnabled(Int_t id); virtual void HideEntry(Int_t id); virtual Bool_t IsEntryHidden(Int_t id); virtual void DefaultEntry(Int_t id); virtual void CheckEntry(Int_t id); virtual void CheckEntryByData(void *user_data); virtual void UnCheckEntry(Int_t id); virtual void UnCheckEntryByData(void *user_data); virtual void UnCheckEntries(); virtual Bool_t IsEntryChecked(Int_t id); virtual void RCheckEntry(Int_t id, Int_t IDfirst, Int_t IDlast); virtual Bool_t IsEntryRChecked(Int_t id); virtual void PlaceMenu(Int_t x, Int_t y, Bool_t stick_mode, Bool_t grab_pointer); virtual Int_t EndMenu(void *&userData); virtual void DeleteEntry(Int_t id); virtual void DeleteEntry(TGMenuEntry *entry); virtual TGMenuEntry *GetEntry(Int_t id); virtual TGMenuEntry *GetCurrent() const { return fCurrent; } virtual TGMenuEntry *GetEntry(const char *s); const TList *GetListOfEntries() const { return fEntryList; } void DrawBorder() override; Bool_t HandleButton(Event_t *event) override; Bool_t HandleMotion(Event_t *event) override; Bool_t HandleCrossing(Event_t *event) override; Bool_t HandleTimer(TTimer *t) override; virtual void Associate(const TGWindow *w) { fMsgWindow = w; } virtual void SetMenuBar(TGMenuBar *bar) { fMenuBar = bar; } TGMenuBar *GetMenuBar() const { return fMenuBar; } void Activate(Bool_t) override {} virtual void Activate(TGMenuEntry *entry); void SavePrimitive(std::ostream &out, Option_t *option = "") override; UInt_t GetEntrySep() const { return fEntrySep; } virtual void SetEntrySep(UInt_t sep) { fEntrySep = sep; } virtual void PoppedUp() { Emit("PoppedUp()"); } // *SIGNAL* virtual void PoppedDown() { Emit("PoppedDown()"); } // *SIGNAL* virtual void Highlighted(Int_t id) { Emit("Highlighted(Int_t)", id); } // *SIGNAL* virtual void Activated(Int_t id) { Emit("Activated(Int_t)", id); } // *SIGNAL* ClassDefOverride(TGPopupMenu,0) // Popup menu }; /** \class TGMenuTitle This class creates a menu title. A menu title is a frame to which a popup menu can be attached. Menu titles are automatically created when adding a popup menu to a menubar. */ class TGMenuTitle : public TGFrame { protected: TGPopupMenu *fMenu; ///< attached popup menu TGHotString *fLabel; ///< menu title Int_t fTitleId; ///< id of selected menu item void *fTitleData; ///< user data associated with selected item Bool_t fState; ///< menu title state (active/not active) Int_t fHkeycode; ///< hot key code FontStruct_t fFontStruct; ///< font Pixel_t fTextColor; ///< text color GContext_t fNormGC, fSelGC; ///< normal and selection graphics contexts void DoRedraw() override; static const TGFont *fgDefaultFont; static const TGGC *fgDefaultSelectedGC; static const TGGC *fgDefaultGC; private: TGMenuTitle(const TGMenuTitle&) = delete; TGMenuTitle& operator=(const TGMenuTitle&) = delete; public: static FontStruct_t GetDefaultFontStruct(); static const TGGC &GetDefaultSelectedGC(); static const TGGC &GetDefaultGC(); TGMenuTitle(const TGWindow *p = nullptr, TGHotString *s = nullptr, TGPopupMenu *menu = nullptr, GContext_t norm = GetDefaultGC()(), FontStruct_t font = GetDefaultFontStruct(), UInt_t options = 0); ~TGMenuTitle() override { if (fLabel) delete fLabel; } Pixel_t GetTextColor() const { return fTextColor; } void SetTextColor(Pixel_t col) { fTextColor = col; } virtual void SetState(Bool_t state); Bool_t GetState() const { return fState; } Int_t GetHotKeyCode() const { return fHkeycode; } TGPopupMenu *GetMenu() const { return fMenu; } const char *GetName() const override { return fLabel ? fLabel->GetString() : nullptr; } virtual void DoSendMessage(); void SavePrimitive(std::ostream &out, Option_t *option = "") override; ClassDefOverride(TGMenuTitle,0) // Menu title class }; class TGMenuBar : public TGHorizontalFrame { friend class TGPopupMenu; protected: TGMenuTitle *fCurrent; ///< current menu title TList *fTitles; ///< list of menu titles Cursor_t fDefaultCursor; ///< right pointing cursor Bool_t fStick; ///< stick mode (popup menu stays sticked on screen) TList *fTrash; ///< garbage Bool_t fKeyNavigate; ///< kTRUE if arrow key navigation is on TGPopupMenu *fMenuMore; ///< extra >> menu TGLayoutHints *fMenuBarMoreLayout; ///< layout of the extra menu Bool_t fWithExt; ///< indicates whether the >> menu is shown or not TList *fOutLayouts; ///< keeps trace of layouts of hidden menus TList *fNeededSpace; ///< keeps trace of space needed for hidden menus virtual void AddFrameBefore(TGFrame *f, TGLayoutHints *l = nullptr, TGPopupMenu *before = nullptr); virtual void BindHotKey(Int_t keycode, Bool_t on = kTRUE); virtual void BindKeys(Bool_t on = kTRUE); void BindMenu(TGPopupMenu* subMenu, Bool_t on); private: TGMenuBar(const TGMenuBar&) = delete; TGMenuBar& operator=(const TGMenuBar&) = delete; public: TGMenuBar(const TGWindow *p = nullptr, UInt_t w = 60, UInt_t h = 20, UInt_t options = kHorizontalFrame | kRaisedFrame); ~TGMenuBar() override; virtual void AddPopup(TGHotString *s, TGPopupMenu *menu, TGLayoutHints *l, TGPopupMenu *before = nullptr); virtual void AddPopup(const char *s, TGPopupMenu *menu, TGLayoutHints *l, TGPopupMenu *before = nullptr); virtual TGPopupMenu *AddPopup(const TString &s, Int_t padleft = 4, Int_t padright = 0, Int_t padtop = 0, Int_t padbottom = 0); virtual void AddTitle(TGMenuTitle *title, TGLayoutHints *l, TGPopupMenu *before = nullptr); virtual TGPopupMenu *GetPopup(const char *s); virtual TGPopupMenu *RemovePopup(const char *s); virtual TGMenuTitle *GetCurrent() const { return fCurrent; } virtual TList *GetTitles() const { return fTitles; } Bool_t HandleButton(Event_t *event) override; Bool_t HandleMotion(Event_t *event) override; Bool_t HandleKey(Event_t *event) override; void SavePrimitive(std::ostream &out, Option_t *option = "") override; void Layout() override; void PopupConnection(); TGFrameElement* GetLastOnLeft(); ClassDefOverride(TGMenuBar,0) // Menu bar class }; #endif