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