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