KaliVeda
Toolkit for HIC analysis
KVIDGridEditorCanvas.cpp
1 //Created by KVClassFactory on Fri Feb 17 17:47:35 2012
2 //Author: dgruyer
3 
4 #include "KVIDGridEditorCanvas.h"
5 #include "KVIDGridEditor.h"
6 #include "TROOT.h"
7 #include "TBox.h"
8 #include "TAxis.h"
9 #include "TContextMenu.h"
10 #include "TRootCanvas.h"
11 #include "TGWindow.h"
12 #include <KeySymbols.h>
13 #include "TVirtualX.h"
14 #include "TFrame.h"
15 
17 
18 
19 
20 
24 KVIDGridEditorCanvas::KVIDGridEditorCanvas(const char* name, const char* title, Int_t ww, Int_t wh): KVCanvas(name, title, ww, wh)
25 {
26  // gIDGridEditorCanvas = this;
27  // fKeyHandler = new KeyHandler(this);
28 }
29 
30 
31 
32 
35 
37 {
38  // Default constructor
39 }
40 
41 
42 
45 
47 {
48  // Destructor
49 }
50 
51 
52 
57 
59 {
60  // Handle Input Events.
61  //
62  // Handle input events, like button up/down in current canvas.
63 
64  TPad* pad;
65  TPad* prevSelPad = (TPad*) fSelectedPad;
66  TObject* prevSelObj = fSelected;
67 
68  fPadSave = (TPad*)gPad;
69  cd(); // make sure this canvas is the current canvas
70 
71  fEvent = event;
72  fEventX = px;
73  fEventY = py;
74 
75  switch (event) {
76 
77  case kMouseMotion:
78  // highlight object tracked over
79  pad = Pick(px, py, prevSelObj);
80  if (!pad) return;
81 
82  EnterLeave(prevSelPad, prevSelObj);
83 
84  gPad = pad; // don't use cd() we will use the current
85  // canvas via the GetCanvas member and not via
86  // gPad->GetCanvas
87 
88  fSelected->ExecuteEvent(event, px, py);
89 
90  RunAutoExec();
91 
92  break;
93 
94  case kMouseEnter:
95  // mouse enters canvas
97  break;
98 
99  case kMouseLeave:
100  // mouse leaves canvas
101  {
102  // force popdown of tooltips
103  TObject* sobj = fSelected;
104  TPad* spad = fSelectedPad;
105  fSelected = 0;
106  fSelectedPad = 0;
107  EnterLeave(prevSelPad, prevSelObj);
108  fSelected = sobj;
109  fSelectedPad = spad;
111  }
112  break;
113 
114  case kButton1Double:
115  // triggered on the second button down within 350ms and within
116  // 3x3 pixels of the first button down, button up finishes action
117 
118  case kButton1Down:
119  {// find pad in which input occured
120  pad = Pick(px, py, prevSelObj);
121  if (!pad) return;
122 
123  gPad = pad; // don't use cd() because we won't draw in pad
124  // we will only use its coordinate system
125 
126  auto outside_frame = !pad->GetFrame()->IsInside(AbsPixeltoX(px),AbsPixeltoY(py));
127  if (fSelected) {
128  FeedbackMode(kTRUE); // to draw in rubberband mode
129  if (!fSelected->InheritsFrom("TPaveLabel")
130  && !(fSelected->InheritsFrom("KVIDentifier") && outside_frame))
131  fSelected->ExecuteEvent(event, px, py);
132 
133  RunAutoExec();
134 
135  if (fSelected && fSelected->InheritsFrom("TH2")) {
136  oldx = GetEventX();
137  oldy = GetEventY();
138  xmin = AbsPixeltoX(oldx);
139  ymin = AbsPixeltoY(oldy);
141  }
142 
143  }
144  }
145  break;
146 
147  case kButton1Motion:
148  if (fSelected) {
149  if (fSelected->InheritsFrom("TH2")) {
151  oldx = GetEventX();
152  oldy = GetEventY();
154  moved = true;
155  }
156  }
157  case kButton1ShiftMotion: //8 == kButton1Motion + shift modifier
158  if (fSelected) {
159  gPad = fSelectedPad;
160 
161  if (!fSelected->InheritsFrom("TPaveLabel")) fSelected->ExecuteEvent(event, px, py);
162  gVirtualX->Update();
163 
164  if (!fSelected->InheritsFrom(TAxis::Class()) && (!fSelected->InheritsFrom("TPaveLabel"))) {
165  Bool_t resize = kFALSE;
167  resize = ((TBox*)fSelected)->IsBeingResized();
169  resize = ((TVirtualPad*)fSelected)->IsBeingResized();
170 
171  if ((!resize && TestBit(kMoveOpaque)) || (resize && TestBit(kResizeOpaque))) {
172  gPad = fPadSave;
173  Update();
175  }
176  }
177 
178  RunAutoExec();
179  }
180 
181  break;
182 
183  case kButton1Up:
184 
185  if (fSelected) {
186  gPad = fSelectedPad;
187 
188  if (!fSelected->InheritsFrom("TPaveLabel")) fSelected->ExecuteEvent(event, px, py);
189 
190  if (fPadSave)
191  gPad = fPadSave;
192  else {
193  gPad = this;
194  fPadSave = this;
195  }
196  if (fSelected->InheritsFrom("TH2") && moved) {
199  Double_t toto = 0;
200  if (xmax < xmin) {
201  toto = xmax;
202  xmax = xmin;
203  xmin = toto;
204  }
205  if (ymax < ymin) {
206  toto = ymax;
207  ymax = ymin;
208  ymin = toto;
209  }
211  moved = false;
212  }
213 
214  RunAutoExec();
215 
216  Update(); // before calling update make sure gPad is reset
217  }
218  break;
219 
220  //*-*----------------------------------------------------------------------
221 
222  case kButton2Down:
223  // find pad in which input occured
224  pad = Pick(px, py, prevSelObj);
225  if (!pad) return;
226 
227  gPad = pad; // don't use cd() because we won't draw in pad
228  // we will only use its coordinate system
229 
231 
232  if (!fSelected->InheritsFrom("TH1")) {
233  fSelected->Pop(); // pop object to foreground
234  pad->cd(); // and make its pad the current pad
235  }
236  if (fSelected->InheritsFrom("TH2")) {
237  // implement pan & scan
238  X0 = px;
239  Y0 = py; // u clikd here
240  theXaxis = ((TH2*)fSelected)->GetXaxis();
241  theYaxis = ((TH2*)fSelected)->GetYaxis();
242  NXbins = theXaxis->GetNbins(); // maximum bin number in X
243  NYbins = theYaxis->GetNbins(); // maximum bin number in Y
244  Xf1 = Xfirst0 = theXaxis->GetFirst(); // initial displayed bin range in X
245  Xl1 = Xlast0 = theXaxis->GetLast();
246  Yf1 = Yfirst0 = theYaxis->GetFirst(); // initial displayed bin range in Y
247  Yl1 = Ylast0 = theYaxis->GetLast();
248  // size of axes in pixels
249  Int_t pixelWidthX = gPad->XtoAbsPixel(gPad->GetUxmax()) - gPad->XtoAbsPixel(gPad->GetUxmin());
250  Int_t pixelWidthY = gPad->YtoAbsPixel(gPad->GetUymax()) - gPad->YtoAbsPixel(gPad->GetUymin());
251  // sizes of bins in pixels
252  NdisXbins = Xlast0 - Xfirst0 + 1;
253  NdisYbins = Ylast0 - Yfirst0 + 1;
254  XbinPixel = pixelWidthX / (1.0 * NdisXbins);
255  YbinPixel = pixelWidthY / (1.0 * NdisYbins);
256  }
257 
258  if (gDebug)
259  printf("Current Pad: %s / %s\n", pad->GetName(), pad->GetTitle());
260 
261  // loop over all canvases to make sure that only one pad is highlighted
262  {
263  TIter next(gROOT->GetListOfCanvases());
264  TCanvas* tc;
265  while ((tc = (TCanvas*)next()))
266  tc->Update();
267  }
268 
269  /*if (pad->GetGLDevice() != -1 && fSelected)
270  fSelected->ExecuteEvent(event, px, py);*/
271 
272  break; // don't want fPadSave->cd() to be executed at the end
273 
274  case kButton2Motion:
275  if (fSelected && fSelected->InheritsFrom("TH2")) {
276  // implement pan & scan
277  Int_t dX = px - X0; // how far have i moved ?
278  Int_t dY = py - Y0;
279  Int_t dXbins = dX / XbinPixel;
280  Int_t dYbins = dY / YbinPixel;
281  Bool_t changed = kFALSE;
282  Int_t newXfirst = Xfirst0 - dXbins;
283  Int_t newXlast;
284  if (newXfirst < 1) {
285  newXfirst = 1;
286  newXlast = NdisXbins;
287  }
288  else {
289  newXlast = Xlast0 - dXbins;
290  if (newXlast > NXbins) {
291  newXlast = NXbins;
292  newXfirst = newXlast - NdisXbins + 1;
293  }
294  }
295  if (newXfirst != Xf1) {
296  Xf1 = newXfirst;
297  Xl1 = newXlast;
299  changed = kTRUE;
300  }
301  Int_t newYfirst = Yfirst0 - dYbins;
302  Int_t newYlast;
303  if (newYfirst < 1) {
304  newYfirst = 1;
305  newYlast = NdisYbins;
306  }
307  else {
308  newYlast = Ylast0 - dYbins;
309  if (newYlast > NYbins) {
310  newYlast = NYbins;
311  newYfirst = newYlast - NdisYbins + 1;
312  }
313  }
314  if (newYfirst != Yf1) {
315  Yf1 = newYfirst;
316  Yl1 = newYlast;
318  changed = kTRUE;
319  }
320  if (changed) {
321  Modified();
322  Update();
323  }
324  }
325  break;
326 
327  case kButton2Up:
328  if (fSelected) {
329  gPad = fSelectedPad;
330 
331  if (!fSelected->InheritsFrom("TPaveLabel")) fSelected->ExecuteEvent(event, px, py);
332  RunAutoExec();
333  }
334  break;
335 
336  case kButton2Double:
337  break;
338 
339  //*-*----------------------------------------------------------------------
340 
341  case kButton3Down:
342  // popup context menu
343  pad = Pick(px, py, prevSelObj);
344  if (!pad) return;
345 
347 
349  !pad->TestBit(kNoContextMenu) && !TestBit(kNoContextMenu) && (!fSelected->InheritsFrom("TPaveLabel")))
350  fContextMenu->Popup(px, py, fSelected, this, pad);
351 
352  break;
353 
354  case kButton3Motion:
355  break;
356 
357  case kButton3Up:
359  break;
360 
361  case kButton3Double:
362  break;
363 
364  case kESC:
365  RunAutoExec();
366  break;
367 
368  case kKeyPress:
369  if (!fSelectedPad || !fSelected) return;
370  gPad = fSelectedPad; // don't use cd() because we won't draw in pad
371  // we will only use its coordinate system
372  if (!fSelected->InheritsFrom("TPaveLabel")) fSelected->ExecuteEvent(event, px, py);
373 
374  HandleKey(px, py);
375  RunAutoExec();
376 
377 
378  break;
379  case kButton1Shift:
380  // Try to select
381  pad = Pick(px, py, prevSelObj);
382 
383  if (!pad) return;
384 
385  EnterLeave(prevSelPad, prevSelObj);
386 
387  gPad = pad; // don't use cd() we will use the current
388  // canvas via the GetCanvas member and not via
389  // gPad->GetCanvas
390  if (!fSelected->InheritsFrom("TPaveLabel")) fSelected->ExecuteEvent(event, px, py);
391  RunAutoExec();
392 
393  break;
394  case kWheelUp:
395  case kWheelDown:
396  pad = Pick(px, py, prevSelObj);
397  if (!pad) return;
398 
399  gPad = pad;
400  // if(!fSelected->InheritsFrom("TAxis")) fSelected->ExecuteEvent(event, px, py);
401 
402  RunAutoExec();
403 
404  break;
405  default:
406  break;
407  }
408 
409  if (fPadSave && event != kButton2Down)
410  fPadSave->cd();
411 
412  if (event != kMouseLeave) { // signal was already emitted for this event
413  ProcessedEvent(event, px, py, fSelected); // emit signal
414  DrawEventStatus(event, px, py, fSelected);
415  }
416 }
417 
418 
419 
421 
423 {
424  if (gIDGridEditor) gIDGridEditor->HandleKey(px, py);
425  return kTRUE;
426 }
427 
428 
429 
433 
435 {
436  // Execute the list of TExecs in the current pad.
437 // if (!TestBit(kAutoExec)) return;
438  if (!gPad) return;
439  // ((TPad*)gPad)->AutoExec();
440  if (gIDGridEditor) {
441  gIDGridEditor->MakeTransformation();
442  gIDGridEditor->SelectLabel();
443  }
444 
445 }
446 
447 
448 
449 
EEventType
kButton1ShiftMotion
kMouseMotion
kWheelUp
kButton3Up
kButton2Motion
kButton3Motion
kButton3Down
kButton2Down
kKeyPress
kButton2Double
kButton1Double
kButton3Double
kButton1Shift
kButton1Motion
kButton1Up
kWheelDown
kButton2Up
kMouseLeave
kButton1Down
kESC
kMouseEnter
int Int_t
bool Bool_t
constexpr Bool_t kFALSE
double Double_t
constexpr Bool_t kTRUE
Int_t gDebug
#define gROOT
#define gPad
#define gVirtualX
TCanvas with mouse-controlled dynamic zoom and pan & scan.
Definition: KVCanvas.h:54
Double_t ymin
Definition: KVCanvas.h:58
Double_t ymax
Definition: KVCanvas.h:58
Double_t oldx
Definition: KVCanvas.h:59
void DrawEventStatus(Int_t event, Int_t px, Int_t py, TObject *selected)
Definition: KVCanvas.cpp:185
Double_t xmax
Definition: KVCanvas.h:58
Double_t xmin
Definition: KVCanvas.h:58
void ZoomSelected(TH2 *TheHisto)
Definition: KVCanvas.cpp:659
Double_t oldy
Definition: KVCanvas.h:59
Bool_t moved
Definition: KVCanvas.h:69
Extended version of KVCanvas used by KVIDGridEditor.
Double_t YbinPixel
size of bins in pixels
Int_t NdisYbins
number of displayed bins on X & Y
virtual ~KVIDGridEditorCanvas()
Destructor.
Int_t Ylast0
number of bins on y-axis, initial displayed bins
Int_t X0
friend class KeyHandler;
Int_t Xlast0
number of bins on x-axis, initial displayed bins
KVIDGridEditorCanvas()
Default constructor.
Int_t Yl1
last modification to axis limits
Bool_t HandleKey(Int_t px, Int_t py) override
KeyHandler *fKeyHandler; // handler for arrow keys.
TAxis * theYaxis
the axes of the histogram
Int_t Y0
coordinates of initial click in pad pixels
void HandleInput(EEventType event, Int_t px, Int_t py) override
Bool_t HandleKey(Int_t px, Int_t py)
Handle keys.
static TClass * Class()
Int_t GetLast() const
Int_t GetNbins() const
virtual void SetRange(Int_t first=0, Int_t last=0)
Int_t GetFirst() const
static TClass * Class()
virtual Int_t IsInside(Double_t x, Double_t y) const
void EnterLeave(TPad *prevSelPad, TObject *prevSelObj)
TPad * fPadSave
Int_t GetEventY() const override
Int_t fEventX
virtual TPad * Pick(Int_t px, Int_t py, TObject *prevSelObj)
virtual void ProcessedEvent(Int_t event, Int_t x, Int_t y, TObject *selected)
Int_t GetEventX() const override
Int_t fEventY
TVirtualPad * cd(Int_t subpadnumber=0) override
TPad * fSelectedPad
TObject * fSelected
TContextMenu * fContextMenu
void FeedbackMode(Bool_t set)
void Update() override
Int_t fDoubleBuffer
Int_t fEvent
virtual void Popup(Int_t x, Int_t y, TObject *obj, TBrowser *b)
R__ALWAYS_INLINE Bool_t TestBit(UInt_t f) const
virtual void ExecuteEvent(Int_t event, Int_t px, Int_t py)
virtual Bool_t InheritsFrom(const char *classname) const
virtual void Pop()
Double_t AbsPixeltoY(Int_t py) override
const char * GetTitle() const override
Double_t AbsPixeltoX(Int_t px) override
void Modified(Bool_t flag=1) override
Int_t YtoAbsPixel(Double_t y) const override
TVirtualPad * cd(Int_t subpadnumber=0) override
TFrame * GetFrame() override
const char * GetName() const override
Int_t XtoAbsPixel(Double_t x) const override
static TClass * Class()
ClassImp(TPyArg)