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 member = method->FindDataMember()) {
158 if (needSep) {
159 menu.addSeparator();
160 needSep = kFALSE;
161 }
162
163 if (member->GetterMethod()) {
164 QMenu *r = menu.addMenu(method->GetName());
165 TIter nxt(member->GetOptions());
166 while (auto it = (TOptionListItem*) nxt()) {
167 TToggle *t = new TToggle;
168 t->SetToggledObject(object, member);
169 t->SetOnValue(it->fValue);
170 fTrash.Add(t);
171
172 auto act = addMenuAction(r, &map, it->fOptName.Data(), togglelist++, t);
173 act->setCheckable(true);
174 if (t->GetState())
175 act->setChecked(true);
176 }
177 } else {
178 addMenuAction(&menu, &map, method->GetName(), entry++, method);
179 }
180 }
181 break;
182
183 case kMenuToggle: {
184 if (needSep) {
185 menu.addSeparator();
186 needSep = kFALSE;
187 }
188
189 TToggle *t = new TToggle;
190 t->SetToggledObject(object, method);
191 t->SetOnValue(1);
192 fTrash.Add(t);
193
194 auto act = addMenuAction(&menu, &map, method->GetName(), toggle++, t);
195 act->setCheckable(true);
196 if (t->GetState())
197 act->setChecked(true);
198 break;
199 }
200 default:
201 break;
202 }
203 }
204 delete methodList;
205 }
206 break;
208 const char* menuItemTitle = menuItem->GetTitle();
209 if (menuItem->IsToggle()) {
210 TMethod* method = object->IsA()->GetMethodWithPrototype(menuItem->GetFunctionName(),menuItem->GetArgs());
211 if (method) {
212 TToggle *t = new TToggle;
213 t->SetToggledObject(object, method);
214 t->SetOnValue(1);
215 fTrash.Add(t);
216
217 if (strlen(menuItemTitle)==0)
218 menuItemTitle = method->GetName();
219 auto act = addMenuAction(&menu, &map, menuItemTitle, toggle++, t);
220 act->setCheckable(true);
221 if (t->GetState())
222 act->setChecked(true);
223 }
224 } else {
225 if (strlen(menuItemTitle)==0)
226 menuItemTitle = menuItem->GetFunctionName();
227 addMenuAction(&menu, &map, menuItemTitle, userfunction++, menuItem);
228 }
229 break;
230 }
231
232 default:
233 break;
234 }
235 }
236
237 menu.exec(screenPos + QPoint(x, y));
238}
239
240////////////////////////////////////////////////////////////////////////////////
241/// Create dialog object with OK and Cancel buttons. This dialog
242/// prompts for the arguments of "method".
243
245{
246 Dialog(object, (TFunction *)method);
247}
248
249////////////////////////////////////////////////////////////////////////////////
250/// Create dialog object with OK and Cancel buttons. This dialog
251/// prompts for the arguments of "function".
252/// function may be a global function or a method
253
255{
257 dlg.methodDialog(fContextMenu, object, func);
258}
259
260////////////////////////////////////////////////////////////////////////////////
261/// Handle remove of some ROOT objects
262
264{
265 if (obj == fContextMenu->GetSelectedCanvas())
266 fContextMenu->SetCanvas(nullptr);
267 if (obj == fContextMenu->GetSelectedPad())
268 fContextMenu->SetPad(nullptr);
269 if (obj == fContextMenu->GetSelectedObject()) {
270 // if the object being deleted is the one selected,
271 // ungrab the mouse pointer and terminate (close) the menu
272 fContextMenu->SetObject(nullptr);
273 }
274}
275
276////////////////////////////////////////////////////////////////////////////////
277/// Register menu action in signal map
278
279QAction* QRootContextMenu::addMenuAction(QMenu* menu, QSignalMapper *map, const QString& text, int id, void *arg)
280{
281 bool enabled = true;
282
283 QAction* act = new QAction(text, menu);
284
285 if (!enabled)
286 if ((text.compare("DrawClone") == 0) || (text.compare("DrawClass") == 0) || (text.compare("Inspect") == 0) ||
287 (text.compare("SetShowProjectionX") == 0) || (text.compare("SetShowProjectionY") == 0) ||
288 (text.compare("DrawPanel") == 0) || (text.compare("FitPanel") == 0))
289 act->setEnabled(false);
290
291 QObject::connect(act, &QAction::triggered, [id, map]() {
292 map->mappedInt(id);
293 });
294
295 menu->addAction(act);
296 map->setMapping(act, id);
297
298 fCustomArg[id] = arg;
299
300 return act;
301}
302
303////////////////////////////////////////////////////////////////////////////////
304/// Execute specified menu item
305
307{
308 if (id < 0)
309 return;
310 void *ud = fCustomArg[id];
311
312 if (ud) {
313 // retrieve the highlighted function
314 TFunction *function = nullptr;
315 if (id < kToggleStart) {
316 TMethod *m = (TMethod *)ud;
317 function = (TFunction *)m;
318 } else if (id >= kToggleStart && id < kUserFunctionStart) {
319 TToggle *t = (TToggle *)ud;
320 TMethodCall *mc = (TMethodCall *)t->GetSetter();
321 function = (TFunction *)mc->GetMethod();
322 } else {
323 TClassMenuItem *mi = (TClassMenuItem *)ud;
324 function = gROOT->GetGlobalFunctionWithPrototype(mi->GetFunctionName());
325 }
326 if (function)
327 fContextMenu->SetMethod(function);
328 }
329
330 if (id < kToggleStart) {
331 auto m = (TMethod *)ud;
333 } else if (id >= kToggleStart && id < kToggleListStart) {
334 auto t = (TToggle *) ud;
336 } else if (id >= kToggleListStart && id < kUserFunctionStart) {
337 auto t = (TToggle *) ud;
338 if (t->GetState() == 0)
339 t->SetState(1);
340 } else {
341 auto mi = (TClassMenuItem *)ud;
342 fContextMenu->Action(mi);
343 }
344}
@ kToggleStart
@ kToggleListStart
@ kUserFunctionStart
#define c(i)
Definition RSha256.hxx:101
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
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:49
virtual void SetOnValue(Long_t lon)
Definition TToggle.h:82
TMethodCall * GetSetter() const
return setter method request new for the TDataMember while it can be recreated at any time
Definition TToggle.cxx:167
virtual void SetToggledObject(TObject *obj, TMethod *anymethod)
Initializes it to toggle an object's datamember using this object's method.
Definition TToggle.cxx:116
virtual Bool_t GetState()
Returns the state of Toggle according to its current value and fOnValue, returns true if they match.
Definition TToggle.cxx:60
Double_t y[n]
Definition legend1.C:17
Double_t x[n]
Definition legend1.C:17
TMarker m
Definition textangle.C:8