22#include <QtCore/QSignalMapper>
23#include <QtCore/QTimer>
25#include <QDragEnterEvent>
29#include <QInputDialog>
30#include <QColorDialog>
39#include "TObjString.h"
44#include "TDataMember.h"
46#include "TMethodCall.h"
47#include "TMethodArg.h"
52#include "TGedEditor.h"
53#include "TVirtualPadEditor.h"
57#include "TGo4LockGuard.h"
59#define TGo4LockGuard int
72 setObjectName(
"QRootCanvas");
74 setSizeIncrement( QSize( 100, 100 ) );
79 setUpdatesEnabled(
true );
80 setMouseTracking(
true);
82 setFocusPolicy( Qt::TabFocus );
83 setCursor( Qt::CrossCursor );
88 setAttribute(Qt::WA_PaintOnScreen);
89 setAttribute(Qt::WA_PaintUnclipped);
98 fQtScalingfactor = (double) metric(QPaintDevice::PdmDevicePixelRatioScaled)/65536.;
105 setAcceptDrops(
true);
157#if QT_VERSION < QT_VERSION_CHECK(6,0,0)
164 return QPoint(scaledX, scaledY);
172 static ulong lastprocesstime = 0;
173 static ulong delta = 100;
174 ulong timestamp = e->timestamp();
175 if(timestamp-delta < lastprocesstime) {
185 if (e->buttons() & Qt::LeftButton)
186 fCanvas->HandleInput(kButton1Motion, pnt.x(), pnt.y());
188 fCanvas->HandleInput(kMouseMotion, pnt.x(), pnt.y());
192 TObject *selected =
fCanvas->GetSelected();
193 Int_t px =
fCanvas->GetEventX();
194 Int_t py =
fCanvas->GetEventY();
197 buffer = selected->GetName();
199 buffer += selected->GetObjectInfo(px, py);
201 buffer =
"No selected object x = ";
202 buffer += QString::number(px);
204 buffer += QString::number(py);
212 lastprocesstime = timestamp;
223#if QT_VERSION < QT_VERSION_CHECK(5,15,0)
224 bool positive = (e->delta() > 0);
225 int ex = e->x(), ey = e->y();
227 QPoint delta = e->pixelDelta();
228 if (delta.isNull()) delta = e->angleDelta() / 8;
229 bool positive = delta.x() > 0 || delta.y() > 0;
230 int ex = e->position().x(), ey = e->position().y();
242 TObjLink* pickobj =
nullptr;
247#if QT_VERSION < QT_VERSION_CHECK(6,0,0)
248 QPoint mouse_pnt = e->globalPos();
250 QPoint mouse_pnt = e->globalPosition().toPoint();
278 TPad *pad =
fCanvas->Pick(scaled.x(), scaled.y(), pickobj);
279 TObject *selected =
fCanvas->GetSelected();
281 switch(e->button()) {
282 case Qt::LeftButton :
283 fCanvas->HandleInput(kButton1Down, scaled.x(), scaled.y());
286 case Qt::RightButton : {
287 TString selectedOpt(
"");
292 }
else if(!selected) {
293 selected = pickobj->GetObject();
294 selectedOpt = pickobj->GetOption();
299 gROOT->SetSelectedPrimitive(selected);
300 fMousePosX = gPad->AbsPixeltoX(gPad->GetEventX());
301 fMousePosY = gPad->AbsPixeltoY(gPad->GetEventY());
305 #if QT_VERSION < QT_VERSION_CHECK(5,15,0)
306 auto signal = QOverload<int>::of(&QSignalMapper::mapped);
308 auto signal = &QSignalMapper::mappedInt;
317 QString buffer = TString::Format(
"%s::%s", cl->GetName(),
fMenuObj->GetName()).Data();
323 if(!cl->InheritsFrom(TLatex::Class())) {
328 if(cl->InheritsFrom(TH1::Class())) {
335 while (
auto method =
dynamic_cast<TMethod*
>(iter())) {
336 buffer = method->GetName();
340 if (menu.exec(mouse_pnt) ==
nullptr) {
348 case Qt::MiddleButton :
349 fCanvas->HandleInput(kButton2Down, scaled.x(), scaled.y());
369 switch(e->button()) {
370 case Qt::LeftButton :
371 fCanvas->HandleInput(kButton1Up, scaled.x(), scaled.y());
373 case Qt::RightButton :
374 fCanvas->HandleInput(kButton3Up, scaled.x(), scaled.y());
376 case Qt::MiddleButton :
377 fCanvas->HandleInput(kButton2Up, scaled.x(), scaled.y());
394 switch(e->button()) {
395 case Qt::LeftButton : {
397 fCanvas->HandleInput(kButton1Double, scaled.x(), scaled.y());
398 TObjLink* pickobj =
nullptr;
399 TPad *pad =
fCanvas->Pick(scaled.x(), scaled.y(), pickobj);
406 case Qt::RightButton :
407 fCanvas->HandleInput(kButton3Double, scaled.x(), scaled.y());
409 case Qt::MiddleButton :
410 fCanvas->HandleInput(kButton2Double, scaled.x(), scaled.y());
458 fRootWindowId = gVirtualX->AddWindow((ULong_t)newid, width(), height());
475 QWidget::leaveEvent(e);
481 fCanvas->HandleInput(kMouseLeave, 0, 0);
500 if (e->mimeData()->hasText())
501 e->acceptProposedAction();
506 TObject *obj =
nullptr;
508#if QT_VERSION < QT_VERSION_CHECK(6,0,0)
509 QPoint pos =
event->pos();
511 QPoint pos =
event->position().toPoint();
549 return fCanvas->DrawClone(option);
554 return fCanvas->DrawClonePad();
564 fCanvas->EnterLeave(prevSelPad, prevSelObj);
594 return fCanvas->GetContextMenu();
599 return fCanvas->GetDoubleBuffer();
619 return fCanvas->GetHighLightColor();
634 return fCanvas->GetSelectedOpt();
639 return fCanvas->GetSelectedPad();
644 return fCanvas->GetShowEventStatus();
654 return fCanvas->GetXsizeUser();
659 return fCanvas->GetYsizeUser();
664 return fCanvas->GetXsizeReal();
669 return fCanvas->GetYsizeReal();
679 return fCanvas->GetWindowTopX();
684 return fCanvas->GetWindowTopY();
689 return fCanvas->GetWindowWidth();
694 return fCanvas->GetWindowHeight();
709 fCanvas->GetCanvasPar(wtopx, wtopy, ww, wh);
754 return fCanvas->OpaqueMoving();
759 return fCanvas->OpaqueResizing();
769 return fCanvas->Pick(px, py, pickobj);
774 return fCanvas->Pick(px, py, prevSelObj);
789 fCanvas->SaveSource(filename, option);
799 fCanvas->SetDoubleBuffer(mode);
804 fCanvas->SetWindowPosition(x, y);
814 fCanvas->SetCanvasSize(ww, wh);
819 fCanvas->SetHighLightColor(col);
839 fCanvas->Size(xsizeuser, ysizeuser);
849 fCanvas->SetRetained(retained);
885 if (!
object || !method)
return;
895 dlg.setWindowTitle(TString::Format(
"%s:%s", object->GetName(), method->GetName()).Data());
899 TIter next(method->GetListOfMethodArgs());
901 while (
auto argument = (TMethodArg *) next()) {
902 TString argTitle = TString::Format(
"(%s) %s", argument->GetTitle(), argument->GetName());
903 TString argDflt = argument->GetDefault() ? argument->GetDefault() :
"";
904 if (argDflt.Length() > 0)
905 argTitle += TString::Format(
" [default: %s]", argDflt.Data());
906 TString type = argument->GetTypeName();
907 TDataType *datatype = gROOT->GetType(type);
911 basictype = datatype->GetTypeName();
913 if (type.CompareTo(
"enum") != 0)
914 std::cout <<
"*** Warning in Dialog(): data type is not basic type, assuming (int)\n";
918 if (TString(argument->GetTitle()).Index(
"*") != kNPOS) {
923 TDataMember *m = argument->GetDataMember();
924 if (m && m->GetterMethod()) {
926 m->GetterMethod()->Init(object->IsA(), m->GetterMethod()->GetMethodName(),
"");
932 if (basictype ==
"char*") {
933 char *tdefval =
nullptr;
934 m->GetterMethod()->Execute(
object,
"", &tdefval);
935 if (tdefval) val = tdefval;
937 if ((basictype ==
"float") ||
938 (basictype ==
"double")) {
939 Double_t ddefval = 0.;
940 m->GetterMethod()->Execute(
object,
"", ddefval);
941 val = TString::Format(
"%g", ddefval);
943 if ((basictype ==
"char") ||
944 (basictype ==
"int") ||
945 (basictype ==
"long") ||
946 (basictype ==
"short")) {
948 m->GetterMethod()->Execute(
object,
"", ldefval);
949 val = TString::Format(
"%ld", ldefval);
955 if ((opt = m->GetOptions()) !=
nullptr) {
958 dlg.
addArg(argTitle.Data(), val.Data(), type.Data());
962 dlg.
addArg(argTitle.Data(), val.Data(), type.Data());
965 if ((argDflt.Length() > 1) &&
966 (argDflt[0]==
'\"') && (argDflt[argDflt.Length()-1]==
'\"')) {
969 argDflt.Remove(argDflt.Length()-1,1);
972 dlg.
addArg(argTitle.Data(), argDflt.Data(), type.Data());
976 if (dlg.exec() != QDialog::Accepted)
return;
978 Bool_t deletion = kFALSE;
980 qDebug(
"DIAL executeMethod: simple version\n");
981 TVirtualPad *psave = gROOT->GetSelectedPad();
983 qDebug(
"DIAL saved pad: %s gPad:%s \n",psave->GetName(),gPad->GetName());
985 qDebug(
"DIAL obj:%s meth:%s \n", object->GetName(), method->GetName());
987 TObjArray tobjlist(method->GetListOfMethodArgs()->LastIndex() + 1);
988 for (
int n = 0; n <= method->GetListOfMethodArgs()->LastIndex(); n++) {
989 QString s = dlg.
getArg(n);
990 qDebug(
"** QString values (first ) :%s \n", s.toLatin1().constData() );
991 tobjlist.AddLast(
new TObjString(s.toLatin1().constData()));
995 if(strcmp(method->GetName(),
"Delete") == 0) {
997 qDebug(
" DIAL obj name deleted :%s \n", object->GetName());
1002 qDebug(
" DIAL deletion done closing ... \n");
1004 if (strcmp(method->GetName(),
"SetCanvasSize") == 0) {
1005 int width = dlg.
getArg(0).toInt();
1006 int height = dlg.
getArg(1).toInt();
1007 qDebug(
" do resize with %i %i \n", width, height);
1008 resize(width, height);
1012 qDebug(
"TCint::Execute called !\n");
1014 object->Execute(method, &tobjlist);
1016 if (object->TestBit(TObject::kNotDeleted))
1025 qDebug(
"DIAL set saved pad: %s herit:%s gPad:%s\n",
1026 psave->GetName(), psave->ClassName(), gPad->GetName());
1027 gROOT->SetSelectedPad(psave);
1028 gROOT->GetSelectedPad()->Modified();
1029 gROOT->GetSelectedPad()->Update();
1030 qDebug(
"DIAL update done on %s \n", gROOT->GetSelectedPad()->GetName());
1032 gROOT->SetSelectedPad(gPad);
1033 gROOT->GetSelectedPad()->Update();
1041 QAction* act =
new QAction(text, menu);
1044 if ((text.compare(
"DrawClone") == 0) || (text.compare(
"DrawClass") == 0) || (text.compare(
"Inspect") == 0) ||
1045 (text.compare(
"SetShowProjectionX") == 0) || (text.compare(
"SetShowProjectionY") == 0) ||
1046 (text.compare(
"DrawPanel") == 0) || (text.compare(
"FitPanel") == 0))
1047 act->setEnabled(
false);
1049 QObject::connect(act, &QAction::triggered, [
id, map]() {
1050#if QT_VERSION < QT_VERSION_CHECK(5,15,0)
1057 menu->addAction(act);
1058 map->setMapping(act,
id);
1073 TLatex *fxLatex =
new TLatex();
1074 text = QInputDialog::getText(
this, tr(
"Qt Root" ),
1075 tr(
"Please enter your text" ),
1076 QLineEdit::Normal, QString(), &ok);
1083 TH1 *h1 =
dynamic_cast<TH1 *
> (
fMenuObj);
1085 QColor col = QColorDialog::getColor();
1086 if (col.isValid()) {
1087 short int C_new = TColor::GetColor(col.red(), col.green(), col.blue());
1088 h1->SetLineColor(C_new);
1095 TH1 *h1 =
dynamic_cast<TH1 *
> (
fMenuObj);
1097 QColor col = QColorDialog::getColor();
1098 if (col.isValid()) {
1099 short int C_new = TColor::GetColor(col.red(), col.green(), col.blue());
1100 h1->SetFillColor(C_new);
1106 gROOT->GetSelectedPad()->Update();
1107 gROOT->GetSelectedPad()->Modified();
1110 gROOT->SetFromPopUp( kFALSE );
1116 TVirtualPad *psave = gROOT->GetSelectedPad();
1125 if (method->GetListOfMethodArgs()->First()) {
1126 if (strstr(method->GetName(),
"Delete")) {
1134 gROOT->SetFromPopUp(kTRUE);
1135 fMenuObj->Execute(method->GetName(),
"");
1137 if (
fMenuObj->TestBit(TObject::kNotDeleted)) {
1145 #ifndef __NOGO4GED__
1146 TGedEditor* ed =
dynamic_cast<TGedEditor*
>(TVirtualPadEditor::GetPadEditor(kFALSE));
1150 fCanvas->GetPadSave()->Update();
1151 fCanvas->GetPadSave()->Modified();
1153 gROOT->SetSelectedPad(psave);
1155 gROOT->GetSelectedPad()->Update();
1156 gROOT->GetSelectedPad()->Modified();
1160 gROOT->SetFromPopUp(kFALSE);
1193 double scalefactor = (double) metric(QPaintDevice::PdmDevicePixelRatioScaled)/65536.;
1209 fxPeditor = TVirtualPadEditor::LoadEditor();
1219 TGedEditor* ed =
dynamic_cast<TGedEditor*
>(
fxPeditor);
1229 TGedEditor* ed =
dynamic_cast<TGedEditor*
>(
fxPeditor);
1232 ed->SetModel(pad, obj, kButton1Down);
1240 TGedEditor* ed =
dynamic_cast<TGedEditor*
>(
fxPeditor);
1243 fDummyHisto =
new TH1I(
"dummyhisto",
"dummyhisto", 100, -10., 10.);
1250 ed->SetModel(
nullptr,
getCanvas(), kButton1Down);
1279 QVBoxLayout* gedlayout =
new QVBoxLayout(
fEditorFrame);
1280 gedlayout->setContentsMargins(0, 0, 0, 0);
static bool IsRootCanvasMenuEnabled()
void activateRepaint(int act)
virtual void ToggleEventStatus()
void SelectedPadChanged(TPad *)
signal which will be emitted when root selected pad is changed via clicking the mid-mouse button (M.
bool isStatusBarVisible()
void activateEditor(TPad *pad, TObject *obj)
virtual TPad * Pick(Int_t px, Int_t py, TObjLink *&pickobj)
void FeedbackMode(Bool_t set)
void showStatusMessage(const char *msg)
void dropEvent(QDropEvent *Event) override
TVirtualPadEditor * fxPeditor
double scaledPosition(int p)
returns scaled point coordinate, for high dpi case
virtual void SetDoubleBuffer(Int_t mode=1)
void paintEvent(QPaintEvent *e) override
virtual TObject * DrawClonePad()
void processRepaintTimer()
void SetTitle(const char *title="")
void closeEvent(QCloseEvent *e) override
void CanvasDropEvent(QDropEvent *, TPad *)
virtual void Browse(TBrowser *b)
void SetCanvasSize(UInt_t ww, UInt_t wh)
void mouseDoubleClickEvent(QMouseEvent *e) override
virtual void Resize(Option_t *option="")
TVirtualPad * GetPadSave()
void SetRetained(Bool_t retained=kTRUE)
const char * GetDISPLAY()
void setShowEventStatus(bool s)
void SaveSource(const char *filename="", Option_t *option="")
void MoveOpaque(Int_t set=1)
TVirtualPad * GetSelectedPad()
QAction * addMenuAction(QMenu *menu, QSignalMapper *map, const QString &text, int id)
Color_t GetHighLightColor()
QRootCanvas(QWidget *parent=nullptr)
virtual void Size(Float_t xsizeuser=0, Float_t ysizeuser=0)
virtual void ls(Option_t *option="")
void setStatusBarVisible(bool flag)
void SetWindowPosition(Int_t x, Int_t y)
virtual void SetCursor(ECursor cursor)
virtual void HandleInput(EEventType button, Int_t x, Int_t y)
virtual void GetCanvasPar(Int_t &wtopx, Int_t &wtopy, UInt_t &ww, UInt_t &wh)
virtual void Paint(Option_t *option="")
virtual TObject * DrawClone(Option_t *option="")
void methodDialog(TObject *object, TMethod *method)
void leaveEvent(QEvent *e) override
void mousePressEvent(QMouseEvent *e) override
QPoint scaledMousePoint(QMouseEvent *ev)
void wheelEvent(QWheelEvent *e) override
void SetWindowSize(UInt_t ww, UInt_t wh)
void PadDoubleClicked(TPad *, int, int)
signal emitted when user produce left mouse double-click on pad
void mouseMoveEvent(QMouseEvent *e) override
void MenuCommandExecuted(TObject *, const char *)
void Clear(Option_t *option="")
void PadClicked(TPad *, int, int)
signal emitted when mouse clicks on pad
void ResizeOpaque(Int_t set=1)
void SetBatch(Bool_t batch=kTRUE)
void Close(Option_t *option="")
void cd(Int_t subpadnumber=0)
virtual void Draw(Option_t *option="")
Option_t * GetSelectedOpt()
void SetSelected(TObject *obj)
virtual void ToggleAutoExec()
void SetSelectedPad(TPad *pad)
void CanvasStatusEvent(const char *)
Bool_t GetShowEventStatus()
void resizeEvent(QResizeEvent *e) override
TContextMenu * GetContextMenu()
void SetHighLightColor(Color_t col)
void EnterLeave(TPad *prevSelPad, TObject *prevSelObj)
bool showEventStatus() const
void mouseReleaseEvent(QMouseEvent *e) override
QRootWindow * fxRooteditor
void dragEnterEvent(QDragEnterEvent *e) override
void addArg(const char *argname, const char *value, const char *type)
Qt widget wrapper for ROOT TGWindow class.