ROOT  6.06/09
Reference Guide
TASPaletteEditor.cxx
Go to the documentation of this file.
1 // @(#)root/asimage:$Id$
2 // Author: Reiner Rohlfs 24/03/2002
3 
4 /*************************************************************************
5  * Copyright (C) 1995-2002, Rene Brun, Fons Rademakers and Reiner Rohlfs *
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 /** \class TASPaletteEditor
13 \ingroup asimage
14 
15 This is a GUI window to edit a color palette.
16 It is called by a pull down menu item of TASImage.
17 */
18 
19 #include "TASImage.h"
20 #include "TRootEmbeddedCanvas.h"
21 #include "TCanvas.h"
22 #include "TH1.h"
23 #include "TFile.h"
24 #include "TASPaletteEditor.h"
25 #include "TGXYLayout.h"
26 #include "TGButton.h"
27 #include "TGComboBox.h"
28 #include "TGFileDialog.h"
29 #include "TLine.h"
30 #include "TROOT.h"
31 #include "TClass.h"
32 #include "TMath.h"
33 #include "RConfigure.h"
34 
35 #ifdef R__HAS_COCOA
36 # define X_DISPLAY_MISSING 1
37 #endif
38 
39 #ifdef WIN32
40 #include "Windows4root.h"
41 #endif
42 
43 extern "C" {
44 #ifndef WIN32
45 # include <afterbase.h>
46 #else
47 # include <win32/config.h>
48 # include <win32/afterbase.h>
49 #endif
50 # include <afterimage.h>
51 # include <bmp.h>
52 
53 }
54 
55 
56 static const char *gFileTypes[] = {
57  "ROOT palette file", "*.pal.root",
58  "ASCII palette file", "*.pal.txt",
59  0, 0
60 };
61 
62 static UShort_t gRedRainbow[12] = {
63  0x0000, 0x7000, 0x0000, 0x0000, 0x0000,
64  0xffff, 0xffff, 0x7000, 0x8000, 0xffff
65 };
66 static UShort_t gGreenRainbow[12] = {
67  0x0000, 0x0000, 0x0000, 0xffff, 0xffff,
68  0xffff, 0x0000, 0x0000, 0x8000, 0xffff
69 };
70 static UShort_t gBlueRainbow[12] = {
71  0x0000, 0x7000, 0xffff, 0xffff, 0x0000,
72  0x0000, 0x0000, 0x0000, 0xa000, 0xffff
73 };
74 
75 
77 
78 ////////////////////////////////////////////////////////////////////////////////
79 /// Palette editor constructor.
80 /// The palette editor allows the editing of the color palette of the image.
81 
83  : TPaletteEditor(attImage, w, h), TGMainFrame(0, w, h)
84 {
85  SetLayoutManager(new TGXYLayout(this));
86  fHisto = 0;
87  fLimitLine[0] = 0;
88  fLimitLine[1] = 0;
89  fRampFactor = 0;
90  fImagePad = gPad;
91 
92  fPaletteList = new TList;
93  fPaletteList->SetOwner();
94 
95  fPalette = new TImagePalette(attImage->GetPalette());
96  fPaletteList->Add(fPalette);
97 
98  // buttons
99  TGTextButton *button;
100 
101  button = new TGTextButton(this, "&Apply", 1);
102  button->SetToolTipText("Apply the palette to the image");
103  AddFrame(button, new TGXYLayoutHints(70, 1, 8, 1.8));
104 
105  button = new TGTextButton(this, "&Ok", 2);
106  button->SetToolTipText("Same as Apply and Cancel button");
107  AddFrame(button, new TGXYLayoutHints(70, 3, 8, 1.8));
108 
109  button = new TGTextButton(this, "&Cancel", 3);
110  button->SetToolTipText("Close this window");
111  AddFrame(button, new TGXYLayoutHints(70, 5, 8, 1.8));
112 
113  button = new TGTextButton(this, "&Save", 4);
114  button->SetToolTipText("Save the palette in a ROOT or an ASCII file");
115  AddFrame(button, new TGXYLayoutHints(70, 7.5, 8, 1.8));
116 
117  button = new TGTextButton(this, "O&pen", 5);
118  button->SetToolTipText("Read a palette from a ROOT or an ASCII file");
119  AddFrame(button, new TGXYLayoutHints(70, 9.5, 8, 1.8));
120 
121  button = new TGTextButton(this, "&New", 6);
122  button->SetToolTipText("Create a new palette (not yet implemented)");
123  button->SetState(kButtonDisabled);
124  AddFrame(button, new TGXYLayoutHints(70, 12, 8, 1.8));
125 
126  button = new TGTextButton(this, "&Edit", 7);
127  button->SetToolTipText("Edit a palette (not yet implemented)");
128  button->SetState(kButtonDisabled);
129  AddFrame(button, new TGXYLayoutHints(70, 14, 8, 1.8));
130 
131  fAutoUpdate = new TGCheckButton(this, "Auto Update", 13);
132  fAutoUpdate->SetToolTipText("Automatic update of the image (without Apply button)");
133  AddFrame(fAutoUpdate, new TGXYLayoutHints(50, 1, 20, 1.8));
134 
135  fUnDoButton = new TGTextButton(this, "&Undo", 20);
136  fUnDoButton->SetToolTipText("Undo the last modification (repeatable)");
137  AddFrame(fUnDoButton, new TGXYLayoutHints(50, 3, 8, 1.8));
138 
139  fReDoButton = new TGTextButton(this, "&Redo", 21);
140  fReDoButton->SetToolTipText("Undo the last undo operation (repeatable)");
141  AddFrame(fReDoButton, new TGXYLayoutHints(60, 3, 8, 1.8));
142 
143  button = new TGTextButton(this, "&Log", 8);
144  button->SetToolTipText("Apply a log operation to the anchor points of the palette");
145  AddFrame(button, new TGXYLayoutHints(50, 15, 8, 1.8));
146 
147  button = new TGTextButton(this, "E&xp", 9);
148  button->SetToolTipText("Apply a exp operation to the anchor points of the palette");
149  AddFrame(button, new TGXYLayoutHints(50, 17, 8, 1.8));
150 
151  button = new TGTextButton(this, "L&in", 10);
152  button->SetToolTipText("Make the distance of all anchor points constant");
153  AddFrame(button, new TGXYLayoutHints(50, 19, 8, 1.8));
154 
155  button = new TGTextButton(this, "In&vert", 11);
156  button->SetToolTipText("Invert the order of the colors");
157  AddFrame(button, new TGXYLayoutHints(60, 17, 8, 1.8));
158 
159  fStepButton = new TGCheckButton(this, "Step", 12);
160  fStepButton->SetToolTipText("Apply a step function to the palette");
161  AddFrame(fStepButton, new TGXYLayoutHints(60, 19, 8, 1.8));
162 
163  // ramp: 1, 2 or 4
164  TGGroupFrame *rampFrame = new TGGroupFrame(this, "Ramps");
165  rampFrame->SetLayoutManager(new TGXYLayout(rampFrame));
166  AddFrame(rampFrame, new TGXYLayoutHints(50, 8.5, 14, 6,
169 
170  fRamps[0] = new TGRadioButton(rampFrame, "1", 1);
171  fRamps[0]->SetToolTipText("Repeat the palette once");
172  rampFrame->AddFrame(fRamps[0], new TGXYLayoutHints(2, 1.4, 5, 1.8));
173 
174  fRamps[1] = new TGRadioButton(rampFrame, "2", 2);
175  fRamps[1]->SetToolTipText("Repeat the palette twice");
176  rampFrame->AddFrame(fRamps[1], new TGXYLayoutHints(2, 3.3, 5, 1.8));
177 
178  fRamps[2] = new TGRadioButton(rampFrame, "4", 4);
179  fRamps[2]->SetToolTipText("Repeat the palette four times");
180  rampFrame->AddFrame(fRamps[2], new TGXYLayoutHints(8, 3.3, 5, 1.8));
181 
182  fRamps[0]->Associate(this);
183  fRamps[1]->Associate(this);
184  fRamps[2]->Associate(this);
185 
186  // the histogram of the data
187  fHistCanvas = new TRootEmbeddedCanvas("data hist", this, 300, 50);
188  AddFrame(fHistCanvas, new TGXYLayoutHints(1, 1, 48, 20,
190 
191  const ASImage *image = ((TASImage*)attImage)->GetImage();
192  if (image && image->alt.vector) {
193  Int_t pixel;
194  Double_t *data = image->alt.vector;
195  Int_t numPixel = image->width * image->height;
196  Int_t numBins = numPixel / 20;
197  numBins = (numBins < 10) ? 10 : (numBins > 200) ? 200 : numBins;
198 
199  // get min and max value of image
200  fMinValue = fMaxValue = *image->alt.vector;
201  for (pixel = 1; pixel < numPixel; pixel++) {
202  if (fMinValue > *(data + pixel)) fMinValue = *(data + pixel);
203  if (fMaxValue < *(data + pixel)) fMaxValue = *(data + pixel);
204  }
205 
206  fHisto = new TH1D("Statistics", "Pixel histogram of unzoomed image ",
207  numBins, fMinValue, fMaxValue);
208  for (pixel = 0; pixel < numPixel; pixel++)
209  fHisto->Fill(*(data + pixel));
210 
211  fHisto->Draw("HIST");
212  fHisto->GetXaxis()->SetLabelFont(63);
213  fHisto->GetXaxis()->SetLabelSize(10);
214  fHisto->GetYaxis()->SetLabelFont(63);
215  fHisto->GetYaxis()->SetLabelSize(10);
216 
217  fLimitLine[0] = new LimitLine(fMinValue + fPalette->fPoints[1] * (fMaxValue - fMinValue),
218  0, fHisto->GetMaximum(), this);
219  fLimitLine[0]->Draw();
220  fLimitLine[1] = new LimitLine(fMinValue + fPalette->fPoints[fPalette->fNumPoints - 2] *
221  (fMaxValue - fMinValue), 0, fHisto->GetMaximum(), this);
222  fLimitLine[1]->Draw();
223  }
224 
225  // the combobox of different palettes
226  fComboBox = new TGComboBox(this, 100);
227  AddFrame(fComboBox, new TGXYLayoutHints(50, 6, 14, 2));
228 
229  fComboBox->AddEntry("Rainbow", 0);
230  fComboBox->AddEntry("Grey", 1);
231  fComboBox->AddEntry("Hot", 2);
232  fComboBox->AddEntry("Cold", 3);
233  fComboBox->AddEntry("Bowlerhat", 4);
234  fComboBox->AddEntry("", 5);
235 
236 
237  // the palette
238  fPaletteCanvas = new TRootEmbeddedCanvas("palette", this, 300, 50);
239  AddFrame(fPaletteCanvas, new TGXYLayoutHints(1, 22, 78, 2.5,
241 
242  fPaintPalette = new PaintPalette(&fPalette, attImage);
243  fPaintPalette->Draw();
244 
245  MapSubwindows();
246  Layout();
247 
248  SetWindowName("Palette Editor");
249  SetIconName("Palette Editor");
250 
251  MapWindow();
252 
253  UpdateScreen(kFALSE);
254 }
255 
256 ////////////////////////////////////////////////////////////////////////////////
257 /// Palette editor destructor. Deletes all frames and their layout hints.
258 
260 {
261  TGFrameElement *ptr;
262 
263  // delete all frames and layout hints
264  if (fList) {
265  TIter next(fList);
266  while ((ptr = (TGFrameElement *) next())) {
267  if (ptr->fLayout)
268  delete ptr->fLayout;
269  if (ptr->fFrame)
270  delete ptr->fFrame;
271  }
272  }
273 
274  delete fHisto;
275  delete fPaintPalette;
276  delete fLimitLine[0];
277  delete fLimitLine[1];
278  delete fPaletteList;
279 }
280 
281 ////////////////////////////////////////////////////////////////////////////////
282 /// Close editor.
283 
285 {
287  delete this;
288 }
289 
290 ////////////////////////////////////////////////////////////////////////////////
291 /// Process all editor mouse events
292 
294 {
295  switch (GET_MSG(msg)) {
296 
297  case kC_COMMAND:
298  switch (GET_SUBMSG(msg)) {
299 
300  case kCM_COMBOBOX:
301  NewPalette(param2);
302  break;
303 
304  case kCM_RADIOBUTTON:
305  SetRamp(param1);
306  break;
307 
308  case kCM_CHECKBUTTON:
309  if (param1 == 12)
310  SetStep();
311  break;
312 
313  case kCM_BUTTON:
314  switch (param1) {
315 
316  case 1 : // Apply
318  fImagePad->Modified();
319  fImagePad->Update();
320  break;
321 
322  case 2 : // OK
324  fImagePad->Modified();
325  fImagePad->Update();
326  CloseWindow();
327  break;
328 
329  case 3 : // Cancel
330  CloseWindow();
331  break;
332 
333  case 4 : // Save
334  Save();
335  break;
336 
337  case 5 : // Open
338  Open();
339  break;
340 
341  case 8: // log
342  LogPalette();
343  break;
344 
345  case 9: // exp
346  ExpPalette();
347  break;
348 
349  case 10: // lin
350  LinPalette();
351  break;
352 
353  case 11: // invert
354  InvertPalette();
355  break;
356 
357 
358  case 20: // undo
360  if (fAutoUpdate->GetState() == kButtonDown) {
362  fImagePad->Modified();
363  fImagePad->Update();
364  }
366  break;
367 
368  case 21: // redo
370  if (fAutoUpdate->GetState() == kButtonDown) {
372  fImagePad->Modified();
373  fImagePad->Update();
374  }
376  break;
377 
378  default: ;
379  }
380  break;
381 
382  default: ;
383  }
384  break;
385 
386  default: ;
387  }
388 
389  return kTRUE;
390 }
391 
392 ////////////////////////////////////////////////////////////////////////////////
393 /// The newPalette is inserted in the list of palettes (fPaletteList) and
394 /// fPalette is set to the newPalette. Protected method,
395 
397 {
398  // first remove all palettes in the list which are behind the
399  // current palette
400  TObject *obj;
401  while ((obj = fPaletteList->After(fPalette)) != 0)
402  delete fPaletteList->Remove(obj);
403 
404  // add new palette and make it to the current palette
405  fPaletteList->Add(newPalette);
406  fPalette = newPalette;
407 
408  // update the image
409  if (fAutoUpdate->GetState() == kButtonDown) {
411  fImagePad->Modified();
412  fImagePad->Update();
413  }
414 }
415 
416 ////////////////////////////////////////////////////////////////////////////////
417 /// Saves the current palette either into a ROOT file or in an ASCII file.
418 /// It is called by the Save - button. Protected method.
419 
421 {
422  TGFileInfo fi;
423  fi.fFileTypes = gFileTypes;
424  static Bool_t overwr = kFALSE;
425  fi.fOverwrite = overwr;
426 
427  new TGFileDialog(gClient->GetRoot(), this, kFDSave, &fi);
428  overwr = fi.fOverwrite;
429  if (fi.fFilename == 0)
430  return;
431 
432  if (strcmp(".pal.txt", fi.fFilename + strlen(fi.fFilename) - 8) == 0) {
433  // write into an ASCII file
434  FILE *fl = fopen(fi.fFilename, "w");
435  if (!fl) return;
436  fprintf(fl, "%u\n", fPalette->fNumPoints);
437  for (Int_t pt = 0; pt < Int_t(fPalette->fNumPoints); pt++)
438  fprintf(fl, "%10.9f %04hx %04hx %04hx %04hx\n",
439  fPalette->fPoints[pt],
443  fPalette->fColorAlpha[pt] );
444  fclose(fl);
445  } else {
446  // write into a ROOT file
447  char fn[512];
448  if (strcmp(".pal.root", fi.fFilename + strlen(fi.fFilename) - 9) != 0)
449  snprintf(fn,512, "%s%s", fi.fFilename, ".pal.root");
450  else
451  strlcpy(fn, fi.fFilename,512);
452 
453  gROOT->ProcessLine(Form("gROOT->SaveObjectAs((TASPaletteEditor*)0x%lx,\"%s\",\"%s\");",(ULong_t)this,fn,"q"));
454  }
455 }
456 
457 ////////////////////////////////////////////////////////////////////////////////
458 /// Opens either a ROOT file or an ASCII file and reads a palette.
459 /// It is called by the Open - button. Protected method.
460 
462 {
463  TGFileInfo fi;
464  fi.fFileTypes = gFileTypes;
465 
466  new TGFileDialog(gClient->GetRoot(), this, kFDOpen, &fi);
467  if (fi.fFilename == 0)
468  return;
469 
470  TImagePalette *newPalette;
471 
472  if (strcmp(".pal.txt", fi.fFilename + strlen(fi.fFilename) - 8) == 0) {
473  FILE *fl = fopen(fi.fFilename, "r");
474  if (!fl) return;
475  UInt_t numPoints;
476  // coverity [Calling risky function : FALSE]
477  if (fscanf(fl, "%u\n", &numPoints)) {;}
478  newPalette = new TImagePalette(numPoints);
479  for (Int_t pt = 0; pt < Int_t(numPoints); pt++)
480  // coverity [Calling risky function : FALSE]
481  if (fscanf(fl, "%lf %hx %hx %hx %hx\n",
482  newPalette->fPoints + pt,
483  newPalette->fColorRed + pt,
484  newPalette->fColorGreen + pt,
485  newPalette->fColorBlue + pt,
486  newPalette->fColorAlpha + pt )) {;}
487  fclose(fl);
488  } else {
489  // read from a ROOT file
490  char fn[512];
491  if (strcmp(".pal.root", fi.fFilename + strlen(fi.fFilename) - 9) != 0)
492  snprintf(fn,512, "%s%s", fi.fFilename, ".pal.root");
493  else
494  strlcpy(fn, fi.fFilename,512);
495  TDirectory *dirsav = gDirectory;
496 
497  TFile *fsave = new TFile(fn, "READ");
498  if (!fsave->IsOpen()) {
499  delete fsave;
500  return;
501  }
502 
503  newPalette = (TImagePalette*)fsave->Get("TImagePalette");
504  delete fsave;
505  if (dirsav) dirsav->cd();
506  if (!newPalette)
507  return;
508  }
509 
510  InsertNewPalette(newPalette);
512 
513  fComboBox->Select(5); // empty entry
514 }
515 
516 ////////////////////////////////////////////////////////////////////////////////
517 /// All widgets of the screen are updated with the current palette.
518 /// Protected method.
519 
521 {
522  // update the color palette
525 
526  if (histoUpdate) {
527  // update the limit lines
529  fLimitLine[0]->SetX1(xPos);
530  fLimitLine[0]->SetX2(xPos);
531 
533  fLimitLine[1]->SetX1(xPos);
534  fLimitLine[1]->SetX2(xPos);
535 
538  }
539 
540  // update undo / redo button
543 
544  // test if it is a step palette
545  EButtonState step = kButtonDown;
546 
547  Int_t pt;
548  for (pt = 2; pt < Int_t(fPalette->fNumPoints - 2); pt += 2)
549  if (TMath::Abs(fPalette->fPoints[pt] - fPalette->fPoints[pt + 1]) > 0.0001 ||
550  fPalette->fColorRed[pt] != fPalette->fColorRed[pt-1] ||
553  step = kButtonUp;
554  fStepButton->SetState(step);
555 
556  // find the ramp factor
557  fRampFactor = 4;
558  Int_t off = (fPalette->fNumPoints - 2) / 4;
559  for (pt = 0; pt < Int_t(fPalette->fNumPoints - 2) / 4 * 3; pt++)
560  if (fPalette->fColorRed[pt + 1] != fPalette->fColorRed[pt + 1 + off] ||
561  fPalette->fColorGreen[pt + 1] != fPalette->fColorGreen[pt + 1 + off] ||
562  fPalette->fColorBlue[pt + 1] != fPalette->fColorBlue[pt + 1 + off] ||
563  fPalette->fColorAlpha[pt + 1] != fPalette->fColorAlpha[pt + 1 + off]) {
564  fRampFactor = 2;
565  break;
566  }
567 
568  off = (fPalette->fNumPoints - 2) / 2;
569  for (pt = 0; pt < Int_t(fPalette->fNumPoints - 2) / 2; pt++)
570  if (fPalette->fColorRed[pt + 1] != fPalette->fColorRed[pt + 1 + off] ||
571  fPalette->fColorGreen[pt + 1] != fPalette->fColorGreen[pt + 1 + off] ||
572  fPalette->fColorBlue[pt + 1] != fPalette->fColorBlue[pt + 1 + off] ||
573  fPalette->fColorAlpha[pt + 1] != fPalette->fColorAlpha[pt + 1 + off]) {
574  fRampFactor = 1;
575  break;
576  }
577 
579  fRamps[1]->SetState(fRampFactor == 2 ? kButtonDown : kButtonUp);
580  fRamps[2]->SetState(fRampFactor == 4 ? kButtonDown : kButtonUp);
581 }
582 
583 ////////////////////////////////////////////////////////////////////////////////
584 /// The anchor points are rescaled by a log operation.
585 /// It is called by the log - button. Protected method.
586 
588 {
589  TImagePalette *newPalette = new TImagePalette(*fPalette);
590 
592 
593  for (Int_t pt = 2; pt < Int_t(fPalette->fNumPoints - 2); pt++)
594  newPalette->fPoints[pt] = fPalette->fPoints[1] +
596  TMath::Log(delta + 1) * delta;
597 
598  InsertNewPalette(newPalette);
600 }
601 
602 ////////////////////////////////////////////////////////////////////////////////
603 /// The anchor points are rescaled by a exp operation.
604 /// It is called by the exp - button. Protected method.
605 
607 {
608  TImagePalette *newPalette = new TImagePalette(*fPalette);
609 
611 
612  for (Int_t pt = 2; pt < Int_t(fPalette->fNumPoints - 2); pt++)
613  newPalette->fPoints[pt] = fPalette->fPoints[1] +
615  TMath::Log(delta + 1) / delta) - 1;
616 
617  InsertNewPalette(newPalette);
619 }
620 
621 ////////////////////////////////////////////////////////////////////////////////
622 /// The anchor points are rescaled to be linar.
623 /// It is called by the lin - button. Protected method.
624 
626 {
627  TImagePalette *newPalette = new TImagePalette(*fPalette);
628 
630  if (fStepButton->GetState() == kButtonUp) {
631  for (Int_t pt = 2; pt < Int_t(fPalette->fNumPoints - 2); pt++)
632  newPalette->fPoints[pt] = fPalette->fPoints[1] +
633  delta * (pt - 1) / (fPalette->fNumPoints - 3);
634  } else {
635  for (Int_t pt = 0; pt < Int_t(fPalette->fNumPoints - 4); pt += 2) {
636  newPalette->fPoints[pt + 3] = fPalette->fPoints[1] + delta * (pt + 2) /
637  (fPalette->fNumPoints - 2) ;
638  newPalette->fPoints[pt + 2] = newPalette->fPoints[pt + 3];
639  }
640  }
641 
642  InsertNewPalette(newPalette);
644 }
645 
646 ////////////////////////////////////////////////////////////////////////////////
647 /// The palette is inverted.
648 /// It is called by the invert - button. Protected method.
649 
651 {
652  TImagePalette *newPalette = new TImagePalette(*fPalette);
653 
654  Int_t pt;
655  for (pt = 0; pt < Int_t(fPalette->fNumPoints); pt++) {
656  newPalette->fColorRed[pt] = fPalette->fColorRed[fPalette->fNumPoints - 1 - pt];
657  newPalette->fColorGreen[pt] = fPalette->fColorGreen[fPalette->fNumPoints - 1 - pt];
658  newPalette->fColorBlue[pt] = fPalette->fColorBlue[fPalette->fNumPoints - 1 - pt];
659  newPalette->fColorAlpha[pt] = fPalette->fColorAlpha[fPalette->fNumPoints - 1 - pt];
660  }
661 
662  for (pt = 2; pt < Int_t(fPalette->fNumPoints - 2); pt++)
663  newPalette->fPoints[pt] = fPalette->fPoints[1] +
665  fPalette->fPoints[fPalette->fNumPoints - 1 - pt];
666 
667  InsertNewPalette(newPalette);
669 }
670 
671 ////////////////////////////////////////////////////////////////////////////////
672 /// A new palette is created, depending on the id.
673 /// It is called by the combo box. Protected method.
674 
676 {
677  if (id == 5) // empty entry
678  return;
679 
680  TImagePalette *newPalette;
681 
683  UInt_t numPt;
684 
685  numPt = id == 0 ? 12 : 13;
686  newPalette = new TImagePalette(numPt);
687  Int_t pt;
688  for (pt = 1; pt < Int_t(numPt - 1); pt++) {
689  newPalette->fPoints[pt] = fPalette->fPoints[1] + (pt - 1) * delta / (numPt - 3);
690  newPalette->fColorAlpha[pt] = 0xffff;
691  }
692 
693  switch (id) {
694  case 0: // rainbow
695  memcpy(newPalette->fColorRed + 1, gRedRainbow, 12 * sizeof(UShort_t));
696  memcpy(newPalette->fColorGreen + 1, gGreenRainbow, 12 * sizeof(UShort_t));
697  memcpy(newPalette->fColorBlue + 1, gBlueRainbow, 12 * sizeof(UShort_t));
698  break;
699 
700  case 1: // gray
701  for (pt = 1; pt < Int_t(numPt - 1); pt++) {
702  newPalette->fColorRed[pt] = 0xffff * (pt - 1) / (numPt - 3);
703  newPalette->fColorGreen[pt] = 0xffff * (pt - 1) / (numPt - 3);
704  newPalette->fColorBlue[pt] = 0xffff * (pt - 1) / (numPt - 3);
705  }
706  break;
707 
708  case 2: // hot (red)
709  for (pt = 1; pt < Int_t(numPt - 1) / 2; pt++) {
710  newPalette->fColorRed[pt] = 0xffff * (pt - 1) / ((numPt - 3) / 2);
711  newPalette->fColorGreen[pt] = 0;
712  newPalette->fColorBlue[pt] = 0;
713  }
714 
715  for (; pt < Int_t(numPt - 1); pt++) {
716  newPalette->fColorRed[pt] = 0xffff;
717  newPalette->fColorGreen[pt] = 0xffff * (pt - (numPt - 1) / 2) / ((numPt - 3) / 2);
718  newPalette->fColorBlue[pt] = 0xffff * (pt - (numPt - 1) / 2) / ((numPt - 3) / 2);
719  }
720  break;
721 
722  case 3: // cold (blue)
723  for (pt = 1; pt < Int_t(numPt - 1) / 2; pt++) {
724  newPalette->fColorRed[pt] = 0;
725  newPalette->fColorGreen[pt] = 0;
726  newPalette->fColorBlue[pt] = 0xffff * (pt - 1) / ((numPt - 3) / 2);
727  }
728 
729  for (; pt < Int_t(numPt - 1); pt++) {
730  newPalette->fColorRed[pt] = 0xffff * (pt - (numPt - 1) / 2) / ((numPt - 3) / 2);
731  newPalette->fColorGreen[pt] = 0xffff * (pt - (numPt - 1) / 2) / ((numPt - 3) / 2);
732  newPalette->fColorBlue[pt] = 0xffff;
733  }
734  break;
735 
736  case 4: // bolwerhat
737  for (pt = 1; pt < Int_t(numPt + 1) / 2; pt++) {
738  newPalette->fColorRed[pt] = newPalette->fColorRed[numPt - pt - 1]
739  = 0xffff * (pt - 1) / ((numPt - 3) / 2);
740  newPalette->fColorGreen[pt] = newPalette->fColorGreen[numPt - pt - 1]
741  = 0xffff * (pt - 1) / ((numPt - 3) / 2);
742  newPalette->fColorBlue[pt] = newPalette->fColorBlue[numPt - pt - 1]
743  = 0xffff * (pt - 1) / ((numPt - 3) / 2);
744  }
745  break;
746  }
747 
748  newPalette->fPoints[0] = 0;
749  newPalette->fColorRed[0] = newPalette->fColorRed[1];
750  newPalette->fColorGreen[0] = newPalette->fColorGreen[1];
751  newPalette->fColorBlue[0] = newPalette->fColorBlue[1];
752  newPalette->fColorAlpha[0] = newPalette->fColorAlpha[1];
753 
754  newPalette->fPoints[newPalette->fNumPoints-1] = 1.0;
755  newPalette->fColorRed[newPalette->fNumPoints-1] = newPalette->fColorRed[newPalette->fNumPoints-2];
756  newPalette->fColorGreen[newPalette->fNumPoints-1] = newPalette->fColorGreen[newPalette->fNumPoints-2];
757  newPalette->fColorBlue[newPalette->fNumPoints-1] = newPalette->fColorBlue[newPalette->fNumPoints-2];
758  newPalette->fColorAlpha[newPalette->fNumPoints-1] = newPalette->fColorAlpha[newPalette->fNumPoints-2];
759 
760  InsertNewPalette(newPalette);
762 }
763 
764 ////////////////////////////////////////////////////////////////////////////////
765 /// Create a step palette. This is called by the step - check button.
766 /// Protected method.
767 
769 {
770  TImagePalette *newPalette;
771 
772  if (fStepButton->GetState() == kButtonDown) {
773  // change colors in steps
774  newPalette = new TImagePalette(fPalette->fNumPoints * 2 - 2);
775  Double_t fkt = (Double_t)(fPalette->fNumPoints - 3) / (fPalette->fNumPoints - 2);
776  for (Int_t pt = 1; pt < Int_t(fPalette->fNumPoints - 1); pt++) {
777  newPalette->fPoints[pt * 2 - 1] = fPalette->fPoints[1] + (fPalette->fPoints[pt] - fPalette->fPoints[1]) * fkt;
778  newPalette->fPoints[pt * 2] = fPalette->fPoints[1] + (fPalette->fPoints[pt + 1] - fPalette->fPoints[1]) * fkt;
779  newPalette->fColorRed[pt * 2 - 1] = newPalette->fColorRed[pt * 2] = fPalette->fColorRed[pt];
780  newPalette->fColorGreen[pt * 2 - 1] = newPalette->fColorGreen[pt * 2] = fPalette->fColorGreen[pt];
781  newPalette->fColorBlue[pt * 2 - 1] = newPalette->fColorBlue[pt * 2] = fPalette->fColorBlue[pt];
782  newPalette->fColorAlpha[pt * 2 - 1] = newPalette->fColorAlpha[pt * 2] = fPalette->fColorAlpha[pt];
783  }
784  } else {
785  // continuous change of colors
786  newPalette = new TImagePalette(fPalette->fNumPoints / 2 + 1);
789  for (Int_t pt = 1; pt < Int_t(newPalette->fNumPoints - 1); pt++) {
790  newPalette->fPoints[pt] = fPalette->fPoints[pt * 2 -1] * fkt;
791  newPalette->fColorRed[pt] = fPalette->fColorRed[pt * 2 - 1];
792  newPalette->fColorGreen[pt] = fPalette->fColorGreen[pt * 2 - 1];
793  newPalette->fColorBlue[pt] = fPalette->fColorBlue[pt * 2 - 1];
794  newPalette->fColorAlpha[pt] = fPalette->fColorAlpha[pt * 2 - 1];
795  }
796  }
797 
798  newPalette->fPoints[0] = fPalette->fPoints[0];
799  newPalette->fColorRed[0] = fPalette->fColorRed[0];
800  newPalette->fColorGreen[0] = fPalette->fColorGreen[0];
801  newPalette->fColorBlue[0] = fPalette->fColorBlue[0];
802  newPalette->fColorAlpha[0] = fPalette->fColorAlpha[0];
803 
804  newPalette->fPoints[newPalette->fNumPoints-2] = fPalette->fPoints[fPalette->fNumPoints-2];
805  newPalette->fPoints[newPalette->fNumPoints-1] = fPalette->fPoints[fPalette->fNumPoints-1];
806  newPalette->fColorRed[newPalette->fNumPoints-1] = fPalette->fColorRed[fPalette->fNumPoints-1];
807  newPalette->fColorGreen[newPalette->fNumPoints-1] = fPalette->fColorGreen[fPalette->fNumPoints-1];
808  newPalette->fColorBlue[newPalette->fNumPoints-1] = fPalette->fColorBlue[fPalette->fNumPoints-1];
809  newPalette->fColorAlpha[newPalette->fNumPoints-1] = fPalette->fColorAlpha[fPalette->fNumPoints-1];
810 
811  InsertNewPalette(newPalette);
813 }
814 
815 ////////////////////////////////////////////////////////////////////////////////
816 /// The palette is repeated up to 4 times.
817 /// This is called by one of the ramp radio buttons. Protected method.
818 
820 {
821  if (ramp == fRampFactor)
822  return;
823 
824  Int_t ptPerRamp = (fPalette->fNumPoints - 2) / fRampFactor;
825  TImagePalette *newPalette = new TImagePalette(ptPerRamp * ramp + 2);
826 
828  for (Int_t rp = 0; rp < ramp; rp++) {
829  for (Int_t pt = 0; pt < ptPerRamp; pt++) {
830  newPalette->fPoints[1 + pt + rp * ptPerRamp] = fPalette->fPoints[1] +
831  delta / ramp * rp +
832  (fPalette->fPoints[1+pt] - fPalette->fPoints[1]) * fRampFactor / ramp;
833  newPalette->fColorRed [1 + pt + rp * ptPerRamp] = fPalette->fColorRed [1 + pt];
834  newPalette->fColorGreen[1 + pt + rp * ptPerRamp] = fPalette->fColorGreen[1 + pt];
835  newPalette->fColorBlue [1 + pt + rp * ptPerRamp] = fPalette->fColorBlue [1 + pt];
836  newPalette->fColorAlpha[1 + pt + rp * ptPerRamp] = fPalette->fColorAlpha[1 + pt];
837  }
838  }
839 
840  newPalette->fPoints[0] = fPalette->fPoints[0];
841  newPalette->fColorRed[0] = fPalette->fColorRed[0];
842  newPalette->fColorGreen[0] = fPalette->fColorGreen[0];
843  newPalette->fColorBlue[0] = fPalette->fColorBlue[0];
844  newPalette->fColorAlpha[0] = fPalette->fColorAlpha[0];
845 
846  newPalette->fPoints[newPalette->fNumPoints-2] = fPalette->fPoints[fPalette->fNumPoints-2];
847  newPalette->fPoints[newPalette->fNumPoints-1] = fPalette->fPoints[fPalette->fNumPoints-1];
848  newPalette->fColorRed[newPalette->fNumPoints-1] = fPalette->fColorRed[fPalette->fNumPoints-1];
849  newPalette->fColorGreen[newPalette->fNumPoints-1] = fPalette->fColorGreen[fPalette->fNumPoints-1];
850  newPalette->fColorBlue[newPalette->fNumPoints-1] = fPalette->fColorBlue[fPalette->fNumPoints-1];
851  newPalette->fColorAlpha[newPalette->fNumPoints-1] = fPalette->fColorAlpha[fPalette->fNumPoints-1];
852 
853  InsertNewPalette(newPalette);
855 }
856 
857 ////////////////////////////////////////////////////////////////////////////////
858 /// Updates the range of the palette.
859 /// This is called after the blue limit lines were moved to define
860 /// a new range.
861 
863 {
864  if (fMaxValue == fMinValue)
865  return;
866 
867  TImagePalette *newPalette = new TImagePalette(*fPalette);
868 
869  Double_t l0 = fLimitLine[0]->GetX1();
870  Double_t l1 = fLimitLine[1]->GetX1();
871  l0 = (l0 < fMinValue) ? fMinValue : ((l0 > fMaxValue) ? fMaxValue : l0);
872  l1 = (l1 < fMinValue) ? fMinValue : ((l1 > fMaxValue) ? fMaxValue : l1);
873  if (l0 > l1) {
874  Double_t tmp = l0;
875  l0 = l1;
876  l1 = tmp;
877  }
878 
879  Double_t oldDelta = fPalette->fPoints[fPalette->fNumPoints - 2] - fPalette->fPoints[1];
880  Double_t newDelta = (l1 - l0) / (fMaxValue - fMinValue);
881  Double_t newOff = (l0 - fMinValue) / (fMaxValue - fMinValue);
882 
883  if (newDelta < 0.001 || oldDelta < 0.001)
884  return;
885 
886  for (Int_t pt = 1; pt < Int_t(fPalette->fNumPoints - 1); pt++)
887  newPalette->fPoints[pt] = newOff +
888  (fPalette->fPoints[pt] - fPalette->fPoints[1]) * newDelta / oldDelta;
889 
890  InsertNewPalette(newPalette);
892 }
893 
894 ////////////////////////////////////////////////////////////////////////////////
895 /// Actually paint the paletter.
896 
898 {
899  // get geometry of pad
900  Int_t to_w = TMath::Abs(gPad->XtoPixel(gPad->GetX2()) -
901  gPad->XtoPixel(gPad->GetX1()));
902  Int_t to_h = TMath::Abs(gPad->YtoPixel(gPad->GetY2()) -
903  gPad->YtoPixel(gPad->GetY1()));
904 
905  ASGradient grad;
906 
907  grad.npoints = (*fPalette)->fNumPoints - 2;
908  grad.type = GRADIENT_Left2Right;
909  grad.color = new ARGB32[grad.npoints];
910  grad.offset = new double[grad.npoints];
911  for (Int_t pt = 0; pt < grad.npoints; pt++) {
912  grad.offset[pt] = ((*fPalette)->fPoints[pt + 1] - (*fPalette)->fPoints[1]) /
913  ((*fPalette)->fPoints[(*fPalette)->fNumPoints - 2] - (*fPalette)->fPoints[1]);
914  grad.color[pt] = (((ARGB32)((*fPalette)->fColorBlue[pt + 1] & 0xff00)) >> 8) |
915  (((ARGB32)((*fPalette)->fColorGreen[pt + 1] & 0xff00)) ) |
916  (((ARGB32)((*fPalette)->fColorRed[pt + 1] & 0xff00)) << 8) |
917  (((ARGB32)((*fPalette)->fColorAlpha[pt + 1] & 0xff00)) << 16);
918  }
919 
920  ASImage * grad_im = make_gradient((ASVisual*)TASImage::GetVisual(), &grad , to_w, to_h,
921  SCL_DO_COLOR, ASA_ARGB32, 0,
923  delete [] grad.color;
924  delete [] grad.offset;
925 
926  Window_t wid = (Window_t)gVirtualX->GetWindowID(gPad->GetPixmapID());
927  TASImage::Image2Drawable(grad_im, wid, 0, 0);
928  destroy_asimage(&grad_im);
929 }
930 
931 ////////////////////////////////////////////////////////////////////////////////
932 /// The blue limit line in the pixel value histogram.
933 
935  TASPaletteEditor *gui)
936  : TLine(x, y1, x, y2)
937 {
938  fGui = gui;
939  SetLineColor(4);
940  SetLineWidth(2);
941 }
942 
943 ////////////////////////////////////////////////////////////////////////////////
944 /// Paint the limit lines.
945 
947 {
948  fY1 = gPad->GetUymin();
949  fY2 = gPad->GetUymax();
950 
951  TLine::Paint(option);
952 }
953 
954 ////////////////////////////////////////////////////////////////////////////////
955 
957  Int_t px, Int_t /*py*/)
958 {
959  static Int_t oldX;
960 
961  if (!gPad) return;
962 
963  switch(event) {
964  case kMouseMotion:
965  gPad->SetCursor(kMove);
966  break;
967 
968  case kButton1Down:
969  gVirtualX->SetLineColor(-1);
970  TAttLine::Modify(); //Change line attributes only if necessary
971  oldX = gPad->XtoAbsPixel(fX1);
972  break;
973 
974  case kButton1Motion:
975  gVirtualX->DrawLine(oldX, gPad->YtoPixel(fY1), oldX, gPad->YtoPixel(fY2));
976  oldX = px;
977  gVirtualX->DrawLine(oldX, gPad->YtoPixel(fY1), oldX, gPad->YtoPixel(fY2));
978  gVirtualX->Update();
979  break;
980 
981  case kButton1Up:
982  gVirtualX->SetLineColor(-1);
983  TAttLine::Modify(); //Change line attributes only if necessary
984  fX1 = fX2 = gPad->AbsPixeltoX(oldX);
985  fGui->UpdateRange();
986  gPad->Modified(kTRUE);
987  gPad->Update();
988  break;
989 
990  default:
991  break;
992  }
993 }
virtual void SetLineWidth(Width_t lwidth)
Definition: TAttLine.h:57
Double_t * fPoints
Definition: TAttImage.h:87
This is a GUI window to edit a color palette.
Double_t Log(Double_t x)
Definition: TMath.h:526
ClassImp(TSeqCollection) Int_t TSeqCollection TIter next(this)
Return index of object in collection.
Bool_t fOverwrite
Definition: TGFileDialog.h:67
Double_t GetX1() const
Definition: TLine.h:67
const char Option_t
Definition: RtypesCore.h:62
Image class.
Definition: TASImage.h:33
static const ASVisual * GetVisual()
Return visual.
Definition: TASImage.cxx:5140
void CloseWindow()
Close editor.
virtual void Update()=0
unsigned short UShort_t
Definition: RtypesCore.h:36
#define gDirectory
Definition: TDirectory.h:218
virtual void SetOwner(Bool_t enable=kTRUE)
Set whether this collection is the owner (enable==true) of its content.
TH1 * h
Definition: legend2.C:5
void InsertNewPalette(TImagePalette *newPalette)
The newPalette is inserted in the list of palettes (fPaletteList) and fPalette is set to the newPalet...
A ROOT file is a suite of consecutive data records (TKey instances) with a well defined format...
Definition: TFile.h:45
TImagePalette * fPalette
virtual TObject * Get(const char *namecycle)
Return pointer to object identified by namecycle.
#define gROOT
Definition: TROOT.h:340
#define gClient
Definition: TGClient.h:174
virtual void SetLayoutManager(TGLayoutManager *l)
Set the layout manager for the composite frame.
Definition: TGFrame.cxx:982
int Int_t
Definition: RtypesCore.h:41
bool Bool_t
Definition: RtypesCore.h:59
PaintPalette * fPaintPalette
const Bool_t kFALSE
Definition: Rtypes.h:92
void Paint(Option_t *option)
Actually paint the paletter.
void InvertPalette()
The palette is inverted.
TGComboBox * fComboBox
virtual void Modify()
Change current line attributes if necessary.
Definition: TAttLine.cxx:229
void UpdateScreen(Bool_t histoUpdate)
All widgets of the screen are updated with the current palette.
EButtonState
Definition: TGButton.h:56
Short_t Abs(Short_t d)
Definition: TMathBase.h:110
TCanvas * GetCanvas() const
THist< 1, double > TH1D
Definition: THist.h:314
UShort_t * fColorRed
Definition: TAttImage.h:88
virtual void SetState(EButtonState state, Bool_t emit=kFALSE)
Set radio button state.
Definition: TGButton.cxx:1563
TGLayoutHints * fLayout
Definition: TGLayout.h:127
EImageQuality GetImageQuality() const
Definition: TAttImage.h:136
virtual ~TASPaletteEditor()
Palette editor destructor. Deletes all frames and their layout hints.
TGRadioButton * fRamps[3]
virtual Bool_t IsOpen() const
Returns kTRUE in case file is open and kFALSE if file is not open.
Definition: TFile.cxx:1373
Double_t x[n]
Definition: legend1.C:17
virtual TObject * After(const TObject *obj) const
Returns the object after object obj.
Definition: TList.cxx:288
const char ** fFileTypes
Definition: TGFileDialog.h:65
virtual void Select(Int_t id, Bool_t emit=kTRUE)
Make the selected item visible in the combo box window and emit signals according to the second param...
Definition: TGComboBox.cxx:443
virtual void Paint(Option_t *option="")
Paint this line with its current attributes.
Definition: TLine.cxx:371
Edit the palette via a GUI.
Definition: TAttImage.h:67
void Paint(Option_t *option)
Paint the limit lines.
Bool_t ProcessMessage(Long_t msg, Long_t param1, Long_t param2)
Process all editor mouse events.
A doubly linked list.
Definition: TList.h:47
void SetRamp(Long_t ramp)
The palette is repeated up to 4 times.
LimitLine * fLimitLine[2]
virtual void SetLineColor(Color_t lcolor)
Definition: TAttLine.h:54
virtual void SetX2(Double_t x2)
Definition: TLine.h:83
static UShort_t gBlueRainbow[12]
TList * fList
Definition: TGFrame.h:367
TPaveText * pt
virtual TObject * Before(const TObject *obj) const
Returns the object before object obj.
Definition: TList.cxx:321
virtual EButtonState GetState() const
Definition: TGButton.h:116
TGCheckButton * fStepButton
Int_t GET_SUBMSG(Long_t val)
void LogPalette()
The anchor points are rescaled by a log operation.
double Coord_t
Definition: RtypesCore.h:81
virtual TObject * Remove(TObject *obj)
Remove object from the list.
Definition: TList.cxx:674
UShort_t * fColorAlpha
Definition: TAttImage.h:91
unsigned int UInt_t
Definition: RtypesCore.h:42
char * Form(const char *fmt,...)
A simple line.
Definition: TLine.h:41
virtual void SetPalette(const TImagePalette *palette)
Set a new palette for the image.
Definition: TAttImage.cxx:650
TGFrame * fFrame
Definition: TGLayout.h:125
virtual void ExecuteEvent(Int_t event, Int_t px, Int_t py)
Execute action corresponding to one event.
void SetStep()
Create a step palette.
UInt_t fNumPoints
Definition: TAttImage.h:86
void NewPalette(Long_t id)
A new palette is created, depending on the id.
UShort_t * fColorBlue
Definition: TAttImage.h:90
#define gVirtualX
Definition: TVirtualX.h:362
TGTextButton * fUnDoButton
Int_t GET_MSG(Long_t val)
virtual void SetX1(Double_t x1)
Definition: TLine.h:82
virtual TObject * Last() const
Return the last object in the list. Returns 0 when list is empty.
Definition: TList.cxx:580
long Long_t
Definition: RtypesCore.h:50
virtual void Modified(Bool_t flag=1)=0
Double_t Exp(Double_t x)
Definition: TMath.h:495
LimitLine(Coord_t x, Coord_t y1, Coord_t y2, TASPaletteEditor *gui)
The blue limit line in the pixel value histogram.
double Double_t
Definition: RtypesCore.h:55
TGTextButton * fReDoButton
Describe directory structure in memory.
Definition: TDirectory.h:41
unsigned long ULong_t
Definition: RtypesCore.h:51
TRootEmbeddedCanvas * fPaletteCanvas
char * fFilename
Definition: TGFileDialog.h:63
virtual void AddFrame(TGFrame *f, TGLayoutHints *l=0)
Add frame to the composite frame using the specified layout hints.
Definition: TGFrame.cxx:1099
A class to define a conversion from pixel values to pixel color.
Definition: TAttImage.h:83
void UpdateRange()
Updates the range of the palette.
Mother of all ROOT objects.
Definition: TObject.h:58
TGCheckButton * fAutoUpdate
virtual TObject * First() const
Return the first object in the list. Returns 0 when list is empty.
Definition: TList.cxx:556
Handle_t Window_t
Definition: GuiTypes.h:30
UShort_t * fColorGreen
Definition: TAttImage.h:89
void ExpPalette()
The anchor points are rescaled by a exp operation.
RooCmdArg Layout(Double_t xmin, Double_t xmax=0.99, Double_t ymin=0.95)
static const char * gFileTypes[]
TVirtualPad * fImagePad
virtual Bool_t cd(const char *path=0)
Change current directory to "this" directory.
Definition: TDirectory.cxx:433
static UShort_t gGreenRainbow[12]
virtual void Add(TObject *obj)
Definition: TList.h:81
ClassImp(TASPaletteEditor) TASPaletteEditor
Palette editor constructor.
TImage attributes.
Definition: TAttImage.h:108
#define gPad
Definition: TVirtualPad.h:288
TAttImage * fAttImage
Definition: TAttImage.h:70
virtual void SetState(EButtonState state, Bool_t emit=kFALSE)
Set check button state.
Definition: TGButton.cxx:1200
TRootEmbeddedCanvas * fHistCanvas
virtual void Update()
Update canvas pad buffers.
Definition: TCanvas.cxx:2179
static UShort_t gRedRainbow[12]
virtual void CloseWindow()
Closes the window and deletes itself.
Definition: TAttImage.cxx:262
const Bool_t kTRUE
Definition: Rtypes.h:91
void Open()
Opens either a ROOT file or an ASCII file and reads a palette.
TObject * obj
void LinPalette()
The anchor points are rescaled to be linar.
virtual void SetToolTipText(const char *text, Long_t delayms=400)
Set tool tip text associated with this button.
Definition: TGButton.cxx:395
void Save()
Saves the current palette either into a ROOT file or in an ASCII file.
void Modified(Bool_t flag=1)
Definition: TPad.h:407
static void Image2Drawable(ASImage *im, Drawable_t wid, Int_t x, Int_t y, Int_t xsrc=0, Int_t ysrc=0, UInt_t wsrc=0, UInt_t hsrc=0, Option_t *opt="")
Draw asimage on drawable.
Definition: TASImage.cxx:1221
const char Int_t const char * image
Definition: TXSlave.cxx:46
virtual void SetState(EButtonState state, Bool_t emit=kFALSE)
Set button state.
Definition: TGButton.cxx:185