GRSISort "v4.0.0.5"
An extension of the ROOT analysis Framework
Loading...
Searching...
No Matches
GRootCanvas.cxx
Go to the documentation of this file.
1#include "RConfigure.h"
2
3#include "GRootCanvas.h"
4
5#include "TRootApplication.h"
6#include "TRootHelpDialog.h"
7#include "TGClient.h"
8#include "TGCanvas.h"
9#include "TGMenu.h"
10#include "TGWidget.h"
11#include "TGFileDialog.h"
12#include "TGStatusBar.h"
13#include "TGTextEditDialogs.h"
14#include "TROOT.h"
15#include "TClass.h"
16#include "TSystem.h"
17#include "TCanvas.h"
18#include "TPadPainter.h"
19#include "TBrowser.h"
20#include "TClassTree.h"
21#include "TMarker.h"
22#include "TStyle.h"
23#include "TColorWheel.h"
24#include "TVirtualX.h"
25#include "TApplication.h"
26#include "TFile.h"
27#include "TInterpreter.h"
28#include "TEnv.h"
29#include "TMath.h"
30#include "Riostream.h"
31#include "TGDockableFrame.h"
32
33#include "TG3DLine.h"
34#include "TGToolBar.h"
35#include "TGToolTip.h"
36#include "TVirtualPadEditor.h"
37#include "TRootControlBar.h"
38#include "TGLabel.h"
39#include "TGuiBuilder.h"
40#include "TImage.h"
41#include "TError.h"
42#include "TGDNDManager.h"
43#include "TBufferFile.h"
44#include "TRootBrowser.h"
45#include "TGTab.h"
46#include "TGedEditor.h"
47
48#include "TPluginManager.h"
49#include "TVirtualGL.h"
50
51#ifdef WIN32
52#include "TWin32SplashThread.h"
53#endif
54
55#include "HelpText.h"
56
57#include "GCanvas.h"
58
59// Canvas menu command ids
142
143constexpr int kButton1Ctrl = 9;
144constexpr int kButton1CtrlMotion = 10;
145
146static std::array<const char*, 6> gOpenTypes = {"ROOT files", "*.root", "All files", "*", nullptr, nullptr};
147
148static std::array<const char*, 32> gSaveAsTypes = {"PDF", "*.pdf", "PostScript", "*.ps", "Encapsulated PostScript",
149 "*.eps", "SVG", "*.svg", "TeX", "*.tex",
150 "GIF", "*.gif", "ROOT macros", "*.C", "ROOT files",
151 "*.root", "XML", "*.xml", "PNG", "*.png",
152 "XPM", "*.xpm", "JPEG", "*.jpg", "TIFF",
153 "*.tiff", "XCF", "*.xcf", "All files", "*",
154 nullptr, nullptr};
155
156static std::array<ToolBarData_t, 11> gToolBarData = {{//{ filename, tooltip, staydown,id, button}
157 {"newcanvas.xpm", "New", kFALSE, kFileNewCanvas, nullptr},
158 {"open.xpm", "Open", kFALSE, kFileOpen, nullptr},
159 {"save.xpm", "Save As", kFALSE, kFileSaveAs, nullptr},
160 {"printer.xpm", "Print", kFALSE, kFilePrint, nullptr},
161 {"", "", kFALSE, -1, nullptr},
162 {"interrupt.xpm", "Interrupt", kFALSE, kOptionInterrupt, nullptr},
163 {"refresh2.xpm", "Refresh", kFALSE, kOptionRefresh, nullptr},
164 {"", "", kFALSE, -1, nullptr},
165 {"inspect.xpm", "Inspect", kFALSE, kInspectRoot, nullptr},
166 {"browser.xpm", "Browser", kFALSE, kToolsBrowser, nullptr},
167 {nullptr, nullptr, kFALSE, 0, nullptr}}};
168
169static std::array<ToolBarData_t, 18> gToolBarData1 = {{{"pointer.xpm", "Modify", kFALSE, kToolModify, nullptr},
170 {"arc.xpm", "Arc", kFALSE, kToolArc, nullptr},
171 {"line.xpm", "Line", kFALSE, kToolLine, nullptr},
172 {"arrow.xpm", "Arrow", kFALSE, kToolArrow, nullptr},
173 {"diamond.xpm", "Diamond", kFALSE, kToolDiamond, nullptr},
174 {"ellipse.xpm", "Ellipse", kFALSE, kToolEllipse, nullptr},
175 {"pad.xpm", "Pad", kFALSE, kToolPad, nullptr},
176 {"pave.xpm", "Pave", kFALSE, kToolPave, nullptr},
177 {"pavelabel.xpm", "Pave Label", kFALSE, kToolPLabel, nullptr},
178 {"pavetext.xpm", "Pave Text", kFALSE, kToolPText, nullptr},
179 {"pavestext.xpm", "Paves Text", kFALSE, kToolPsText, nullptr},
180 {"graph.xpm", "Graph", kFALSE, kToolGraph, nullptr},
181 {"curlyline.xpm", "Curly Line", kFALSE, kToolCurlyLine, nullptr},
182 {"curlyarc.xpm", "Curly Arc", kFALSE, kToolCurlyArc, nullptr},
183 {"latex.xpm", "Text/Latex", kFALSE, kToolLatex, nullptr},
184 {"marker.xpm", "Marker", kFALSE, kToolMarker, nullptr},
185 {"cut.xpm", "Graphical Cut", kFALSE, kToolCutG, nullptr},
186 {nullptr, nullptr, kFALSE, 0, nullptr}}};
187
188/////////////////////////////////////////////////////////////////////////
189///
190/// \class GRootContainer
191///
192/// Utility class used by GRootCanvas. The GRootContainer is the frame
193/// embedded in the TGCanvas widget. The ROOT graphics goes into this
194/// frame. This class is used to enable input events on this graphics
195/// frame and forward the events to the GRootCanvas handlers.
196///
197/////////////////////////////////////////////////////////////////////////
198
199class GRootContainer : public TGCompositeFrame {
200private:
201 GRootCanvas* fCanvas; // pointer back to canvas imp
202public:
203 GRootContainer(GRootCanvas* c, Window_t id, const TGWindow* p);
204
205 Bool_t HandleButton(Event_t* event) override;
206 Bool_t HandleDoubleClick(Event_t* ev) override { return fCanvas->HandleContainerDoubleClick(ev); }
207 Bool_t HandleConfigureNotify(Event_t* ev) override
208 {
209 TGFrame::HandleConfigureNotify(ev);
211 }
212 Bool_t HandleKey(Event_t* ev) override { return fCanvas->HandleContainerKey(ev); }
213 Bool_t HandleMotion(Event_t* ev) override { return fCanvas->HandleContainerMotion(ev); }
214 Bool_t HandleExpose(Event_t* ev) override { return fCanvas->HandleContainerExpose(ev); }
215 Bool_t HandleCrossing(Event_t* ev) override { return fCanvas->HandleContainerCrossing(ev); }
216 void SavePrimitive(std::ostream& out, Option_t* = "") override;
217 void SetEditable(Bool_t) override {}
218};
219
220//______________________________________________________________________________
221GRootContainer::GRootContainer(GRootCanvas* canvas, Window_t id, const TGWindow* p) : TGCompositeFrame(gClient, id, p), fCanvas(canvas)
222{
223 /// Create a canvas container.
224
225 gVirtualX->GrabButton(fId, kAnyButton, kAnyModifier, kButtonPressMask | kButtonReleaseMask | kPointerMotionMask, kNone, kNone);
226
227 AddInput(kKeyPressMask | kKeyReleaseMask | kPointerMotionMask | kExposureMask | kStructureNotifyMask | kLeaveWindowMask);
228 fEditDisabled = kEditDisable;
229}
230
231//______________________________________________________________________________
232Bool_t GRootContainer::HandleButton(Event_t* event)
233{
234 /// Directly handle scroll mouse buttons (4 and 5), only pass buttons
235 /// 1, 2 and 3 on to the TCanvas.
236
237 const auto* viewPort = static_cast<const TGViewPort*>(fParent);
238 UInt_t page = viewPort->GetHeight() / 4;
239
240 gVirtualX->SetInputFocus(GetMainFrame()->GetId());
241
242 if(event->fCode == kButton4) {
243 // scroll up
244 auto newpos = fCanvas->fCanvasWindow->GetVsbPosition() - page;
245 fCanvas->fCanvasWindow->SetVsbPosition(newpos);
246 }
247 if(event->fCode == kButton5) {
248 // scroll down
249 auto newpos = fCanvas->fCanvasWindow->GetVsbPosition() + page;
250 fCanvas->fCanvasWindow->SetVsbPosition(newpos);
251 }
252 return fCanvas->HandleContainerButton(event);
253}
254
255//______________________________________________________________________________
256GRootCanvas::GRootCanvas(GCanvas* canvas, const char* name, UInt_t width, UInt_t height)
257 : TGMainFrame(gClient->GetRoot(), width, height), TCanvasImp(canvas)
258{
259 /// Create a basic ROOT canvas.
260 CreateCanvas(name);
261
262 ShowToolBar(kFALSE);
263 ShowEditor(kFALSE);
264
265 Resize(width, height);
266}
267
268//______________________________________________________________________________
269GRootCanvas::GRootCanvas(GCanvas* canvas, const char* name, Int_t x, Int_t y, UInt_t width, UInt_t height)
270 : TGMainFrame(gClient->GetRoot(), width, height), TCanvasImp(canvas)
271{
272 /// Create a basic ROOT canvas.
273 CreateCanvas(name);
274
275 ShowToolBar(kFALSE);
276 ShowEditor(kFALSE);
277
278 MoveResize(x, y, width, height);
279 SetWMPosition(x, y);
280}
281
282//______________________________________________________________________________
283void GRootCanvas::CreateCanvas(const char* name)
284{
285 /// Create the actual canvas.
286
287 fButton = 0;
288 fAutoFit = kTRUE; // check also menu entry
289 fEditor = nullptr;
290 fEmbedded = kFALSE;
291
292 // Create menus
293 fFileSaveMenu = new TGPopupMenu(fClient->GetDefaultRoot());
294 fFileSaveMenu->AddEntry(Form("%s.&ps", name), kFileSaveAsPS);
295 fFileSaveMenu->AddEntry(Form("%s.&eps", name), kFileSaveAsEPS);
296 fFileSaveMenu->AddEntry(Form("%s.p&df", name), kFileSaveAsPDF);
297 fFileSaveMenu->AddEntry(Form("%s.&gif", name), kFileSaveAsGIF);
298
299 static Int_t img = 0;
300
301 if(img == 0) {
302 Int_t sav = gErrorIgnoreLevel;
303 gErrorIgnoreLevel = kFatal;
304 img = TImage::Create() != nullptr ? 1 : -1;
305 gErrorIgnoreLevel = sav;
306 }
307 if(img > 0) {
308 fFileSaveMenu->AddEntry(Form("%s.&jpg", name), kFileSaveAsJPG);
309 fFileSaveMenu->AddEntry(Form("%s.&png", name), kFileSaveAsPNG);
310 }
311
312 fFileSaveMenu->AddEntry(Form("%s.&C", name), kFileSaveAsC);
313 fFileSaveMenu->AddEntry(Form("%s.&root", name), kFileSaveAsRoot);
314
315 fFileMenu = new TGPopupMenu(fClient->GetDefaultRoot());
316 fFileMenu->AddEntry("&New Canvas", kFileNewCanvas);
317 fFileMenu->AddEntry("&Open...", kFileOpen);
318 fFileMenu->AddEntry("&Close Canvas", kFileCloseCanvas);
319 fFileMenu->AddSeparator();
320 fFileMenu->AddPopup("&Save", fFileSaveMenu);
321 fFileMenu->AddEntry("Save &As...", kFileSaveAs);
322 fFileMenu->AddSeparator();
323 fFileMenu->AddEntry("&Print...", kFilePrint);
324 fFileMenu->AddSeparator();
325 fFileMenu->AddEntry("&Quit ROOT", kFileQuit);
326
327 fEditClearMenu = new TGPopupMenu(fClient->GetDefaultRoot());
328 fEditClearMenu->AddEntry("&Pad", kEditClearPad);
329 fEditClearMenu->AddEntry("&Canvas", kEditClearCanvas);
330
331 fEditMenu = new TGPopupMenu(fClient->GetDefaultRoot());
332 fEditMenu->AddEntry("&Style...", kEditStyle);
333 fEditMenu->AddSeparator();
334 fEditMenu->AddEntry("Cu&t", kEditCut);
335 fEditMenu->AddEntry("&Copy", kEditCopy);
336 fEditMenu->AddEntry("&Paste", kEditPaste);
337 fEditMenu->AddSeparator();
338 fEditMenu->AddPopup("C&lear", fEditClearMenu);
339 fEditMenu->AddSeparator();
340 fEditMenu->AddEntry("&Undo", kEditUndo);
341 fEditMenu->AddEntry("&Redo", kEditRedo);
342
343 fEditMenu->DisableEntry(kEditCut);
344 fEditMenu->DisableEntry(kEditCopy);
345 fEditMenu->DisableEntry(kEditPaste);
346 fEditMenu->DisableEntry(kEditUndo);
347 fEditMenu->DisableEntry(kEditRedo);
348
349 fViewWithMenu = new TGPopupMenu(fClient->GetDefaultRoot());
350 fViewWithMenu->AddEntry("&X3D", kViewX3D);
351 fViewWithMenu->AddEntry("&OpenGL", kViewOpenGL);
352
353 fViewMenu = new TGPopupMenu(fClient->GetDefaultRoot());
354 fViewMenu->AddEntry("&Editor", kViewEditor);
355 fViewMenu->AddEntry("&Toolbar", kViewToolbar);
356 fViewMenu->AddEntry("Event &Statusbar", kViewEventStatus);
357 fViewMenu->AddEntry("T&oolTip Info", kViewToolTips);
358 fViewMenu->AddSeparator();
359 fViewMenu->AddEntry("&Colors", kViewColors);
360 fViewMenu->AddEntry("&Fonts", kViewFonts);
361 fViewMenu->AddEntry("&Markers", kViewMarkers);
362 fViewMenu->AddSeparator();
363 fViewMenu->AddEntry("&Iconify", kViewIconify);
364 fViewMenu->AddSeparator();
365 fViewMenu->AddPopup("&View With", fViewWithMenu);
366
367 fViewMenu->DisableEntry(kViewFonts);
368
369 fOptionMenu = new TGPopupMenu(fClient->GetDefaultRoot());
370 fOptionMenu->AddEntry("&Auto Resize Canvas", kOptionAutoResize);
371 fOptionMenu->AddEntry("&Resize Canvas", kOptionResizeCanvas);
372 fOptionMenu->AddEntry("&Move Opaque", kOptionMoveOpaque);
373 fOptionMenu->AddEntry("Resize &Opaque", kOptionResizeOpaque);
374 fOptionMenu->AddSeparator();
375 fOptionMenu->AddEntry("&Interrupt", kOptionInterrupt);
376 fOptionMenu->AddEntry("R&efresh", kOptionRefresh);
377 fOptionMenu->AddSeparator();
378 fOptionMenu->AddEntry("&Pad Auto Exec", kOptionAutoExec);
379 fOptionMenu->AddSeparator();
380 fOptionMenu->AddEntry("&Statistics", kOptionStatistics);
381 fOptionMenu->AddEntry("Histogram &Title", kOptionHistTitle);
382 fOptionMenu->AddEntry("&Fit Parameters", kOptionFitParams);
383 fOptionMenu->AddEntry("Can Edit &Histograms", kOptionCanEdit);
384
385 // Opaque options initialized in InitWindow()
386 fOptionMenu->CheckEntry(kOptionAutoResize);
387 if(gStyle->GetOptStat() != 0) {
388 fOptionMenu->CheckEntry(kOptionStatistics);
389 }
390 if(gStyle->GetOptTitle() != 0) {
391 fOptionMenu->CheckEntry(kOptionHistTitle);
392 }
393 if(gStyle->GetOptFit() != 0) {
394 fOptionMenu->CheckEntry(kOptionFitParams);
395 }
396 if(gROOT->GetEditHistograms()) {
397 fOptionMenu->CheckEntry(kOptionCanEdit);
398 }
399
400 fToolsMenu = new TGPopupMenu(fClient->GetDefaultRoot());
401 fToolsMenu->AddEntry("&Inspect ROOT", kInspectRoot);
402 fToolsMenu->AddEntry("&Class Tree", kClassesTree);
403 fToolsMenu->AddEntry("&Fit Panel", kFitPanel);
404 fToolsMenu->AddEntry("&Start Browser", kToolsBrowser);
405 fToolsMenu->AddEntry("&Gui Builder", kToolsBuilder);
406 fToolsMenu->AddEntry("&Event Recorder", kToolsRecorder);
407
408 fHelpMenu = new TGPopupMenu(fClient->GetDefaultRoot());
409 fHelpMenu->AddLabel("Basic Help On...");
410 fHelpMenu->AddSeparator();
411 fHelpMenu->AddEntry("&Canvas", kHelpOnCanvas);
412 fHelpMenu->AddEntry("&Menus", kHelpOnMenus);
413 fHelpMenu->AddEntry("&Graphics Editor", kHelpOnGraphicsEd);
414 fHelpMenu->AddEntry("&Browser", kHelpOnBrowser);
415 fHelpMenu->AddEntry("&Objects", kHelpOnObjects);
416 fHelpMenu->AddEntry("&PostScript", kHelpOnPS);
417 fHelpMenu->AddSeparator();
418 fHelpMenu->AddEntry("&About ROOT...", kHelpAbout);
419
420 // This main frame will process the menu commands
421 fFileMenu->Associate(this);
422 fFileSaveMenu->Associate(this);
423 fEditMenu->Associate(this);
424 fEditClearMenu->Associate(this);
425 fViewMenu->Associate(this);
426 fViewWithMenu->Associate(this);
427 fOptionMenu->Associate(this);
428 fToolsMenu->Associate(this);
429 fHelpMenu->Associate(this);
430
431 // Create menubar layout hints
432 fMenuBarLayout = new TGLayoutHints(kLHintsTop | kLHintsLeft | kLHintsExpandX, 0, 0, 1, 1);
433 fMenuBarItemLayout = new TGLayoutHints(kLHintsTop | kLHintsLeft, 0, 4, 0, 0);
434 fMenuBarHelpLayout = new TGLayoutHints(kLHintsTop | kLHintsRight);
435
436 // Create menubar
437 fMenuBar = new TGMenuBar(this, 1, 1, kHorizontalFrame);
438 fMenuBar->AddPopup("&File", fFileMenu, fMenuBarItemLayout);
439 fMenuBar->AddPopup("&Edit", fEditMenu, fMenuBarItemLayout);
440 fMenuBar->AddPopup("&View", fViewMenu, fMenuBarItemLayout);
441 fMenuBar->AddPopup("&Options", fOptionMenu, fMenuBarItemLayout);
442 fMenuBar->AddPopup("&Tools", fToolsMenu, fMenuBarItemLayout);
443 fMenuBar->AddPopup("&Help", fHelpMenu, fMenuBarHelpLayout);
444
445 AddFrame(fMenuBar, fMenuBarLayout);
446
447 fHorizontal1 = new TGHorizontal3DLine(this);
448 fHorizontal1Layout = new TGLayoutHints(kLHintsTop | kLHintsExpandX);
450
451 // Create toolbar dock
452 fToolDock = new TGDockableFrame(this);
453 fToolDock->SetCleanup();
454 fToolDock->EnableHide(kFALSE);
455 AddFrame(fToolDock, fDockLayout = new TGLayoutHints(kLHintsExpandX));
456
457 // will alocate it later
458 fToolBar = nullptr;
459 fVertical1 = nullptr;
460 fVertical2 = nullptr;
461 fVertical1Layout = nullptr;
462 fVertical2Layout = nullptr;
463
464 fToolBarSep = new TGHorizontal3DLine(this);
465 fToolBarLayout = new TGLayoutHints(kLHintsTop | kLHintsExpandX);
466 AddFrame(fToolBarSep, fToolBarLayout);
467
468 fMainFrame = new TGCompositeFrame(this, GetWidth() + 4, GetHeight() + 4, kHorizontalFrame);
469 fMainFrameLayout = new TGLayoutHints(kLHintsExpandX | kLHintsExpandY);
470
471 // Create editor frame that will host the pad editor
472 fEditorFrame = new TGCompositeFrame(fMainFrame, 175, fMainFrame->GetHeight() + 4, kFixedWidth);
473 fEditorLayout = new TGLayoutHints(kLHintsExpandY | kLHintsLeft);
475
476 // Create canvas and canvas container that will host the ROOT graphics
477 fCanvasWindow = new TGCanvas(fMainFrame, GetWidth() + 4, GetHeight() + 4, kSunkenFrame | kDoubleBorder);
478
479 fCanvasID = -1;
480
481 if(fCanvas->UseGL()) {
482 fCanvas->SetSupportGL(kFALSE);
483 // first, initialize GL (if not yet)
484 if(gGLManager == nullptr) {
485 TString osString = "win32";
486 if(gVirtualX->InheritsFrom("TGX11")) {
487 osString = "x11";
488 } else if(gVirtualX->InheritsFrom("TGCocoa")) {
489 osString = "osx";
490 }
491 TPluginHandler* pluginHandler = gROOT->GetPluginManager()->FindHandler("TGLManager", osString);
492
493 if(pluginHandler != nullptr && pluginHandler->LoadPlugin() != -1) {
494 if(pluginHandler->ExecPlugin(0) == 0) {
495 Error("CreateCanvas", "GL manager plugin failed");
496 }
497 }
498 } else {
499 fCanvasID = gGLManager->InitGLWindow(static_cast<ULong_t>(fCanvasWindow->GetViewPort()->GetId()));
500 if(fCanvasID != -1) {
501 // Create gl context.
502 const Int_t glCtx = gGLManager->CreateGLContext(fCanvasID);
503 if(glCtx != -1) {
504 fCanvas->SetSupportGL(kTRUE);
505 fCanvas->SetGLDevice(glCtx); // Now, fCanvas is responsible for context deletion!
506 } else {
507 Error("CreateCanvas", "GL context creation failed.");
508 }
509 } else {
510 Error("CreateCanvas", "GL window creation failed\n");
511 }
512 }
513 }
514
515 if(fCanvasID == -1) {
516 fCanvasID = gVirtualX->InitWindow(static_cast<ULong_t>(fCanvasWindow->GetViewPort()->GetId()));
517 }
518
519 Window_t win = gVirtualX->GetWindowID(fCanvasID);
520 fCanvasContainer = new GRootContainer(this, win, fCanvasWindow->GetViewPort());
521 fCanvasWindow->SetContainer(fCanvasContainer);
522 fCanvasLayout = new TGLayoutHints(kLHintsExpandX | kLHintsExpandY | kLHintsRight);
523
525 AddFrame(fMainFrame, fMainFrameLayout);
526
527 // create the tooltip with a timeout of 250 ms
528 fToolTip = new TGToolTip(fClient->GetDefaultRoot(), fCanvasWindow, "", 250);
529
530 fCanvas->Connect("ProcessedEvent(Int_t, Int_t, Int_t, TObject*)", "GRootCanvas", this,
531 "EventInfo(Int_t, Int_t, Int_t, TObject*)");
532
533 // Create status bar
534 std::array<int, 4> parts = {33, 10, 10, 47};
535 fStatusBar = new TGStatusBar(this, 10, 10);
536 fStatusBar->SetParts(parts.data(), parts.size());
537
538 fStatusBarLayout = new TGLayoutHints(kLHintsBottom | kLHintsLeft | kLHintsExpandX, 2, 2, 1, 1);
539
540 AddFrame(fStatusBar, fStatusBarLayout);
541
542 // Misc
543 SetWindowName(name);
544 SetIconName(name);
545 fIconPic = SetIconPixmap("macro_s.xpm");
546 SetClassHints("ROOT", "Canvas");
547
548 SetEditDisabled(kEditDisable);
549 MapSubwindows();
550
551 // by default status bar, tool bar and pad editor are hidden
552 HideFrame(fStatusBar);
553 HideFrame(fToolDock);
554 HideFrame(fToolBarSep);
555 HideFrame(fHorizontal1);
556
557 ShowToolBar(kFALSE);
558 ShowEditor(kFALSE);
559
560 // we need to use GetDefaultSize() to initialize the layout algorithm...
561 Resize(GetDefaultSize());
562
563 gVirtualX->SetDNDAware(fId, fDNDTypeList);
564 SetDNDTarget(kTRUE);
565}
566
567//______________________________________________________________________________
569{
570 /// Delete ROOT basic canvas. Order is significant. Delete in reverse
571 /// order of creation.
572
573 delete fToolTip;
574 if(fIconPic != nullptr) {
575 gClient->FreePicture(fIconPic);
576 }
577 if((fEditor != nullptr) && !fEmbedded) {
578 delete fEditor;
579 }
580 if(fToolBar != nullptr) {
581 Disconnect(fToolDock, "Docked()", this, "AdjustSize()");
582 Disconnect(fToolDock, "Undocked()", this, "AdjustSize()");
583 fToolBar->Cleanup();
584 delete fToolBar;
585 }
586
587 if(MustCleanup() == 0) {
588 delete fStatusBar;
589 delete fStatusBarLayout;
590 delete fCanvasContainer;
591 delete fCanvasWindow;
592
593 delete fEditorFrame;
594 delete fEditorLayout;
595 delete fMainFrame;
596 delete fMainFrameLayout;
597 delete fToolBarSep;
598#ifndef __APPLE__
599 delete fToolDock;
600#endif
601 delete fToolBarLayout;
602 delete fHorizontal1;
603 delete fHorizontal1Layout;
604 delete fMenuBarLayout;
605 delete fMenuBarItemLayout;
606 delete fMenuBarHelpLayout;
607 delete fCanvasLayout;
608 delete fDockLayout;
609 }
610
611 delete fFileMenu;
612 delete fFileSaveMenu;
613 delete fEditMenu;
614 delete fEditClearMenu;
615 delete fViewMenu;
616 delete fViewWithMenu;
617 delete fOptionMenu;
618 delete fToolsMenu;
619 delete fHelpMenu;
620}
621
622//______________________________________________________________________________
624{
625 /// Called via TCanvasImp interface by TCanvas.
626
627 TVirtualPadEditor* gged = TVirtualPadEditor::GetPadEditor(kFALSE);
628 if((gged != nullptr) && gged->GetCanvas() == fCanvas) {
629 if(fEmbedded) {
630 static_cast<TGedEditor*>(gged)->SetModel(nullptr, nullptr, kButton1Down);
631 static_cast<TGedEditor*>(gged)->SetCanvas(nullptr);
632 } else {
633 gged->Hide();
634 }
635 }
636
637 gVirtualX->CloseWindow();
638}
639
640//______________________________________________________________________________
642{
643 /// Really delete the canvas and this GUI.
644
645 TVirtualPadEditor* gged = TVirtualPadEditor::GetPadEditor(kFALSE);
646 if((gged != nullptr) && gged->GetCanvas() == fCanvas) {
647 if(fEmbedded) {
648 static_cast<TGedEditor*>(gged)->SetModel(nullptr, nullptr, kButton1Down);
649 static_cast<TGedEditor*>(gged)->SetCanvas(nullptr);
650 } else {
651 gged->Hide();
652 }
653 }
654
655 fToolTip->Hide();
656 Disconnect(fCanvas, "ProcessedEvent(Int_t, Int_t, Int_t, TObject*)", this,
657 "EventInfo(Int_t, Int_t, Int_t, TObject*)");
658
659 TVirtualPad* savepad = gPad;
660 gPad = nullptr; // hide gPad from CINT
661 gInterpreter->DeleteGlobal(fCanvas);
662 gPad = savepad; // restore gPad for ROOT
663 delete fCanvas; // will in turn delete this object
664}
665
666//______________________________________________________________________________
668{
669 /// In case window is closed via WM we get here.
670
671 DeleteWindow();
672}
673
674//______________________________________________________________________________
676{
677 /// Return width of canvas container.
678
679 return fCanvasContainer->GetWidth();
680}
681
682//______________________________________________________________________________
684{
685 /// Return height of canvas container.
686
687 return fCanvasContainer->GetHeight();
688}
689
690//______________________________________________________________________________
691UInt_t GRootCanvas::GetWindowGeometry(Int_t& x, Int_t& y, UInt_t& w, UInt_t& h)
692{
693 /// Gets the size and position of the window containing the canvas. This
694 /// size includes the menubar and borders.
695
696 gVirtualX->GetWindowSize(fId, x, y, w, h);
697
698 Window_t childdum = 0;
699 gVirtualX->TranslateCoordinates(fId, gClient->GetDefaultRoot()->GetId(), 0, 0, x, y, childdum);
700 if(!fCanvas->GetShowEditor()) {
701 return 0;
702 }
703 return fEditorFrame->GetWidth();
704}
705
706//______________________________________________________________________________
707void GRootCanvas::SetStatusText(const char* txt, Int_t partidx)
708{
709 /// Set text in status bar.
710
711 fStatusBar->SetText(txt, partidx);
712}
713
714//______________________________________________________________________________
715Bool_t GRootCanvas::ProcessMessage(Long_t msg, Long_t parm1, Long_t)
716{
717 /// Handle menu and other command generated by the user.
718
719 switch(GET_MSG(msg)) {
720
721 case kC_COMMAND:
722
723 switch(GET_SUBMSG(msg)) {
724
725 case kCM_BUTTON:
726 case kCM_MENU:
727
728 switch(parm1) {
729 // Handle toolbar items...
730 case kToolModify: gROOT->SetEditorMode(); break;
731 case kToolArc: gROOT->SetEditorMode("Arc"); break;
732 case kToolLine: gROOT->SetEditorMode("Line"); break;
733 case kToolArrow: gROOT->SetEditorMode("Arrow"); break;
734 case kToolDiamond: gROOT->SetEditorMode("Diamond"); break;
735 case kToolEllipse: gROOT->SetEditorMode("Ellipse"); break;
736 case kToolPad: gROOT->SetEditorMode("Pad"); break;
737 case kToolPave: gROOT->SetEditorMode("Pave"); break;
738 case kToolPLabel: gROOT->SetEditorMode("PaveLabel"); break;
739 case kToolPText: gROOT->SetEditorMode("PaveText"); break;
740 case kToolPsText: gROOT->SetEditorMode("PavesText"); break;
741 case kToolGraph: gROOT->SetEditorMode("PolyLine"); break;
742 case kToolCurlyLine: gROOT->SetEditorMode("CurlyLine"); break;
743 case kToolCurlyArc: gROOT->SetEditorMode("CurlyArc"); break;
744 case kToolLatex: gROOT->SetEditorMode("Text"); break;
745 case kToolMarker: gROOT->SetEditorMode("Marker"); break;
746 case kToolCutG:
747 gROOT->SetEditorMode("CutG");
748 break;
749
750 // Handle File menu items...
751 case kFileNewCanvas:
752 gROOT->MakeDefCanvas();
753 // GCanvas::MakeDefCanvas();
754 break;
755 case kFileOpen: {
756 static TString dir(".");
757 TGFileInfo fileInfo;
758 fileInfo.fFileTypes = gOpenTypes.data();
759 fileInfo.fIniDir = StrDup(dir);
760 new TGFileDialog(fClient->GetDefaultRoot(), this, kFDOpen, &fileInfo);
761 if(fileInfo.fFilename == nullptr) {
762 return kTRUE;
763 }
764 dir = fileInfo.fIniDir;
765 new TFile(fileInfo.fFilename, "update");
766 } break;
767 case kFileSaveAs: {
768 TString workdir = gSystem->WorkingDirectory();
769 static TString dir(".");
770 static Int_t typeidx = 0;
771 static Bool_t overwr = kFALSE;
772 TGFileInfo fileInfo;
773 TString defaultType = gEnv->GetValue("Canvas.SaveAsDefaultType", ".pdf");
774 if(typeidx == 0) {
775 for(int i = 1; gSaveAsTypes[i] != nullptr; i += 2) {
776 TString ftype = gSaveAsTypes[i];
777 if(ftype.EndsWith(defaultType.Data())) {
778 typeidx = i - 1;
779 break;
780 }
781 }
782 }
783 fileInfo.fFileTypes = gSaveAsTypes.data();
784 fileInfo.fIniDir = StrDup(dir);
785 fileInfo.fFileTypeIdx = typeidx;
786 fileInfo.fOverwrite = overwr;
787 new TGFileDialog(fClient->GetDefaultRoot(), this, kFDSave, &fileInfo);
788 gSystem->ChangeDirectory(workdir.Data());
789 if(fileInfo.fFilename == nullptr) {
790 return kTRUE;
791 }
792 Bool_t appendedType = kFALSE;
793 TString fn = fileInfo.fFilename;
794 TString ft = fileInfo.fFileTypes[fileInfo.fFileTypeIdx + 1];
795 dir = fileInfo.fIniDir;
796 typeidx = fileInfo.fFileTypeIdx;
797 overwr = fileInfo.fOverwrite;
798 again:
799 if(fn.EndsWith(".root") || fn.EndsWith(".ps") || fn.EndsWith(".eps") || fn.EndsWith(".pdf") ||
800 fn.EndsWith(".svg") || fn.EndsWith(".tex") || fn.EndsWith(".gif") || fn.EndsWith(".xml") ||
801 fn.EndsWith(".xpm") || fn.EndsWith(".jpg") || fn.EndsWith(".png") || fn.EndsWith(".xcf") ||
802 fn.EndsWith(".tiff")) {
803 fCanvas->SaveAs(fn);
804 } else if(fn.EndsWith(".C")) {
805 fCanvas->SaveSource(fn);
806 } else {
807 if(!appendedType) {
808 if(ft.Index(".") != kNPOS) {
809 fn += ft(ft.Index("."), ft.Length());
810 appendedType = kTRUE;
811 goto again; // NOLINT(cppcoreguidelines-avoid-goto)
812 }
813 }
814 Warning("ProcessMessage", "file %s cannot be saved with this extension", fileInfo.fFilename);
815 }
816 for(int i = 1; gSaveAsTypes[i] != nullptr; i += 2) {
817 TString ftype = gSaveAsTypes[i];
818 ftype.ReplaceAll("*.", ".");
819 if(fn.EndsWith(ftype.Data())) {
820 typeidx = i - 1;
821 break;
822 }
823 }
824 } break;
825 case kFileSaveAsRoot: fCanvas->SaveAs(".root"); break;
826 case kFileSaveAsC: fCanvas->SaveSource(); break;
827 case kFileSaveAsPS: fCanvas->SaveAs(); break;
828 case kFileSaveAsEPS: fCanvas->SaveAs(".eps"); break;
829 case kFileSaveAsPDF: fCanvas->SaveAs(".pdf"); break;
830 case kFileSaveAsGIF: fCanvas->SaveAs(".gif"); break;
831 case kFileSaveAsJPG: fCanvas->SaveAs(".jpg"); break;
832 case kFileSaveAsPNG: fCanvas->SaveAs(".png"); break;
833 case kFilePrint: PrintCanvas(); break;
834 case kFileCloseCanvas: SendCloseMessage(); break;
835 case kFileQuit:
836 if(!gApplication->ReturnFromRun()) {
837 if((TVirtualPadEditor::GetPadEditor(kFALSE) != nullptr)) {
838 TVirtualPadEditor::Terminate();
839 }
840 SendCloseMessage();
841 }
842 if(TVirtualPadEditor::GetPadEditor(kFALSE) != nullptr) {
843 TVirtualPadEditor::Terminate();
844 }
845 if(TClass::GetClass("TStyleManager") != nullptr) {
846 gROOT->ProcessLine("TStyleManager::Terminate()");
847 }
848 gApplication->Terminate(0);
849 break;
850
851 // Handle Edit menu items...
852 case kEditStyle:
853 if(TClass::GetClass("TStyleManager") == nullptr) {
854 gSystem->Load("libGed");
855 }
856 gROOT->ProcessLine("TStyleManager::Show()");
857 break;
858 case kEditCut:
859 // still noop
860 break;
861 case kEditCopy:
862 // still noop
863 break;
864 case kEditPaste:
865 // still noop
866 break;
867 case kEditUndo:
868 // noop
869 break;
870 case kEditRedo:
871 // noop
872 break;
873 case kEditClearPad:
874 gPad->Clear();
875 gPad->Modified();
876 gPad->Update();
877 break;
878 case kEditClearCanvas:
879 fCanvas->Clear();
880 fCanvas->Modified();
881 fCanvas->Update();
882 break;
883
884 // Handle View menu items...
885 case kViewEditor: fCanvas->ToggleEditor(); break;
886 case kViewToolbar: fCanvas->ToggleToolBar(); break;
887 case kViewEventStatus: fCanvas->ToggleEventStatus(); break;
888 case kViewToolTips: fCanvas->ToggleToolTips(); break;
889 case kViewColors: {
890 TVirtualPad* padsav = gPad->GetCanvas();
891 // This was the code with the old color table
892 // TCanvas *m = new TCanvas("colors","Color Table");
893 // TPad::DrawColorTable();
894 // m->Update();
895 auto* wheel = new TColorWheel();
896 wheel->Draw();
897
898 // tp: with Cocoa, window is visible (and repainted)
899 // before wheel->Draw() was called and you can see "empty"
900 // canvas.
901 gPad->Update();
902 //
903 if(padsav != nullptr) {
904 padsav->cd();
905 }
906 } break;
907 case kViewFonts:
908 // noop
909 break;
910 case kViewMarkers: {
911 TVirtualPad* padsav = gPad->GetCanvas();
912 auto* m = new GCanvas("markers", "Marker Types", 600, 200);
913 TMarker::DisplayMarkerTypes();
914 m->Update();
915 if(padsav != nullptr) {
916 padsav->cd();
917 }
918 } break;
919 case kViewIconify: Iconify(); break;
920 case kViewX3D: gPad->GetViewer3D("x3d"); break;
921 case kViewOpenGL:
922 gPad->GetViewer3D("ogl");
923 break;
924
925 // Handle Option menu items...
926 case kOptionAutoExec:
927 fCanvas->ToggleAutoExec();
928 if(fCanvas->GetAutoExec()) {
929 fOptionMenu->CheckEntry(kOptionAutoExec);
930 } else {
931 fOptionMenu->UnCheckEntry(kOptionAutoExec);
932 }
933 break;
934 case kOptionAutoResize: {
935 fAutoFit = fAutoFit ? kFALSE : kTRUE;
936 unsigned int opt = fCanvasContainer->GetOptions();
937 if(fAutoFit) {
938 opt &= ~kFixedSize;
939 fOptionMenu->CheckEntry(kOptionAutoResize);
940 } else {
941 opt |= kFixedSize;
942 fOptionMenu->UnCheckEntry(kOptionAutoResize);
943 }
944 fCanvasContainer->ChangeOptions(opt);
945 // in case of autofit this will generate a configure
946 // event for the container and this will force the
947 // update of the TCanvas
948 // Layout();
949 }
950 Layout();
951 break;
952 case kOptionResizeCanvas: FitCanvas(); break;
954 if(fCanvas->OpaqueMoving()) {
955 fCanvas->MoveOpaque(0);
956 fOptionMenu->UnCheckEntry(kOptionMoveOpaque);
957 } else {
958 fCanvas->MoveOpaque(1);
959 fOptionMenu->CheckEntry(kOptionMoveOpaque);
960 }
961 break;
963 if(fCanvas->OpaqueResizing()) {
964 fCanvas->ResizeOpaque(0);
965 fOptionMenu->UnCheckEntry(kOptionResizeOpaque);
966 } else {
967 fCanvas->ResizeOpaque(1);
968 fOptionMenu->CheckEntry(kOptionResizeOpaque);
969 }
970 break;
971 case kOptionInterrupt: gROOT->SetInterrupt(); break;
972 case kOptionRefresh:
973 fCanvas->Paint();
974 fCanvas->Update();
975 break;
977 if(gStyle->GetOptStat() != 0) {
978 gStyle->SetOptStat(0);
979 delete gPad->FindObject("stats");
980 fOptionMenu->UnCheckEntry(kOptionStatistics);
981 } else {
982 gStyle->SetOptStat(1);
983 fOptionMenu->CheckEntry(kOptionStatistics);
984 }
985 gPad->Modified();
986 fCanvas->Update();
987 break;
988 case kOptionHistTitle:
989 if(gStyle->GetOptTitle() != 0) {
990 gStyle->SetOptTitle(0);
991 delete gPad->FindObject("title");
992 fOptionMenu->UnCheckEntry(kOptionHistTitle);
993 } else {
994 gStyle->SetOptTitle(1);
995 fOptionMenu->CheckEntry(kOptionHistTitle);
996 }
997 gPad->Modified();
998 fCanvas->Update();
999 break;
1000 case kOptionFitParams:
1001 if(gStyle->GetOptFit() != 0) {
1002 gStyle->SetOptFit(0);
1003 fOptionMenu->UnCheckEntry(kOptionFitParams);
1004 } else {
1005 gStyle->SetOptFit(1);
1006 fOptionMenu->CheckEntry(kOptionFitParams);
1007 }
1008 gPad->Modified();
1009 fCanvas->Update();
1010 break;
1011 case kOptionCanEdit:
1012 if(gROOT->GetEditHistograms()) {
1013 gROOT->SetEditHistograms(kFALSE);
1014 fOptionMenu->UnCheckEntry(kOptionCanEdit);
1015 } else {
1016 gROOT->SetEditHistograms(kTRUE);
1017 fOptionMenu->CheckEntry(kOptionCanEdit);
1018 }
1019 break;
1020
1021 // Handle Tools menu items...
1022 case kInspectRoot:
1023 fCanvas->cd();
1024 gROOT->Inspect();
1025 fCanvas->Update();
1026 break;
1027 case kToolsBrowser: new TBrowser("browser"); break;
1028 case kToolsBuilder: TGuiBuilder::Instance(); break;
1029 case kToolsRecorder:
1030 gROOT->ProcessLine("new TGRecorder()");
1031 break;
1032
1033 // Handle Tools menu items...
1034 case kClassesTree: {
1035 TString cdef;
1036 auto* canvasList = static_cast<TList*>(gROOT->GetListOfCanvases());
1037 if(canvasList->FindObject("ClassTree") != nullptr) {
1038 cdef = TString::Format("ClassTree_%d", canvasList->GetSize() + 1);
1039 } else {
1040 cdef = "ClassTree";
1041 }
1042 new TClassTree(cdef.Data(), "TObject");
1043 fCanvas->Update();
1044 } break;
1045
1046 case kFitPanel: {
1047 // use plugin manager to create instance of TFitEditor
1048 TPluginHandler* handler = gROOT->GetPluginManager()->FindHandler("TFitEditor");
1049 if((handler != nullptr) && handler->LoadPlugin() != -1) {
1050 if(handler->ExecPlugin(2, fCanvas, 0) == 0) {
1051 Error("FitPanel", "Unable to crate the FitPanel");
1052 }
1053 } else {
1054 Error("FitPanel", "Unable to find the FitPanel plug-in");
1055 }
1056 } break;
1057
1058 // Handle Help menu items...
1059 case kHelpAbout: {
1060#ifdef R__UNIX
1061 TString rootx;
1062#ifdef ROOTBINDIR
1063 rootx = ROOTBINDIR;
1064#else
1065 rootx = gSystem->Getenv("ROOTSYS");
1066 if(!rootx.IsNull()) {
1067 rootx += "/bin";
1068 }
1069#endif // ROOTBINDIR
1070 rootx += "/root -a &";
1071 gSystem->Exec(rootx);
1072#else // R__UNIX
1073#ifdef WIN32
1074 new TWin32SplashThread(kTRUE);
1075#else
1076
1077 std::ostringstream str;
1078 str << "About ROOT " << gROOT->GetVersion() << "...";
1079 helperDialog = new GRootHelpDialog(this, str.str(), 600, 400);
1080 helperDialog->SetText(gHelpAbout);
1081 helperDialog->Popup();
1082#endif // WIN32
1083#endif // R__UNIX
1084 } break;
1085 case kHelpOnCanvas: {
1086 auto* helperDialog = new TRootHelpDialog(this, "Help on Canvas...", 600, 400);
1087 helperDialog->SetText(gHelpCanvas); // NOLINT(cppcoreguidelines-pro-bounds-array-to-pointer-decay)
1088 helperDialog->Popup();
1089 break;
1090 }
1091 case kHelpOnMenus: {
1092 auto* helperDialog = new TRootHelpDialog(this, "Help on Menus...", 600, 400);
1093 helperDialog->SetText(gHelpPullDownMenus); // NOLINT(cppcoreguidelines-pro-bounds-array-to-pointer-decay)
1094 helperDialog->Popup();
1095 break;
1096 }
1097 case kHelpOnGraphicsEd: {
1098 auto* helperDialog = new TRootHelpDialog(this, "Help on Graphics Editor...", 600, 400);
1099 helperDialog->SetText(gHelpGraphicsEditor); // NOLINT(cppcoreguidelines-pro-bounds-array-to-pointer-decay)
1100 helperDialog->Popup();
1101 break;
1102 }
1103 case kHelpOnBrowser: {
1104 auto* helperDialog = new TRootHelpDialog(this, "Help on Browser...", 600, 400);
1105 helperDialog->SetText(gHelpBrowser); // NOLINT(cppcoreguidelines-pro-bounds-array-to-pointer-decay)
1106 helperDialog->Popup();
1107 break;
1108 }
1109 case kHelpOnObjects: {
1110 auto* helperDialog = new TRootHelpDialog(this, "Help on Objects...", 600, 400);
1111 helperDialog->SetText(gHelpObjects); // NOLINT(cppcoreguidelines-pro-bounds-array-to-pointer-decay)
1112 helperDialog->Popup();
1113 break;
1114 }
1115 case kHelpOnPS: {
1116 auto* helperDialog = new TRootHelpDialog(this, "Help on PostScript...", 600, 400);
1117 helperDialog->SetText(gHelpPostscript); // NOLINT(cppcoreguidelines-pro-bounds-array-to-pointer-decay)
1118 helperDialog->Popup();
1119 break;
1120 }
1121 }
1122 default: break;
1123 }
1124 default: break;
1125 }
1126 return kTRUE;
1127}
1128
1129//______________________________________________________________________________
1131{
1132 /// Called by TCanvas ctor to get window indetifier.
1133
1134 if(fCanvas->OpaqueMoving()) {
1135 fOptionMenu->CheckEntry(kOptionMoveOpaque);
1136 }
1137 if(fCanvas->OpaqueResizing()) {
1138 fOptionMenu->CheckEntry(kOptionResizeOpaque);
1139 }
1140
1141 return fCanvasID;
1142}
1143
1144//______________________________________________________________________________
1145void GRootCanvas::SetCanvasSize(UInt_t w, UInt_t h)
1146{
1147 /// Set size of canvas container. Units in pixels.
1148
1149 // turn off autofit, we want to stay at the given size
1150 fAutoFit = kFALSE;
1151 fOptionMenu->UnCheckEntry(kOptionAutoResize);
1152 unsigned int opt = fCanvasContainer->GetOptions();
1153 opt |= kFixedSize; // turn on fixed size mode
1154 fCanvasContainer->ChangeOptions(opt);
1155 fCanvasContainer->SetWidth(w);
1156 fCanvasContainer->SetHeight(h);
1157 Layout(); // force layout (will update container to given size)
1158 fCanvas->Resize();
1159 fCanvas->Update();
1160}
1161
1162//______________________________________________________________________________
1164{
1165 /// Set canvas position (units in pixels).
1166
1167 Move(x, y);
1168}
1169
1170//______________________________________________________________________________
1171void GRootCanvas::SetWindowSize(UInt_t w, UInt_t h)
1172{
1173 /// Set size of canvas (units in pixels).
1174
1175 Resize(w, h);
1176
1177 // Make sure the change of size is really done.
1178 if(gThreadXAR == nullptr) {
1179 gSystem->ProcessEvents();
1180 gSystem->Sleep(10);
1181 gSystem->ProcessEvents();
1182 }
1183}
1184
1185//______________________________________________________________________________
1187{
1188 /// Put canvas window on top of the window stack.
1189
1190 gVirtualX->RaiseWindow(GetId());
1191}
1192
1193//______________________________________________________________________________
1194void GRootCanvas::SetWindowTitle(const char* title)
1195{
1196 /// Change title on window.
1197
1198 SetWindowName(title);
1199 SetIconName(title);
1200 fToolDock->SetWindowName(Form("ToolBar: %s", title));
1201}
1202
1203//______________________________________________________________________________
1205{
1206 /// Fit canvas container to current window size.
1207
1208 if(!fAutoFit) {
1209 unsigned int opt = fCanvasContainer->GetOptions();
1210 unsigned int oopt = opt;
1211 opt &= ~kFixedSize; // turn off fixed size mode
1212 fCanvasContainer->ChangeOptions(opt);
1213 Layout(); // force layout
1214 fCanvas->Resize();
1215 fCanvas->Update();
1216 fCanvasContainer->ChangeOptions(oopt);
1217 }
1218}
1219
1220//______________________________________________________________________________
1222{
1223 /// Print the canvas.
1224
1225 Int_t ret = 0;
1226 Bool_t pname = kTRUE;
1227 char* printer = nullptr;
1228 char* printCmd = nullptr;
1229 static TString sprinter;
1230 static TString sprintCmd;
1231
1232 if(sprinter == "") {
1233 printer = StrDup(gEnv->GetValue("Print.Printer", ""));
1234 } else {
1235 printer = StrDup(sprinter);
1236 }
1237 if(sprintCmd == "") {
1238#ifndef WIN32
1239 printCmd = StrDup(gEnv->GetValue("Print.Command", ""));
1240#else
1241 printCmd = StrDup(gEnv->GetValue("Print.Command", "start AcroRd32.exe /p"));
1242#endif
1243 } else {
1244 printCmd = StrDup(sprintCmd);
1245 }
1246
1247 new TGPrintDialog(fClient->GetDefaultRoot(), this, 400, 150, &printer, &printCmd, &ret);
1248 if(ret != 0) {
1249 sprinter = printer;
1250 sprintCmd = printCmd;
1251
1252 if(sprinter == "") {
1253 pname = kFALSE;
1254 }
1255
1256 TString fn = "rootprint";
1257 FILE* f = gSystem->TempFileName(fn, gEnv->GetValue("Print.Directory", gSystem->TempDirectory()));
1258 if(f != nullptr) {
1259 fclose(f);
1260 }
1261 fn += TString::Format(".%s", gEnv->GetValue("Print.FileType", "pdf"));
1262 fCanvas->Print(fn);
1263
1264 TString cmd = sprintCmd;
1265 if(cmd.Contains("%p")) {
1266 cmd.ReplaceAll("%p", sprinter);
1267 } else if(pname) {
1268 cmd += " ";
1269 cmd += sprinter;
1270 cmd += " ";
1271 }
1272
1273 if(cmd.Contains("%f")) {
1274 cmd.ReplaceAll("%f", fn);
1275 } else {
1276 cmd += " ";
1277 cmd += fn;
1278 cmd += " ";
1279 }
1280
1281 gSystem->Exec(cmd);
1282#ifndef WIN32
1283 gSystem->Unlink(fn);
1284#endif
1285 }
1286 delete[] printer;
1287 delete[] printCmd;
1288}
1289
1290//______________________________________________________________________________
1291void GRootCanvas::EventInfo(Int_t event, Int_t px, Int_t py, TObject* selected)
1292{
1293 /// Display a tooltip with infos about the primitive below the cursor.
1294
1295 fToolTip->Hide();
1296 if(!fCanvas->GetShowToolTips() || selected == nullptr || event != kMouseMotion || fButton != 0) {
1297 return;
1298 }
1299 TString tipInfo;
1300 TString objInfo = selected->GetObjectInfo(px, py);
1301 if(objInfo.BeginsWith("-")) {
1302 // if the string begins with '-', display only the object info
1303 objInfo.Remove(TString::kLeading, '-');
1304 tipInfo = objInfo;
1305 } else {
1306 const char* title = selected->GetTitle();
1307 tipInfo += TString::Format("%s::%s", selected->ClassName(), selected->GetName());
1308 if((title != nullptr) && (strlen(title) != 0u)) {
1309 tipInfo += TString::Format("\n%s", selected->GetTitle());
1310 }
1311 tipInfo += TString::Format("\n%d, %d", px, py);
1312 if(!objInfo.IsNull()) {
1313 tipInfo += TString::Format("\n%s", objInfo.Data());
1314 }
1315 }
1316 fToolTip->SetText(tipInfo.Data());
1317 fToolTip->SetPosition(px + 15, py + 15);
1318 fToolTip->Reset();
1319}
1320
1321//______________________________________________________________________________
1323{
1324 /// Show or hide menubar.
1325
1326 if(show) {
1327 ShowFrame(fMenuBar);
1328 } else {
1329 HideFrame(fMenuBar);
1330 }
1331}
1332
1333//______________________________________________________________________________
1335{
1336 /// Show or hide statusbar.
1337
1338 UInt_t dh = fClient->GetDisplayHeight();
1339 UInt_t ch = fCanvas->GetWindowHeight();
1340
1341 UInt_t h = GetHeight();
1342 UInt_t sh = fStatusBar->GetHeight() + 2;
1343
1344 if(show) {
1345 ShowFrame(fStatusBar);
1346 fViewMenu->CheckEntry(kViewEventStatus);
1347 if(dh - ch >= sh) {
1348 h = h + sh;
1349 } else {
1350 h = ch;
1351 }
1352 } else {
1353 HideFrame(fStatusBar);
1354 fViewMenu->UnCheckEntry(kViewEventStatus);
1355 if(dh - ch < sh) {
1356 h = ch;
1357 } else {
1358 h = h - sh;
1359 }
1360 }
1361 Resize(GetWidth(), h);
1362}
1363
1364//______________________________________________________________________________
1366{
1367 /// Show or hide side frame.
1368
1369 TVirtualPad* savedPad = nullptr;
1370 savedPad = gPad;
1371 gPad = Canvas();
1372
1373 UInt_t w = GetWidth();
1374 UInt_t e = fEditorFrame->GetWidth();
1375 UInt_t h = GetHeight();
1376 UInt_t s = fHorizontal1->GetHeight();
1377
1378 if((fParent != nullptr) && fParent != fClient->GetDefaultRoot()) {
1379 const auto* main = static_cast<const TGMainFrame*>(fParent->GetMainFrame()); // fParent is of type TGWindow, so GetMainFrame returns "const TGWindow*"
1380 fMainFrame->HideFrame(fEditorFrame);
1381 if((main != nullptr) && main->InheritsFrom("TRootBrowser")) {
1382 auto* browser = const_cast<TRootBrowser*>(static_cast<const TRootBrowser*>(main)); // NOLINT(cppcoreguidelines-pro-type-const-cast)
1383 if(!fEmbedded) {
1384 browser->GetTabRight()->Connect("Selected(Int_t)", "GRootCanvas", this, "Activated(Int_t)");
1385 }
1386 fEmbedded = kTRUE;
1387 if(show && ((fEditor == nullptr) || !static_cast<TGedEditor*>(fEditor)->IsMapped())) {
1388 if(browser->GetTabLeft()->GetTabTab("Pad Editor") == nullptr) {
1389 browser->StartEmbedding(TRootBrowser::kLeft);
1390 if(fEditor == nullptr) {
1391 fEditor = TVirtualPadEditor::GetPadEditor(kTRUE);
1392 } else {
1393 static_cast<TGedEditor*>(fEditor)->ReparentWindow(fClient->GetRoot());
1394 static_cast<TGedEditor*>(fEditor)->MapWindow();
1395 }
1396 browser->StopEmbedding("Pad Editor");
1397 fEditor->SetGlobal(kFALSE);
1398 gROOT->GetListOfCleanups()->Remove(static_cast<TGedEditor*>(fEditor));
1399 if(fEditor != nullptr) {
1400 static_cast<TGedEditor*>(fEditor)->SetCanvas(fCanvas);
1401 static_cast<TGedEditor*>(fEditor)->SetModel(fCanvas, fCanvas, kButton1Down);
1402 }
1403 }
1404 fEditor = TVirtualPadEditor::GetPadEditor(kFALSE);
1405 }
1406 if(show) {
1407 browser->GetTabLeft()->SetTab("Pad Editor");
1408 }
1409 }
1410 } else {
1411 if(show) {
1412 if(fEditor == nullptr) {
1413 CreateEditor();
1414 }
1415 TVirtualPadEditor* gged = TVirtualPadEditor::GetPadEditor(kFALSE);
1416 if((gged != nullptr) && gged->GetCanvas() == fCanvas) {
1417 gged->Hide();
1418 }
1419 if(!fViewMenu->IsEntryChecked(kViewToolbar) || fToolDock->IsUndocked()) {
1420 ShowFrame(fHorizontal1);
1421 h = h + s;
1422 }
1423 fMainFrame->ShowFrame(fEditorFrame);
1424 fEditor->Show();
1425 fViewMenu->CheckEntry(kViewEditor);
1426 w = w + e;
1427 } else {
1428 if(!fViewMenu->IsEntryChecked(kViewToolbar) || fToolDock->IsUndocked()) {
1429 HideFrame(fHorizontal1);
1430 h = h - s;
1431 }
1432 if(fEditor != nullptr) {
1433 fEditor->Hide();
1434 }
1435 fMainFrame->HideFrame(fEditorFrame);
1436 fViewMenu->UnCheckEntry(kViewEditor);
1437 w = w - e;
1438 }
1439 Resize(w, h);
1440 }
1441 if(savedPad != nullptr) {
1442 gPad = savedPad;
1443 }
1444}
1445
1446//______________________________________________________________________________
1448{
1449 /// Create embedded editor.
1450
1451 fEditorFrame->SetEditDisabled(kEditEnable);
1452 fEditorFrame->SetEditable();
1453 gPad = Canvas();
1454 // next two lines are related to the old editor
1455 Int_t show = gEnv->GetValue("Canvas.ShowEditor", 0);
1456 gEnv->SetValue("Canvas.ShowEditor", "true");
1457 fEditor = TVirtualPadEditor::LoadEditor();
1458 if(fEditor != nullptr) {
1459 fEditor->SetGlobal(kFALSE);
1460 }
1461 fEditorFrame->SetEditable(kEditDisable != 0u);
1462 fEditorFrame->SetEditable(kFALSE);
1463
1464 // next line is related to the old editor
1465 if(show == 0) {
1466 gEnv->SetValue("Canvas.ShowEditor", "false");
1467 }
1468}
1469
1470//______________________________________________________________________________
1472{
1473 /// Show or hide toolbar.
1474
1475 if(show && (fToolBar == nullptr)) {
1476
1477 fToolBar = new TGToolBar(fToolDock, 60, 20, kHorizontalFrame);
1479
1480 Int_t spacing = 6;
1481 for(Int_t i = 0; gToolBarData[i].fPixmap != nullptr; i++) {
1482 if(strlen(gToolBarData[i].fPixmap) == 0) {
1483 spacing = 6;
1484 continue;
1485 }
1486 fToolBar->AddButton(this, &gToolBarData[i], spacing);
1487 spacing = 0;
1488 }
1489 fVertical1 = new TGVertical3DLine(fToolBar);
1490 fVertical2 = new TGVertical3DLine(fToolBar);
1491 fVertical1Layout = new TGLayoutHints(kLHintsLeft | kLHintsExpandY, 4, 2, 0, 0);
1492 fVertical2Layout = new TGLayoutHints(kLHintsLeft | kLHintsExpandY);
1495
1496 spacing = 6;
1497 for(Int_t i = 0; gToolBarData1[i].fPixmap != nullptr; i++) {
1498 if(strlen(gToolBarData1[i].fPixmap) == 0) {
1499 spacing = 6;
1500 continue;
1501 }
1502 fToolBar->AddButton(this, &gToolBarData1[i], spacing);
1503 spacing = 0;
1504 }
1505 fToolDock->MapSubwindows();
1506 fToolDock->Layout();
1507 fToolDock->SetWindowName(Form("ToolBar: %s", GetWindowName()));
1508 fToolDock->Connect("Docked()", "GRootCanvas", this, "AdjustSize()");
1509 fToolDock->Connect("Undocked()", "GRootCanvas", this, "AdjustSize()");
1510 }
1511
1512 if(fToolBar == nullptr) {
1513 return;
1514 }
1515
1516 UInt_t h = GetHeight();
1517 UInt_t sh = fToolBarSep->GetHeight();
1518 UInt_t dh = fToolBar->GetHeight();
1519
1520 if(show) {
1521 ShowFrame(fToolDock);
1522 if(!fViewMenu->IsEntryChecked(kViewEditor)) {
1523 ShowFrame(fHorizontal1);
1524 h = h + sh;
1525 }
1526 ShowFrame(fToolBarSep);
1527 fViewMenu->CheckEntry(kViewToolbar);
1528 h = h + dh + sh;
1529 } else {
1530 if(fToolDock->IsUndocked()) {
1531 fToolDock->DockContainer();
1532 h = h + 2 * sh;
1533 } else {
1534 h = h - dh;
1535 }
1536
1537 HideFrame(fToolDock);
1538 if(!fViewMenu->IsEntryChecked(kViewEditor)) {
1539 HideFrame(fHorizontal1);
1540 h = h - sh;
1541 }
1542 HideFrame(fToolBarSep);
1543 h = h - sh;
1544 fViewMenu->UnCheckEntry(kViewToolbar);
1545 }
1546 Resize(GetWidth(), h);
1547}
1548
1549//______________________________________________________________________________
1551{
1552 /// Enable or disable tooltip info.
1553
1554 if(show) {
1555 fViewMenu->CheckEntry(kViewToolTips);
1556 } else {
1557 fViewMenu->UnCheckEntry(kViewToolTips);
1558 }
1559}
1560
1561//______________________________________________________________________________
1563{
1564 /// Returns kTRUE if the editor is shown.
1565
1566 return ((fEditor) != nullptr) && fViewMenu->IsEntryChecked(kViewEditor);
1567}
1568
1569//______________________________________________________________________________
1571{
1572 /// Returns kTRUE if the menu bar is shown.
1573
1574 return ((fMenuBar) != nullptr) && fMenuBar->IsMapped();
1575}
1576
1577//______________________________________________________________________________
1579{
1580 /// Returns kTRUE if the status bar is shown.
1581
1582 return ((fStatusBar) != nullptr) && fStatusBar->IsMapped();
1583}
1584
1585//______________________________________________________________________________
1587{
1588 /// Returns kTRUE if the tool bar is shown.
1589
1590 return ((fToolBar) != nullptr) && fToolBar->IsMapped();
1591}
1592
1593//______________________________________________________________________________
1595{
1596 /// Returns kTRUE if the tooltips are enabled.
1597
1598 return ((fCanvas) != nullptr) && fCanvas->GetShowToolTips();
1599}
1600
1601//______________________________________________________________________________
1603{
1604 /// Keep the same canvas size while docking/undocking toolbar.
1605
1606 UInt_t h = GetHeight();
1607 UInt_t dh = fToolBar->GetHeight();
1608 UInt_t sh = fHorizontal1->GetHeight();
1609
1610 if(fToolDock->IsUndocked()) {
1611 if(!fViewMenu->IsEntryChecked(kViewEditor)) {
1612 HideFrame(fHorizontal1);
1613 h = h - sh;
1614 }
1615 HideFrame(fToolBarSep);
1616 h = h - dh - sh;
1617 } else {
1618 if(!fViewMenu->IsEntryChecked(kViewEditor)) {
1619 ShowFrame(fHorizontal1);
1620 h = h + sh;
1621 }
1622 ShowFrame(fToolBarSep);
1623 h = h + dh + sh;
1624 }
1625 Resize(GetWidth(), h);
1626}
1627
1628//______________________________________________________________________________
1630{
1631 /// Handle mouse button events in the canvas container.
1632
1633 UInt_t button = event->fCode;
1634 Int_t x = event->fX;
1635 Int_t y = event->fY;
1636
1637 if(event->fType == kButtonPress) {
1638 if((fToolTip != nullptr) && fCanvas->GetShowToolTips()) {
1639 fToolTip->Hide();
1640 gVirtualX->UpdateWindow(0);
1641 gSystem->ProcessEvents();
1642 }
1643 fButton = button;
1644 if(button == kButton1) {
1645 if((event->fState & kKeyShiftMask) != 0u) {
1646 (static_cast<GCanvas*>(fCanvas))->HandleInput(kButton1Shift, x, y);
1647 } else if((event->fState & kKeyControlMask) != 0u) {
1648 (static_cast<GCanvas*>(fCanvas))->HandleInput(kButton1Ctrl, x, y);
1649 } else {
1650 (static_cast<GCanvas*>(fCanvas))->HandleInput(kButton1Down, x, y);
1651 }
1652 }
1653 if(button == kButton2) {
1654 (static_cast<GCanvas*>(fCanvas))->HandleInput(kButton2Down, x, y);
1655 }
1656 if(button == kButton3) {
1657 (static_cast<GCanvas*>(fCanvas))->HandleInput(kButton3Down, x, y);
1658 fButton = 0; // button up is consumed by TContextMenu
1659 }
1660
1661 } else if(event->fType == kButtonRelease) {
1662 if(button == kButton4) {
1663 (static_cast<GCanvas*>(fCanvas))->HandleInput(kWheelUp, x, y);
1664 }
1665 if(button == kButton5) {
1666 (static_cast<GCanvas*>(fCanvas))->HandleInput(kWheelDown, x, y);
1667 }
1668 if(button == kButton1) {
1669 (static_cast<GCanvas*>(fCanvas))->HandleInput(kButton1Up, x, y);
1670 }
1671 if(button == kButton2) {
1672 (static_cast<GCanvas*>(fCanvas))->HandleInput(kButton2Up, x, y);
1673 }
1674 if(button == kButton3) {
1675 (static_cast<GCanvas*>(fCanvas))->HandleInput(kButton3Up, x, y);
1676 }
1677
1678 fButton = 0;
1679 }
1680
1681 return kTRUE;
1682}
1683
1684//______________________________________________________________________________
1686{
1687 /// Handle mouse button double click events in the canvas container.
1688
1689 UInt_t button = event->fCode;
1690 Int_t x = event->fX;
1691 Int_t y = event->fY;
1692
1693 if(button == kButton1) {
1694 (static_cast<GCanvas*>(fCanvas))->HandleInput(kButton1Double, x, y);
1695 }
1696 if(button == kButton2) {
1697 (static_cast<GCanvas*>(fCanvas))->HandleInput(kButton2Double, x, y);
1698 }
1699 if(button == kButton3) {
1700 (static_cast<GCanvas*>(fCanvas))->HandleInput(kButton3Double, x, y);
1701 }
1702
1703 return kTRUE;
1704}
1705
1706//______________________________________________________________________________
1708{
1709 /// Handle configure (i.e. resize) event.
1710 if(fAutoFit) {
1711 fCanvas->Resize();
1712 fCanvas->Update();
1713 }
1714
1715 if(fCanvas->HasFixedAspectRatio()) {
1716 // get menu height
1717 static UInt_t dh = 0;
1718 if(dh == 0) {
1719 dh = GetHeight() - fCanvasContainer->GetHeight();
1720 }
1721 UInt_t h = TMath::Nint(fCanvasContainer->GetWidth() / fCanvas->GetAspectRatio()) + dh;
1722 SetWindowSize(GetWidth(), h);
1723 }
1724 return kTRUE;
1725}
1726
1727//______________________________________________________________________________
1729{
1730 /// Handle keyboard events in the canvas container.
1731
1732 ///
1733 /// This is the function I wanted to edit so bad that
1734 /// I went through all the trouble to copy this thing.
1735 /// This will allow us to take complete control of the
1736 /// canvas interface make a more root-ish/radware-isf
1737 /// work enviorment. pcb.
1738 ///
1739
1740 static EGEventType previous_event = kOtherEvent;
1741 static UInt_t previous_keysym = 0;
1742
1743 UInt_t keysym = 0;
1744 std::array<char, 2> str;
1745 gVirtualX->LookupString(event, str.data(), str.size(), keysym);
1746
1747 if(event->fType == kGKeyPress) {
1748 fButton = event->fCode;
1749
1750 if(str[0] == kESC) { // ESC sets the escape flag
1751 gROOT->SetEscape();
1752 static_cast<GCanvas*>(fCanvas)->HandleInput(kButton1Up, 0, 0);
1753 static_cast<GCanvas*>(fCanvas)->HandleInput(kMouseMotion, 0, 0);
1754 gPad->Modified();
1755 return kTRUE;
1756 }
1757 if(str[0] == 3) { // ctrl-c sets the interrupt flag
1758 gROOT->SetInterrupt();
1759 }
1760
1761 // handle arrow keys
1762 if(keysym > 0x1011 && keysym < 0x1016) {
1763 Window_t dum1 = 0;
1764 Window_t dum2 = 0;
1765 Window_t wid = 0;
1766 UInt_t mask = 0;
1767 Int_t mx = 0;
1768 Int_t my = 0;
1769 Int_t tx = 0;
1770 Int_t ty = 0;
1771 wid = gVirtualX->GetDefaultRootWindow();
1772 gVirtualX->QueryPointer(wid, dum1, dum2, mx, my, mx, my, mask);
1773 gVirtualX->TranslateCoordinates(gClient->GetDefaultRoot()->GetId(), fCanvasContainer->GetId(), mx, my, tx, ty, dum1);
1774
1775 //((GCanvas*)fCanvas)->HandleInput(kArrowKeyPress, tx, ty);
1776 static_cast<GCanvas*>(fCanvas)->HandleInput(static_cast<EEventType>(kArrowKeyPress), tx, keysym);
1777 // handle case where we got consecutive same keypressed events coming
1778 // from auto-repeat on Windows (as it fires only successive keydown events)
1779 if((previous_keysym == keysym) && (previous_event == kGKeyPress)) {
1780 switch(keysym) {
1781 case 0x1012: // left
1782 // gVirtualX->Warp(--mx, my, wid); --tx;
1783 break;
1784 case 0x1013: // up
1785 // gVirtualX->Warp(mx, --my, wid); --ty;
1786 break;
1787 case 0x1014: // right
1788 // gVirtualX->Warp(++mx, my, wid); ++tx;
1789 break;
1790 case 0x1015: // down
1791 // gVirtualX->Warp(mx, ++my, wid); ++ty;
1792 break;
1793 default: break;
1794 }
1795 static_cast<GCanvas*>(fCanvas)->HandleInput(static_cast<EEventType>(kArrowKeyRelease), tx, ty);
1796 }
1797 previous_keysym = keysym;
1798 } else {
1799 static_cast<GCanvas*>(fCanvas)->HandleInput(kKeyPress, str[0], keysym);
1800 }
1801 } else if(event->fType == kKeyRelease) {
1802 if(keysym > 0x1011 && keysym < 0x1016) {
1803 Window_t dum1 = 0;
1804 Window_t dum2 = 0;
1805 Window_t wid = 0;
1806 UInt_t mask = 0;
1807 Int_t mx = 0;
1808 Int_t my = 0;
1809 Int_t tx = 0;
1810 Int_t ty = 0;
1811 wid = gVirtualX->GetDefaultRootWindow();
1812 gVirtualX->QueryPointer(wid, dum1, dum2, mx, my, mx, my, mask);
1813
1814 auto* gCanvas = static_cast<GCanvas*>(gPad->GetCanvas());
1815 gCanvas->HandleArrowKeyPress(event, &keysym);
1816 gVirtualX->TranslateCoordinates(gClient->GetDefaultRoot()->GetId(), fCanvasContainer->GetId(), mx, my, tx, ty,
1817 dum1);
1818 static_cast<GCanvas*>(fCanvas)->HandleInput(static_cast<EEventType>(kArrowKeyRelease), tx, ty);
1819 previous_keysym = keysym;
1820 } else {
1821 auto* gCanvas = static_cast<GCanvas*>(gPad->GetCanvas());
1822 gCanvas->HandleKeyboardPress(event, &keysym);
1823 }
1824
1825 fButton = 0;
1826 }
1827 previous_event = event->fType;
1828 return kTRUE;
1829}
1830
1831//______________________________________________________________________________
1833{
1834 /// Handle mouse motion event in the canvas container.
1835
1836 Int_t x = event->fX;
1837 Int_t y = event->fY;
1838
1839 if(fButton == 0) {
1840 static_cast<GCanvas*>(fCanvas)->HandleInput(kMouseMotion, x, y);
1841 }
1842 if(fButton == kButton1) {
1843 if((event->fState & kKeyShiftMask) != 0u) {
1844 static_cast<GCanvas*>(fCanvas)->HandleInput(static_cast<EEventType>(8), x, y);
1845 } else {
1846 static_cast<GCanvas*>(fCanvas)->HandleInput(kButton1Motion, x, y);
1847 }
1848 }
1849 if(fButton == kButton2) {
1850 static_cast<GCanvas*>(fCanvas)->HandleInput(kButton2Motion, x, y);
1851 }
1852
1853 return kTRUE;
1854}
1855
1856//______________________________________________________________________________
1858{
1859 /// Handle expose events.
1860
1861 if(event->fCount == 0) {
1862 fCanvas->Flush();
1863 }
1864
1865 return kTRUE;
1866}
1867
1868//______________________________________________________________________________
1870{
1871 /// Handle enter/leave events. Only leave is activated at the moment.
1872
1873 Int_t x = event->fX;
1874 Int_t y = event->fY;
1875
1876 // pointer grabs create also an enter and leave event but with fCode
1877 // either kNotifyGrab or kNotifyUngrab, don't propagate these events
1878 if(event->fType == kLeaveNotify && event->fCode == kNotifyNormal) {
1879 (static_cast<GCanvas*>(fCanvas))->HandleInput(kMouseLeave, x, y);
1880 }
1881
1882 return kTRUE;
1883}
1884
1885//______________________________________________________________________________
1886Bool_t GRootCanvas::HandleDNDDrop(TDNDData* data)
1887{
1888 /// Handle drop events.
1889
1890 static Atom_t rootObj = gVirtualX->InternAtom("application/root", kFALSE);
1891 static Atom_t uriObj = gVirtualX->InternAtom("text/uri-list", kFALSE);
1892
1893 if(data->fDataType == rootObj) {
1894 TBufferFile buf(TBuffer::kRead, data->fDataLength, data->fData);
1895 buf.SetReadMode();
1896 auto* obj = reinterpret_cast<TObject*>(buf.ReadObjectAny(TObject::Class()));
1897 if(obj == nullptr) {
1898 return kTRUE;
1899 }
1900 gPad->Clear();
1901 if(obj->InheritsFrom("TKey")) {
1902 auto* object = reinterpret_cast<TObject*>(gROOT->ProcessLine(Form("((TKey *)0x%lx)->ReadObj();", reinterpret_cast<ULong_t>(obj)))); // NOLINT(performance-no-int-to-ptr)
1903 if(object == nullptr) {
1904 return kTRUE;
1905 }
1906 if(object->InheritsFrom("TGraph")) {
1907 object->Draw("ALP");
1908 } else if(object->InheritsFrom("TImage")) {
1909 object->Draw("x");
1910 } else if(object->IsA()->GetMethodAllAny("Draw") != nullptr) {
1911 object->Draw();
1912 }
1913 } else if(obj->InheritsFrom("TGraph")) {
1914 obj->Draw("ALP");
1915 } else if(obj->IsA()->GetMethodAllAny("Draw") != nullptr) {
1916 obj->Draw();
1917 }
1918 gPad->Modified();
1919 gPad->Update();
1920 return kTRUE;
1921 }
1922 if(data->fDataType == uriObj) {
1923 TString sfname(reinterpret_cast<char*>(data->fData));
1924 if(sfname.Length() > 7) {
1925 sfname.ReplaceAll("\r\n", "");
1926 TUrl uri(sfname.Data());
1927 if(sfname.EndsWith(".bmp") || sfname.EndsWith(".gif") || sfname.EndsWith(".jpg") || sfname.EndsWith(".png") ||
1928 sfname.EndsWith(".ps") || sfname.EndsWith(".eps") || sfname.EndsWith(".pdf") || sfname.EndsWith(".tiff") ||
1929 sfname.EndsWith(".xpm")) {
1930 TImage* img = TImage::Open(uri.GetFile());
1931 if(img != nullptr) {
1932 img->Draw("x");
1933 img->SetEditable(kTRUE);
1934 }
1935 }
1936 gPad->Modified();
1937 gPad->Update();
1938 }
1939 }
1940 return kFALSE;
1941}
1942
1943//______________________________________________________________________________
1944Atom_t GRootCanvas::HandleDNDPosition(Int_t x, Int_t y, Atom_t action, Int_t /*xroot*/, Int_t /*yroot*/)
1945{
1946 /// Handle dragging position events.
1947
1948 TPad* pad = fCanvas->Pick(x, y, nullptr);
1949 if(pad != nullptr) {
1950 pad->cd();
1951 gROOT->SetSelectedPad(pad);
1952 // make sure the pad is highlighted (on Windows)
1953 pad->Update();
1954 }
1955 return action;
1956}
1957
1958//______________________________________________________________________________
1959Atom_t GRootCanvas::HandleDNDEnter(Atom_t* typelist)
1960{
1961 /// Handle drag enter events.
1962
1963 static Atom_t rootObj = gVirtualX->InternAtom("application/root", kFALSE);
1964 static Atom_t uriObj = gVirtualX->InternAtom("text/uri-list", kFALSE);
1965 Atom_t ret = kNone;
1966 for(int i = 0; typelist[i] != kNone; ++i) {
1967 if(typelist[i] == rootObj) {
1968 ret = rootObj;
1969 }
1970 if(typelist[i] == uriObj) {
1971 ret = uriObj;
1972 }
1973 }
1974 return ret;
1975}
1976
1977//______________________________________________________________________________
1979{
1980 /// Handle drag leave events.
1981
1982 return kTRUE;
1983}
1984
1985//______________________________________________________________________________
1987{
1988 /// Slot handling tab switching in the browser, to properly set the canvas
1989 /// and the model to the editor.
1990
1991 if(fEmbedded) {
1992 auto* sender = reinterpret_cast<TGTab*>(gTQSender);
1993 if(sender != nullptr) {
1994 TGCompositeFrame* cont = sender->GetTabContainer(id);
1995 if(cont == fParent) {
1996 if(fEditor == nullptr) {
1997 fEditor = TVirtualPadEditor::GetPadEditor(kFALSE);
1998 }
1999 if(fEditor != nullptr && static_cast<TGedEditor*>(fEditor)->IsMapped()) {
2000 static_cast<TGedEditor*>(fEditor)->SetCanvas(fCanvas);
2001 static_cast<TGedEditor*>(fEditor)->SetModel(fCanvas, fCanvas, kButton1Down);
2002 }
2003 }
2004 }
2005 }
2006}
2007
2008//______________________________________________________________________________
2009void GRootContainer::SavePrimitive(std::ostream& out, Option_t* /*= ""*/)
2010{
2011 /// Save a canvas container as a C++ statement(s) on output stream out.
2012
2013 out << std::endl
2014 << " // canvas container" << std::endl;
2015 out << " Int_t canvasID = gVirtualX->InitWindow((ULong_t)" << GetParent()->GetParent()->GetName() << "->GetId());" << std::endl;
2016 out << " Window_t winC = gVirtualX->GetWindowID(canvasID);" << std::endl;
2017 out << " TGCompositeFrame *";
2018 out << GetName() << " = new TGCompositeFrame(gClient, winC, " << GetParent()->GetName() << ");" << std::endl;
2019}
int main(int argc, char **argv)
#define kArrowKeyRelease
Definition GCanvas.cxx:49
#define kArrowKeyPress
Definition GCanvas.cxx:48
ERootCanvasCommands
@ kOptionInterrupt
@ kToolLatex
@ kFitPanel
@ kToolsBuilder
@ kToolPLabel
@ kEditStyle
@ kOptionCanEdit
@ kOptionResizeOpaque
@ kEditClearCanvas
@ kToolPad
@ kFilePrint
@ kViewOpenGL
@ kEditRedo
@ kHelpOnCanvas
@ kToolDiamond
@ kToolCurlyLine
@ kViewFonts
@ kToolLine
@ kFileSaveAsPDF
@ kViewIconify
@ kFileCloseCanvas
@ kViewX3D
@ kFileSaveAs
@ kToolEllipse
@ kToolPsText
@ kToolModify
@ kFileSaveAsGIF
@ kFileQuit
@ kToolArrow
@ kToolArc
@ kToolsRecorder
@ kToolsBrowser
@ kOptionResizeCanvas
@ kToolPave
@ kHelpOnGraphicsEd
@ kFileNewCanvas
@ kOptionFitParams
@ kOptionRefresh
@ kHelpOnObjects
@ kEditCopy
@ kFileSaveAsEPS
@ kInspectRoot
@ kViewToolTips
@ kOptionMoveOpaque
@ kViewEditor
@ kHelpOnBrowser
@ kClassesTree
@ kToolPText
@ kViewToolbar
@ kOptionAutoExec
@ kHelpOnMenus
@ kEditUndo
@ kHelpOnPS
@ kFileSaveAsPNG
@ kViewMarkers
@ kEditClearPad
@ kToolCurlyArc
@ kEditCut
@ kFileSaveAsC
@ kViewColors
@ kToolGraph
@ kViewEventStatus
@ kFileSaveAsPS
@ kOptionStatistics
@ kFileSaveAsJPG
@ kOptionHistTitle
@ kHelpAbout
@ kToolCutG
@ kToolMarker
@ kFileSaveAsRoot
@ kFileOpen
@ kEditPaste
@ kOptionAutoResize
static std::array< const char *, 32 > gSaveAsTypes
static std::array< ToolBarData_t, 18 > gToolBarData1
constexpr int kButton1Ctrl
static std::array< const char *, 6 > gOpenTypes
constexpr int kButton1CtrlMotion
static std::array< ToolBarData_t, 11 > gToolBarData
static std::string sh(const std::string &cmd)
Definition Globals.h:158
const Double_t s
bool HandleArrowKeyPress(Event_t *event, const UInt_t *keysym)
Definition GCanvas.cxx:348
bool HandleKeyboardPress(Event_t *event, const UInt_t *keysym)
Definition GCanvas.cxx:362
Bool_t HandleContainerMotion(Event_t *event)
void SetWindowSize(UInt_t w, UInt_t h) override
TGCanvas * fCanvasWindow
canvas widget
Definition GRootCanvas.h:51
void EventInfo(Int_t event, Int_t px, Int_t py, TObject *selected)
Int_t fButton
currently pressed button
Definition GRootCanvas.h:92
TGPopupMenu * fEditClearMenu
clear cascade submenu
Definition GRootCanvas.h:57
TGCompositeFrame * fEditorFrame
side frame for current pad editor
Definition GRootCanvas.h:70
Bool_t HandleContainerCrossing(Event_t *event)
void SetWindowTitle(const char *title) override
TGLayoutHints * fToolBarLayout
layout for toolbar widget
Definition GRootCanvas.h:73
void ShowToolTips(Bool_t show=kTRUE) override
TGLayoutHints * fDockLayout
layout hints for dockable frame widget
Definition GRootCanvas.h:84
void ShowStatusBar(Bool_t show=kTRUE) override
Bool_t HandleContainerDoubleClick(Event_t *event)
TGVertical3DLine * fVertical2
toolbar vertical separator
Definition GRootCanvas.h:78
const TGPicture * fIconPic
icon picture
Definition GRootCanvas.h:85
TGHorizontal3DLine * fHorizontal1
toolbar sepatator
Definition GRootCanvas.h:79
TGPopupMenu * fOptionMenu
option menu
Definition GRootCanvas.h:60
friend class GRootContainer
Definition GRootCanvas.h:48
Bool_t HandleContainerKey(Event_t *event)
TGLayoutHints * fEditorLayout
layout for editor frame
Definition GRootCanvas.h:71
UInt_t GetCwidth() const
Bool_t HandleContainerConfigure(Event_t *ev)
Bool_t HandleContainerExpose(Event_t *event)
void CreateCanvas(const char *name)
Bool_t HasToolTips() const override
void Activated(Int_t id)
TGMenuBar * fMenuBar
menubar
Definition GRootCanvas.h:53
TGLayoutHints * fHorizontal1Layout
layout hints for separator
Definition GRootCanvas.h:82
TGVertical3DLine * fVertical1
toolbar vertical separator
Definition GRootCanvas.h:77
TGLayoutHints * fStatusBarLayout
layout hints for statusbar
Definition GRootCanvas.h:68
TGDockableFrame * fToolDock
dockable frame holding the toolbar
Definition GRootCanvas.h:83
void CreateEditor()
Bool_t HandleDNDLeave() override
Bool_t HasEditor() const override
void SetCanvasSize(UInt_t w, UInt_t h) override
TGLayoutHints * fCanvasLayout
layout for canvas widget
Definition GRootCanvas.h:66
GRootCanvas(const GRootCanvas &)
TGLayoutHints * fVertical2Layout
layout hints for separator
Definition GRootCanvas.h:81
TGPopupMenu * fFileSaveMenu
save cascade submenu
Definition GRootCanvas.h:55
TGHorizontal3DLine * fToolBarSep
toolbar separator
Definition GRootCanvas.h:75
TGLayoutHints * fMenuBarLayout
menubar layout hints
Definition GRootCanvas.h:63
Bool_t HasStatusBar() const override
TGLayoutHints * fVertical1Layout
layout hints for separator
Definition GRootCanvas.h:80
TGPopupMenu * fToolsMenu
tools menu
Definition GRootCanvas.h:61
Bool_t HasToolBar() const override
Int_t InitWindow() override
TGLayoutHints * fMainFrameLayout
layout for main frame
Definition GRootCanvas.h:76
Bool_t ProcessMessage(Long_t msg, Long_t parm1, Long_t parm2) override
void RaiseWindow() override
TGStatusBar * fStatusBar
statusbar widget
Definition GRootCanvas.h:67
Bool_t HandleContainerButton(Event_t *event)
Atom_t HandleDNDEnter(Atom_t *typelist) override
GRootContainer * fCanvasContainer
container in canvas widget
Definition GRootCanvas.h:52
void Iconify() override
Atom_t HandleDNDPosition(Int_t x, Int_t y, Atom_t action, Int_t xroot, Int_t yroot) override
void ShowToolBar(Bool_t show=kTRUE) override
void SetWindowPosition(Int_t x, Int_t y) override
void ShowEditor(Bool_t show=kTRUE) override
Bool_t HasMenuBar() const override
void Close() override
TGToolTip * fToolTip
tooltip for object info
Definition GRootCanvas.h:86
Bool_t fEmbedded
true if embedded in any other frame (e.g. in the browser)
Definition GRootCanvas.h:89
Bool_t fAutoFit
when true canvas container keeps same size as canvas
Definition GRootCanvas.h:91
UInt_t GetCheight() const
void ReallyDelete() override
TGPopupMenu * fHelpMenu
help menu
Definition GRootCanvas.h:62
TGPopupMenu * fViewWithMenu
view with... cascade submenu
Definition GRootCanvas.h:59
TVirtualPadEditor * fEditor
pointer to currently loaded pad editor
Definition GRootCanvas.h:88
TGCompositeFrame * fMainFrame
main frame containing canvas and side frame
Definition GRootCanvas.h:72
TGPopupMenu * fEditMenu
edit menu
Definition GRootCanvas.h:56
TGLayoutHints * fMenuBarHelpLayout
layout hint for help menu in menubar
Definition GRootCanvas.h:65
void ShowMenuBar(Bool_t show=kTRUE) override
TGToolBar * fToolBar
icon button toolbar
Definition GRootCanvas.h:74
void CloseWindow() override
TGPopupMenu * fViewMenu
view menu
Definition GRootCanvas.h:58
UInt_t GetWindowGeometry(Int_t &x, Int_t &y, UInt_t &w, UInt_t &h) override
TGPopupMenu * fFileMenu
file menu
Definition GRootCanvas.h:54
TGLayoutHints * fMenuBarItemLayout
layout hints for menu in menubar
Definition GRootCanvas.h:64
Bool_t HandleDNDDrop(TDNDData *data) override
Int_t fCanvasID
index in fWindows array of TGX11
Definition GRootCanvas.h:90
void SetStatusText(const char *txt=nullptr, Int_t partidx=0) override
Bool_t HandleDoubleClick(Event_t *ev) override
Bool_t HandleCrossing(Event_t *ev) override
Bool_t HandleButton(Event_t *event) override
Bool_t HandleMotion(Event_t *ev) override
Bool_t HandleKey(Event_t *ev) override
void SetEditable(Bool_t) override
GRootCanvas * fCanvas
GRootContainer(GRootCanvas *c, Window_t id, const TGWindow *p)
Bool_t HandleExpose(Event_t *ev) override
void SavePrimitive(std::ostream &out, Option_t *="") override
Bool_t HandleConfigureNotify(Event_t *ev) override