Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
QRootContextMenu.cpp
Go to the documentation of this file.
1// Author: Sergey Linev 2/07/2026
2
3/*************************************************************************
4 * Copyright (C) 1995-2026, Rene Brun and Fons Rademakers. *
5 * All rights reserved. *
6 * *
7 * For the licensing terms see $ROOTSYS/LICENSE. *
8 * For the list of contributors see $ROOTSYS/README/CREDITS. *
9 *************************************************************************/
10
11
12/** \class QRootContextMenu
13 \ingroup qt6canvas
14
15This class provides an interface to context-sensitive popup menus.
16These menus pop up when the user hits the right mouse button, and
17are destroyed when the menu pops downs.
18*/
19
20
21#include "QRootContextMenu.h"
22
23#include "TROOT.h"
24#include "TContextMenu.h"
25#include "TCanvas.h"
26#include "TColor.h"
27#include "TMethod.h"
28#include "TDataMember.h"
29#include "TToggle.h"
30#include "TClassMenuItem.h"
31#include "TAttText.h"
32#include "TAttMarker.h"
33
34#include "QRootMethodDialog.h"
35#include "QPaintWidget.h"
36#include "TQt6Canvas.h"
37
38#include <QtCore/QSignalMapper>
39#include <QMenu>
40#include <QAction>
41#include <QDialog>
42#include <QVBoxLayout>
43#include <QHBoxLayout>
44#include <QFormLayout>
45#include <QComboBox>
46#include <QSpinBox>
47#include <QPushButton>
48#include <QLabel>
49#include <QColorDialog>
50#include <QDoubleSpinBox>
51
53 kToggleStart = 1000, // first id of toggle menu items
54 kToggleListStart = 2000, // first id of toggle list menu items
55 kUserFunctionStart = 3000 // first id of user added functions/methods, etc...
56};
57
58////////////////////////////////////////////////////////////////////////////////
59/// Create context menu.
60
63{
64 gROOT->GetListOfCleanups()->Add(this);
65}
66
67////////////////////////////////////////////////////////////////////////////////
68/// Delete a context menu.
69
71{
72 gROOT->GetListOfCleanups()->Remove(this);
73 fTrash.Delete();
74}
75
76////////////////////////////////////////////////////////////////////////////////
77/// Display context popup menu for currently selected object.
78
80{
81 // add menu items to popup menu
82 // CreateMenu(fContextMenu->GetSelectedObject());
83
84 auto object = fContextMenu->GetSelectedObject();
85 if (!object)
86 return;
87
88 fCustomArg.clear();
89 fTrash.Delete();
90
91
92 auto canv = dynamic_cast<TCanvas *>(fContextMenu->GetSelectedCanvas());
93 auto canvimp = dynamic_cast<ROOT::Experimental::TQt6Canvas *>(canv->GetCanvasImp());
94 auto widget = canvimp->GetPaintWidget();
95
96 QPoint screenPos = widget->mapToGlobal(widget->rect().topLeft());
97
98 QMenu menu;
99 QSignalMapper map;
100
101 QObject::connect(&map, &QSignalMapper::mappedInt,
103
104 // Add a title
105 QString buffer = fContextMenu->CreatePopupTitle(object);
106 addMenuAction(&menu, &map, buffer, -1, nullptr);
107 menu.addSeparator();
108 bool last_separ = true;
109
110 int entry = 0, toggle = kToggleStart, togglelist = kToggleListStart;
111 int userfunction = kUserFunctionStart;
112
113 // Get list of menu items from the selected object's class
114 TList *menuItemList = object->IsA()->GetMenuList();
115
116 TIter nextItem(menuItemList);
117
118 while (auto menuItem = (TClassMenuItem*) nextItem()) {
119 switch (menuItem->GetType()) {
121 if (!last_separ)
122 menu.addSeparator();
123 last_separ = true;
124 break;
125 }
127 // Standard list of class methods. Rebuild from scratch.
128 // Get linked list of objects menu items (i.e. member functions
129 // with the token *MENU in their comment fields.
130 TList *methodList = new TList;
131 object->IsA()->GetMenuItems(methodList);
132
133 TMethod *method;
134 TClass *classPtr = nullptr;
135 TIter next(methodList);
136 Bool_t needSep = kFALSE;
137
138 while ((method = (TMethod*) next())) {
139 if (classPtr != method->GetClass()) {
140 needSep = kTRUE;
141 classPtr = method->GetClass();
142 }
143
144 EMenuItemKind menuKind = method->IsMenuItem();
145 TString last_component;
146
147 switch (menuKind) {
148 case kMenuDialog:
149 // search for arguments to the MENU statement
150 if (needSep) {
151 menu.addSeparator();
152 needSep = kFALSE;
153 }
154 addMenuAction(&menu, &map, method->GetName(), entry++, method);
155 break;
156 case kMenuSubMenu:
157 if (auto m = method->FindDataMember()) {
158 if (needSep) {
159 menu.addSeparator();
160 needSep = kFALSE;
161 }
162
163 if (m->GetterMethod()) {
164
165 QMenu *r = menu.addMenu(method->GetName());
166 TIter nxt(m->GetOptions());
167 while (auto it = (TOptionListItem*) nxt()) {
168 const char *name = it->fOptName;
169 Long_t val = it->fValue;
170
171 TToggle *t = new TToggle;
172 t->SetToggledObject(object, method);
173 t->SetOnValue(val);
174 fTrash.Add(t);
175
176 auto act = addMenuAction(r, &map, name, togglelist++, t);
177 act->setCheckable(true);
178 if (t->GetState())
179 act->setChecked(true);
180 }
181 } else {
182 addMenuAction(&menu, &map, method->GetName(), entry++, method);
183 }
184 }
185 break;
186
187 case kMenuToggle: {
188 if (needSep) {
189 menu.addSeparator();
190 needSep = kFALSE;
191 }
192
193 TToggle *t = new TToggle;
194 t->SetToggledObject(object, method);
195 t->SetOnValue(1);
196 fTrash.Add(t);
197
198 auto act = addMenuAction(&menu, &map, method->GetName(), toggle++, t);
199 act->setCheckable(true);
200 if (t->GetState())
201 act->setChecked(true);
202 break;
203 }
204 default:
205 break;
206 }
207 }
208 delete methodList;
209 }
210 break;
212 const char* menuItemTitle = menuItem->GetTitle();
213 if (menuItem->IsToggle()) {
214 TMethod* method = object->IsA()->GetMethodWithPrototype(menuItem->GetFunctionName(),menuItem->GetArgs());
215 if (method) {
216 TToggle *t = new TToggle;
217 t->SetToggledObject(object, method);
218 t->SetOnValue(1);
219 fTrash.Add(t);
220
221 if (strlen(menuItemTitle)==0)
222 menuItemTitle = method->GetName();
223 auto act = addMenuAction(&menu, &map, menuItemTitle, toggle++, t);
224 act->setCheckable(true);
225 if (t->GetState())
226 act->setChecked(true);
227 }
228 } else {
229 if (strlen(menuItemTitle)==0)
230 menuItemTitle = menuItem->GetFunctionName();
231 addMenuAction(&menu, &map, menuItemTitle, userfunction++, menuItem);
232 }
233 break;
234 }
235
236 default:
237 break;
238 }
239 }
240
241 menu.exec(screenPos + QPoint(x, y));
242}
243
244////////////////////////////////////////////////////////////////////////////////
245/// Create dialog object with OK and Cancel buttons. This dialog
246/// prompts for the arguments of "method".
247
249{
250 Dialog(object, (TFunction *)method);
251}
252
253////////////////////////////////////////////////////////////////////////////////
254/// Create dialog object with OK and Cancel buttons. This dialog
255/// prompts for the arguments of "function".
256/// function may be a global function or a method
257
259{
261 dlg.methodDialog(fContextMenu, object, func);
262}
263
264////////////////////////////////////////////////////////////////////////////////
265/// Handle remove of some ROOT objects
266
268{
269 if (obj == fContextMenu->GetSelectedCanvas())
270 fContextMenu->SetCanvas(nullptr);
271 if (obj == fContextMenu->GetSelectedPad())
272 fContextMenu->SetPad(nullptr);
273 if (obj == fContextMenu->GetSelectedObject()) {
274 // if the object being deleted is the one selected,
275 // ungrab the mouse pointer and terminate (close) the menu
276 fContextMenu->SetObject(nullptr);
277 }
278}
279
280////////////////////////////////////////////////////////////////////////////////
281/// Register menu action in signal map
282
283QAction* QRootContextMenu::addMenuAction(QMenu* menu, QSignalMapper *map, const QString& text, int id, void *arg)
284{
285 bool enabled = true;
286
287 QAction* act = new QAction(text, menu);
288
289 if (!enabled)
290 if ((text.compare("DrawClone") == 0) || (text.compare("DrawClass") == 0) || (text.compare("Inspect") == 0) ||
291 (text.compare("SetShowProjectionX") == 0) || (text.compare("SetShowProjectionY") == 0) ||
292 (text.compare("DrawPanel") == 0) || (text.compare("FitPanel") == 0))
293 act->setEnabled(false);
294
295 QObject::connect(act, &QAction::triggered, [id, map]() {
296 map->mappedInt(id);
297 });
298
299 menu->addAction(act);
300 map->setMapping(act, id);
301
302 fCustomArg[id] = arg;
303
304 return act;
305}
306
307////////////////////////////////////////////////////////////////////////////////
308/// Execute specified menu item
309
311{
312 if (id < 0)
313 return;
314 void *ud = fCustomArg[id];
315
316 if (ud) {
317 // retrieve the highlighted function
318 TFunction *function = nullptr;
319 if (id < kToggleStart) {
320 TMethod *m = (TMethod *)ud;
321 function = (TFunction *)m;
322 } else if (id >= kToggleStart && id < kUserFunctionStart) {
323 TToggle *t = (TToggle *)ud;
324 TMethodCall *mc = (TMethodCall *)t->GetSetter();
325 function = (TFunction *)mc->GetMethod();
326 } else {
327 TClassMenuItem *mi = (TClassMenuItem *)ud;
328 function = gROOT->GetGlobalFunctionWithPrototype(mi->GetFunctionName());
329 }
330 if (function)
331 fContextMenu->SetMethod(function);
332 }
333
334 if (id < kToggleStart) {
335 auto m = (TMethod *)ud;
337 } else if (id >= kToggleStart && id < kToggleListStart) {
338 auto t = (TToggle *) ud;
340 } else if (id >= kToggleListStart && id < kUserFunctionStart) {
341 auto t = (TToggle *) ud;
342 if (t->GetState() == 0)
343 t->SetState(1);
344 } else {
345 auto mi = (TClassMenuItem *)ud;
346 fContextMenu->Action(mi);
347 }
348}
@ kToggleStart
@ kToggleListStart
@ kUserFunctionStart
#define c(i)
Definition RSha256.hxx:101
long Long_t
Signed long integer 4 bytes (long). Size depends on architecture.
Definition RtypesCore.h:69
constexpr Bool_t kFALSE
Definition RtypesCore.h:109
constexpr Bool_t kTRUE
Definition RtypesCore.h:108
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t r
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize id
Option_t Option_t TPoint TPoint const char text
char name[80]
Definition TGX11.cxx:142
EMenuItemKind
Definition TMethod.h:31
@ kMenuSubMenu
Definition TMethod.h:35
@ kMenuDialog
Definition TMethod.h:33
@ kMenuToggle
Definition TMethod.h:34
#define gROOT
Definition TROOT.h:417
@ kToggleStart
@ kToggleListStart
@ kUserFunctionStart
void executeMenu(int id)
Execute specified menu item.
void Dialog(TObject *object, TMethod *method) override
Create dialog object with OK and Cancel buttons.
void RecursiveRemove(TObject *obj) override
Handle remove of some ROOT objects.
QRootContextMenu(TContextMenu *c=nullptr, const char *name="ROOT Context Menu")
Create context menu.
QAction * addMenuAction(QMenu *menu, QSignalMapper *map, const QString &text, int id, void *arg=nullptr)
Register menu action in signal map.
~QRootContextMenu() override
Delete a context menu.
std::map< int, void * > fCustomArg
void DisplayPopup(Int_t x, Int_t y) override
Display context popup menu for currently selected object.
Specialized dialog to enter arguments for method exection.
void methodDialog(TContextMenu *menu, TObject *object, TFunction *func)
Run method dialog.
QPaintWidget * GetPaintWidget() const
Definition TQt6Canvas.h:45
The Canvas class.
Definition TCanvas.h:23
Describes one element of the context menu associated to a class The menu item may describe.
virtual const char * GetFunctionName() const
TClass instances represent classes, structs and namespaces in the ROOT type system.
Definition TClass.h:84
TList * GetMenuList() const
Return the list of menu items associated with the class.
Definition TClass.cxx:4462
TMethod * GetMethodWithPrototype(const char *method, const char *proto, Bool_t objectIsConst=kFALSE, ROOT::EFunctionMatchMode mode=ROOT::kConversionMatch)
Find the method with a given prototype.
Definition TClass.cxx:4577
void GetMenuItems(TList *listitems)
Returns list of methods accessible by context menu.
Definition TClass.cxx:3937
This class provides an interface to GUI independent context sensitive popup menus.
TContextMenu * fContextMenu
This class provides an interface to context sensitive popup menus.
virtual void SetCanvas(TVirtualPad *c)
virtual TVirtualPad * GetSelectedCanvas()
virtual void Action(TObject *object, TMethod *method)
Action to be performed when this menu item is selected.
virtual TVirtualPad * GetSelectedPad()
virtual void SetPad(TVirtualPad *p)
virtual void SetMethod(TFunction *m)
virtual void SetObject(TObject *o)
virtual TObject * GetSelectedObject()
virtual const char * CreatePopupTitle(TObject *object)
Create title for popup menu.
Global functions class (global functions are obtained from CINT).
Definition TFunction.h:30
A doubly linked list.
Definition TList.h:38
void Add(TObject *obj) override
Definition TList.h:81
void Delete(Option_t *option="") override
Remove all objects from the list AND delete all heap based objects.
Definition TList.cxx:600
TClass * IsA() const override
Definition TList.h:115
Method or function calling interface.
Definition TMethodCall.h:37
TFunction * GetMethod()
Returns the TMethod describing the method to be executed.
Each ROOT class (see TClass) has a linked list of methods.
Definition TMethod.h:38
virtual TDataMember * FindDataMember()
Tries to guess DataMember from comment string and Method's name <==(only if 1 Argument!...
Definition TMethod.cxx:132
TClass * GetClass() const
Definition TMethod.h:55
EMenuItemKind IsMenuItem() const
Definition TMethod.h:56
TClass * IsA() const override
Definition TMethod.h:68
const char * GetName() const override
Returns name of object.
Definition TNamed.h:49
Mother of all ROOT objects.
Definition TObject.h:42
virtual const char * GetTitle() const
Returns title of object.
Definition TObject.cxx:506
Basic string class.
Definition TString.h:137
This class defines toggling facility for both - object's method or variables.
Definition TToggle.h:47
virtual void SetOnValue(Long_t lon)
Definition TToggle.h:78
TMethodCall * GetSetter() const
Definition TToggle.h:87
virtual void SetToggledObject(TObject *obj, TMethod *anymethod)
Initializes it to toggle an object's datamember using this object's method.
Definition TToggle.cxx:134
virtual Bool_t GetState()
Returns the state of Toggle according to its current value and fOnValue, returns true if they match.
Definition TToggle.cxx:68
Double_t y[n]
Definition legend1.C:17
Double_t x[n]
Definition legend1.C:17
TMarker m
Definition textangle.C:8