Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
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
15This is a GUI window to edit a color palette.
16It 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 "TMath.h"
32#include "RConfigure.h"
33#include "TVirtualX.h"
34#include "strlcpy.h"
35#include "snprintf.h"
36
37#ifdef R__HAS_COCOA
38# define X_DISPLAY_MISSING 1
39#endif
40
41#ifdef WIN32
42#include "Windows4root.h"
43#endif
44
45#ifndef WIN32
46# include <afterbase.h>
47#else
48# include <win32/config.h>
49# include <win32/afterbase.h>
50#endif
51# include <afterimage.h>
52extern "C" {
53# include <bmp.h>
54}
55
56
57static const char *gFileTypes[] = {
58 "ROOT palette file", "*.pal.root",
59 "ASCII palette file", "*.pal.txt",
60 nullptr, nullptr
61};
62
63static UShort_t gRedRainbow[12] = {
64 0x0000, 0x7000, 0x0000, 0x0000, 0x0000,
65 0xffff, 0xffff, 0x7000, 0x8000, 0xffff
66};
67static UShort_t gGreenRainbow[12] = {
68 0x0000, 0x0000, 0x0000, 0xffff, 0xffff,
69 0xffff, 0x0000, 0x0000, 0x8000, 0xffff
70};
71static UShort_t gBlueRainbow[12] = {
72 0x0000, 0x7000, 0xffff, 0xffff, 0x0000,
73 0x0000, 0x0000, 0x0000, 0xa000, 0xffff
74};
75
76
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(nullptr, w, h)
84{
86 fHisto = nullptr;
87 fLimitLine[0] = nullptr;
88 fLimitLine[1] = nullptr;
89 fRampFactor = 0;
91
92 fPaletteList = new TList;
94
95 fPalette = new TImagePalette(attImage->GetPalette());
97
98 // buttons
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");
216
218 0, fHisto->GetMaximum(), this);
219 fLimitLine[0]->Draw();
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
244
246 Layout();
247
248 SetWindowName("Palette Editor");
249 SetIconName("Palette Editor");
250
251 MapWindow();
252
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:
302 break;
303
304 case kCM_RADIOBUTTON:
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
319 fImagePad->Update();
320 break;
321
322 case 2 : // OK
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
355 break;
356
357
358 case 20: // undo
360 if (fAutoUpdate->GetState() == kButtonDown) {
363 fImagePad->Update();
364 }
366 break;
367
368 case 21: // redo
370 if (fAutoUpdate->GetState() == kButtonDown) {
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 while (auto obj = fPaletteList->After(fPalette))
401 delete fPaletteList->Remove(obj);
402
403 // add new palette and make it to the current palette
406
407 // update the image
408 if (fAutoUpdate->GetState() == kButtonDown) {
411 fImagePad->Update();
412 }
413}
414
415////////////////////////////////////////////////////////////////////////////////
416/// Saves the current palette either into a ROOT file or in an ASCII file.
417/// It is called by the Save - button. Protected method.
418
420{
422 fi.fFileTypes = gFileTypes;
423 static Bool_t overwr = kFALSE;
424 fi.fOverwrite = overwr;
425
426 new TGFileDialog(gClient->GetRoot(), this, kFDSave, &fi);
427 overwr = fi.fOverwrite;
428 if (!fi.fFilename)
429 return;
430
431 TString fn = fi.fFilename;
432
433 if (fn.EndsWith(".pal.txt")) {
434 // write into an ASCII file
435 FILE *fl = fopen(fn.Data(), "w");
436 if (!fl)
437 return;
438 fprintf(fl, "%u\n", fPalette->fNumPoints);
439 for (Int_t pt = 0; pt < Int_t(fPalette->fNumPoints); pt++)
440 fprintf(fl, "%10.9f %04hx %04hx %04hx %04hx\n", fPalette->fPoints[pt], fPalette->fColorRed[pt],
442 fclose(fl);
443 } else {
444 // write into a ROOT file
445 if (!fn.EndsWith(".pal.root"))
446 fn.Append(".pal.root");
447
448 gROOT->SaveObjectAs(fPalette, fn.Data(), "q");
449 }
450}
451
452////////////////////////////////////////////////////////////////////////////////
453/// Opens either a ROOT file or an ASCII file and reads a palette.
454/// It is called by the Open - button. Protected method.
455
457{
459 fi.fFileTypes = gFileTypes;
460
461 new TGFileDialog(gClient->GetRoot(), this, kFDOpen, &fi);
462 if (!fi.fFilename)
463 return;
464
465 TString fn = fi.fFilename;
466
467 TImagePalette *newPalette = nullptr;
468
469 if (fn.EndsWith(".pal.txt")) {
470 FILE *fl = fopen(fn.Data(), "r");
471 if (!fl)
472 return;
473 UInt_t numPoints = 0;
474 if (fscanf(fl, "%u\n", &numPoints) != 1)
475 Error("Open", "Failure reading num points from %s", fn.Data());
476 newPalette = new TImagePalette(numPoints);
477 for (UInt_t pt = 0; pt < numPoints; pt++) {
478 if (fscanf(fl, "%lf %hx %hx %hx %hx\n", newPalette->fPoints + pt, newPalette->fColorRed + pt,
479 newPalette->fColorGreen + pt, newPalette->fColorBlue + pt, newPalette->fColorAlpha + pt) != 5)
480 Error("Open", "Failure reading point %u from %s", pt, fn.Data());
481 }
482 fclose(fl);
483 } else {
484 // read from a ROOT file
485 if (!fn.EndsWith(".pal.root"))
486 fn.Append(".pal.root");
487
489
490 auto fsave = TFile::Open(fn.Data(), "READ");
491 if (!fsave || !fsave->IsOpen()) {
492 delete fsave;
493 return;
494 }
495
496 newPalette = (TImagePalette *)fsave->Get("TImagePalette");
497 delete fsave;
498 if (dirsav)
499 dirsav->cd();
500 if (!newPalette)
501 return;
502 }
503
506
507 fComboBox->Select(5); // empty entry
508}
509
510////////////////////////////////////////////////////////////////////////////////
511/// All widgets of the screen are updated with the current palette.
512/// Protected method.
513
515{
516 // update the color palette
519
520 if (histoUpdate) {
521 // update the limit lines
523 fLimitLine[0]->SetX1(xPos);
524 fLimitLine[0]->SetX2(xPos);
525
527 fLimitLine[1]->SetX1(xPos);
528 fLimitLine[1]->SetX2(xPos);
529
532 }
533
534 // update undo / redo button
537
538 // test if it is a step palette
540
541 Int_t pt;
542 for (pt = 2; pt < Int_t(fPalette->fNumPoints - 2); pt += 2)
543 if (TMath::Abs(fPalette->fPoints[pt] - fPalette->fPoints[pt + 1]) > 0.0001 ||
547 step = kButtonUp;
548 fStepButton->SetState(step);
549
550 // find the ramp factor
551 fRampFactor = 4;
552 Int_t off = (fPalette->fNumPoints - 2) / 4;
553 for (pt = 0; pt < Int_t(fPalette->fNumPoints - 2) / 4 * 3; pt++)
554 if (fPalette->fColorRed[pt + 1] != fPalette->fColorRed[pt + 1 + off] ||
555 fPalette->fColorGreen[pt + 1] != fPalette->fColorGreen[pt + 1 + off] ||
556 fPalette->fColorBlue[pt + 1] != fPalette->fColorBlue[pt + 1 + off] ||
557 fPalette->fColorAlpha[pt + 1] != fPalette->fColorAlpha[pt + 1 + off]) {
558 fRampFactor = 2;
559 break;
560 }
561
562 off = (fPalette->fNumPoints - 2) / 2;
563 for (pt = 0; pt < Int_t(fPalette->fNumPoints - 2) / 2; pt++)
564 if (fPalette->fColorRed[pt + 1] != fPalette->fColorRed[pt + 1 + off] ||
565 fPalette->fColorGreen[pt + 1] != fPalette->fColorGreen[pt + 1 + off] ||
566 fPalette->fColorBlue[pt + 1] != fPalette->fColorBlue[pt + 1 + off] ||
567 fPalette->fColorAlpha[pt + 1] != fPalette->fColorAlpha[pt + 1 + off]) {
568 fRampFactor = 1;
569 break;
570 }
571
575}
576
577////////////////////////////////////////////////////////////////////////////////
578/// The anchor points are rescaled by a log operation.
579/// It is called by the log - button. Protected method.
580
582{
584
586
587 for (Int_t pt = 2; pt < Int_t(fPalette->fNumPoints - 2); pt++)
588 newPalette->fPoints[pt] = fPalette->fPoints[1] +
590 TMath::Log(delta + 1) * delta;
591
594}
595
596////////////////////////////////////////////////////////////////////////////////
597/// The anchor points are rescaled by a exp operation.
598/// It is called by the exp - button. Protected method.
599
601{
603
605
606 for (Int_t pt = 2; pt < Int_t(fPalette->fNumPoints - 2); pt++)
607 newPalette->fPoints[pt] = fPalette->fPoints[1] +
609 TMath::Log(delta + 1) / delta) - 1;
610
613}
614
615////////////////////////////////////////////////////////////////////////////////
616/// The anchor points are rescaled to be linar.
617/// It is called by the lin - button. Protected method.
618
620{
622
624 if (fStepButton->GetState() == kButtonUp) {
625 for (Int_t pt = 2; pt < Int_t(fPalette->fNumPoints - 2); pt++)
626 newPalette->fPoints[pt] = fPalette->fPoints[1] +
627 delta * (pt - 1) / (fPalette->fNumPoints - 3);
628 } else {
629 for (Int_t pt = 0; pt < Int_t(fPalette->fNumPoints - 4); pt += 2) {
630 newPalette->fPoints[pt + 3] = fPalette->fPoints[1] + delta * (pt + 2) /
631 (fPalette->fNumPoints - 2) ;
632 newPalette->fPoints[pt + 2] = newPalette->fPoints[pt + 3];
633 }
634 }
635
638}
639
640////////////////////////////////////////////////////////////////////////////////
641/// The palette is inverted.
642/// It is called by the invert - button. Protected method.
643
645{
647
648 Int_t pt;
649 for (pt = 0; pt < Int_t(fPalette->fNumPoints); pt++) {
650 newPalette->fColorRed[pt] = fPalette->fColorRed[fPalette->fNumPoints - 1 - pt];
651 newPalette->fColorGreen[pt] = fPalette->fColorGreen[fPalette->fNumPoints - 1 - pt];
652 newPalette->fColorBlue[pt] = fPalette->fColorBlue[fPalette->fNumPoints - 1 - pt];
653 newPalette->fColorAlpha[pt] = fPalette->fColorAlpha[fPalette->fNumPoints - 1 - pt];
654 }
655
656 for (pt = 2; pt < Int_t(fPalette->fNumPoints - 2); pt++)
657 newPalette->fPoints[pt] = fPalette->fPoints[1] +
660
663}
664
665////////////////////////////////////////////////////////////////////////////////
666/// A new palette is created, depending on the id.
667/// It is called by the combo box. Protected method.
668
670{
671 if (id == 5) // empty entry
672 return;
673
675
678
679 numPt = id == 0 ? 12 : 13;
681 Int_t pt;
682 for (pt = 1; pt < Int_t(numPt - 1); pt++) {
683 newPalette->fPoints[pt] = fPalette->fPoints[1] + (pt - 1) * delta / (numPt - 3);
684 newPalette->fColorAlpha[pt] = 0xffff;
685 }
686
687 switch (id) {
688 case 0: // rainbow
689 memcpy(newPalette->fColorRed + 1, gRedRainbow, 12 * sizeof(UShort_t));
690 memcpy(newPalette->fColorGreen + 1, gGreenRainbow, 12 * sizeof(UShort_t));
691 memcpy(newPalette->fColorBlue + 1, gBlueRainbow, 12 * sizeof(UShort_t));
692 break;
693
694 case 1: // gray
695 for (pt = 1; pt < Int_t(numPt - 1); pt++) {
696 newPalette->fColorRed[pt] = 0xffff * (pt - 1) / (numPt - 3);
697 newPalette->fColorGreen[pt] = 0xffff * (pt - 1) / (numPt - 3);
698 newPalette->fColorBlue[pt] = 0xffff * (pt - 1) / (numPt - 3);
699 }
700 break;
701
702 case 2: // hot (red)
703 for (pt = 1; pt < Int_t(numPt - 1) / 2; pt++) {
704 newPalette->fColorRed[pt] = 0xffff * (pt - 1) / ((numPt - 3) / 2);
705 newPalette->fColorGreen[pt] = 0;
706 newPalette->fColorBlue[pt] = 0;
707 }
708
709 for (; pt < Int_t(numPt - 1); pt++) {
710 newPalette->fColorRed[pt] = 0xffff;
711 newPalette->fColorGreen[pt] = 0xffff * (pt - (numPt - 1) / 2) / ((numPt - 3) / 2);
712 newPalette->fColorBlue[pt] = 0xffff * (pt - (numPt - 1) / 2) / ((numPt - 3) / 2);
713 }
714 break;
715
716 case 3: // cold (blue)
717 for (pt = 1; pt < Int_t(numPt - 1) / 2; pt++) {
718 newPalette->fColorRed[pt] = 0;
719 newPalette->fColorGreen[pt] = 0;
720 newPalette->fColorBlue[pt] = 0xffff * (pt - 1) / ((numPt - 3) / 2);
721 }
722
723 for (; pt < Int_t(numPt - 1); pt++) {
724 newPalette->fColorRed[pt] = 0xffff * (pt - (numPt - 1) / 2) / ((numPt - 3) / 2);
725 newPalette->fColorGreen[pt] = 0xffff * (pt - (numPt - 1) / 2) / ((numPt - 3) / 2);
726 newPalette->fColorBlue[pt] = 0xffff;
727 }
728 break;
729
730 case 4: // bolwerhat
731 for (pt = 1; pt < Int_t(numPt + 1) / 2; pt++) {
732 newPalette->fColorRed[pt] = newPalette->fColorRed[numPt - pt - 1]
733 = 0xffff * (pt - 1) / ((numPt - 3) / 2);
734 newPalette->fColorGreen[pt] = newPalette->fColorGreen[numPt - pt - 1]
735 = 0xffff * (pt - 1) / ((numPt - 3) / 2);
736 newPalette->fColorBlue[pt] = newPalette->fColorBlue[numPt - pt - 1]
737 = 0xffff * (pt - 1) / ((numPt - 3) / 2);
738 }
739 break;
740 }
741
742 newPalette->fPoints[0] = 0;
743 newPalette->fColorRed[0] = newPalette->fColorRed[1];
744 newPalette->fColorGreen[0] = newPalette->fColorGreen[1];
745 newPalette->fColorBlue[0] = newPalette->fColorBlue[1];
746 newPalette->fColorAlpha[0] = newPalette->fColorAlpha[1];
747
748 newPalette->fPoints[newPalette->fNumPoints-1] = 1.0;
749 newPalette->fColorRed[newPalette->fNumPoints-1] = newPalette->fColorRed[newPalette->fNumPoints-2];
750 newPalette->fColorGreen[newPalette->fNumPoints-1] = newPalette->fColorGreen[newPalette->fNumPoints-2];
751 newPalette->fColorBlue[newPalette->fNumPoints-1] = newPalette->fColorBlue[newPalette->fNumPoints-2];
752 newPalette->fColorAlpha[newPalette->fNumPoints-1] = newPalette->fColorAlpha[newPalette->fNumPoints-2];
753
756}
757
758////////////////////////////////////////////////////////////////////////////////
759/// Create a step palette. This is called by the step - check button.
760/// Protected method.
761
763{
765
766 if (fStepButton->GetState() == kButtonDown) {
767 // change colors in steps
770 for (Int_t pt = 1; pt < Int_t(fPalette->fNumPoints - 1); pt++) {
771 newPalette->fPoints[pt * 2 - 1] = fPalette->fPoints[1] + (fPalette->fPoints[pt] - fPalette->fPoints[1]) * fkt;
772 newPalette->fPoints[pt * 2] = fPalette->fPoints[1] + (fPalette->fPoints[pt + 1] - fPalette->fPoints[1]) * fkt;
773 newPalette->fColorRed[pt * 2 - 1] = newPalette->fColorRed[pt * 2] = fPalette->fColorRed[pt];
774 newPalette->fColorGreen[pt * 2 - 1] = newPalette->fColorGreen[pt * 2] = fPalette->fColorGreen[pt];
775 newPalette->fColorBlue[pt * 2 - 1] = newPalette->fColorBlue[pt * 2] = fPalette->fColorBlue[pt];
776 newPalette->fColorAlpha[pt * 2 - 1] = newPalette->fColorAlpha[pt * 2] = fPalette->fColorAlpha[pt];
777 }
778 } else {
779 // continuous change of colors
783 for (Int_t pt = 1; pt < Int_t(newPalette->fNumPoints - 1); pt++) {
784 newPalette->fPoints[pt] = fPalette->fPoints[pt * 2 -1] * fkt;
785 newPalette->fColorRed[pt] = fPalette->fColorRed[pt * 2 - 1];
786 newPalette->fColorGreen[pt] = fPalette->fColorGreen[pt * 2 - 1];
787 newPalette->fColorBlue[pt] = fPalette->fColorBlue[pt * 2 - 1];
788 newPalette->fColorAlpha[pt] = fPalette->fColorAlpha[pt * 2 - 1];
789 }
790 }
791
792 newPalette->fPoints[0] = fPalette->fPoints[0];
793 newPalette->fColorRed[0] = fPalette->fColorRed[0];
794 newPalette->fColorGreen[0] = fPalette->fColorGreen[0];
795 newPalette->fColorBlue[0] = fPalette->fColorBlue[0];
796 newPalette->fColorAlpha[0] = fPalette->fColorAlpha[0];
797
798 newPalette->fPoints[newPalette->fNumPoints-2] = fPalette->fPoints[fPalette->fNumPoints-2];
799 newPalette->fPoints[newPalette->fNumPoints-1] = fPalette->fPoints[fPalette->fNumPoints-1];
800 newPalette->fColorRed[newPalette->fNumPoints-1] = fPalette->fColorRed[fPalette->fNumPoints-1];
801 newPalette->fColorGreen[newPalette->fNumPoints-1] = fPalette->fColorGreen[fPalette->fNumPoints-1];
802 newPalette->fColorBlue[newPalette->fNumPoints-1] = fPalette->fColorBlue[fPalette->fNumPoints-1];
803 newPalette->fColorAlpha[newPalette->fNumPoints-1] = fPalette->fColorAlpha[fPalette->fNumPoints-1];
804
807}
808
809////////////////////////////////////////////////////////////////////////////////
810/// The palette is repeated up to 4 times.
811/// This is called by one of the ramp radio buttons. Protected method.
812
814{
815 if (ramp == fRampFactor)
816 return;
817
820
822 for (Int_t rp = 0; rp < ramp; rp++) {
823 for (Int_t pt = 0; pt < ptPerRamp; pt++) {
824 newPalette->fPoints[1 + pt + rp * ptPerRamp] = fPalette->fPoints[1] +
825 delta / ramp * rp +
827 newPalette->fColorRed [1 + pt + rp * ptPerRamp] = fPalette->fColorRed [1 + pt];
828 newPalette->fColorGreen[1 + pt + rp * ptPerRamp] = fPalette->fColorGreen[1 + pt];
829 newPalette->fColorBlue [1 + pt + rp * ptPerRamp] = fPalette->fColorBlue [1 + pt];
830 newPalette->fColorAlpha[1 + pt + rp * ptPerRamp] = fPalette->fColorAlpha[1 + pt];
831 }
832 }
833
834 newPalette->fPoints[0] = fPalette->fPoints[0];
835 newPalette->fColorRed[0] = fPalette->fColorRed[0];
836 newPalette->fColorGreen[0] = fPalette->fColorGreen[0];
837 newPalette->fColorBlue[0] = fPalette->fColorBlue[0];
838 newPalette->fColorAlpha[0] = fPalette->fColorAlpha[0];
839
840 newPalette->fPoints[newPalette->fNumPoints-2] = fPalette->fPoints[fPalette->fNumPoints-2];
841 newPalette->fPoints[newPalette->fNumPoints-1] = fPalette->fPoints[fPalette->fNumPoints-1];
842 newPalette->fColorRed[newPalette->fNumPoints-1] = fPalette->fColorRed[fPalette->fNumPoints-1];
843 newPalette->fColorGreen[newPalette->fNumPoints-1] = fPalette->fColorGreen[fPalette->fNumPoints-1];
844 newPalette->fColorBlue[newPalette->fNumPoints-1] = fPalette->fColorBlue[fPalette->fNumPoints-1];
845 newPalette->fColorAlpha[newPalette->fNumPoints-1] = fPalette->fColorAlpha[fPalette->fNumPoints-1];
846
849}
850
851////////////////////////////////////////////////////////////////////////////////
852/// Updates the range of the palette.
853/// This is called after the blue limit lines were moved to define
854/// a new range.
855
857{
858 if (fMaxValue == fMinValue)
859 return;
860
862
863 Double_t l0 = fLimitLine[0]->GetX1();
864 Double_t l1 = fLimitLine[1]->GetX1();
865 l0 = (l0 < fMinValue) ? fMinValue : ((l0 > fMaxValue) ? fMaxValue : l0);
866 l1 = (l1 < fMinValue) ? fMinValue : ((l1 > fMaxValue) ? fMaxValue : l1);
867 if (l0 > l1) {
868 Double_t tmp = l0;
869 l0 = l1;
870 l1 = tmp;
871 }
872
876
877 if (newDelta < 0.001 || oldDelta < 0.001)
878 return;
879
880 for (Int_t pt = 1; pt < Int_t(fPalette->fNumPoints - 1); pt++)
881 newPalette->fPoints[pt] = newOff +
883
886}
887
888////////////////////////////////////////////////////////////////////////////////
889/// Actually paint the paletter.
890
892{
893 // get geometry of pad
894 Int_t to_w = TMath::Abs(gPad->XtoPixel(gPad->GetX2()) -
895 gPad->XtoPixel(gPad->GetX1()));
896 Int_t to_h = TMath::Abs(gPad->YtoPixel(gPad->GetY2()) -
897 gPad->YtoPixel(gPad->GetY1()));
898
899 ASGradient grad;
900
901 grad.npoints = (*fPalette)->fNumPoints - 2;
902 grad.type = GRADIENT_Left2Right;
903 grad.color = new ARGB32[grad.npoints];
904 grad.offset = new double[grad.npoints];
905 for (Int_t pt = 0; pt < grad.npoints; pt++) {
906 grad.offset[pt] = ((*fPalette)->fPoints[pt + 1] - (*fPalette)->fPoints[1]) /
907 ((*fPalette)->fPoints[(*fPalette)->fNumPoints - 2] - (*fPalette)->fPoints[1]);
908 grad.color[pt] = (((ARGB32)((*fPalette)->fColorBlue[pt + 1] & 0xff00)) >> 8) |
909 (((ARGB32)((*fPalette)->fColorGreen[pt + 1] & 0xff00)) ) |
910 (((ARGB32)((*fPalette)->fColorRed[pt + 1] & 0xff00)) << 8) |
911 (((ARGB32)((*fPalette)->fColorAlpha[pt + 1] & 0xff00)) << 16);
912 }
913
917 delete [] grad.color;
918 delete [] grad.offset;
919
920 Window_t wid = (Window_t)gVirtualX->GetWindowID(gPad->GetPixmapID());
923}
924
925////////////////////////////////////////////////////////////////////////////////
926/// The blue limit line in the pixel value histogram.
927
936
937////////////////////////////////////////////////////////////////////////////////
938/// Paint the limit lines.
939
941{
942 fY1 = gPad->GetUymin();
943 fY2 = gPad->GetUymax();
944
946}
947
948////////////////////////////////////////////////////////////////////////////////
949
951 Int_t px, Int_t /*py*/)
952{
953 static Int_t oldX;
954
955 if (!gPad) return;
956
957 switch(event) {
958 case kMouseMotion:
959 gPad->SetCursor(kMove);
960 break;
961
962 case kButton1Down:
963 gVirtualX->SetLineColor(-1);
964 TAttLine::Modify(); //Change line attributes only if necessary
965 oldX = gPad->XtoAbsPixel(fX1);
966 break;
967
968 case kButton1Motion:
969 gVirtualX->DrawLine(oldX, gPad->YtoPixel(fY1), oldX, gPad->YtoPixel(fY2));
970 oldX = px;
971 gVirtualX->DrawLine(oldX, gPad->YtoPixel(fY1), oldX, gPad->YtoPixel(fY2));
972 gVirtualX->Update();
973 break;
974
975 case kButton1Up:
976 gVirtualX->SetLineColor(-1);
977 TAttLine::Modify(); //Change line attributes only if necessary
978 fX1 = fX2 = gPad->AbsPixeltoX(oldX);
979 fGui->UpdateRange();
980 gPad->Modified(kTRUE);
981 gPad->Update();
982 break;
983
984 default:
985 break;
986 }
987}
@ kMouseMotion
Definition Buttons.h:23
@ kButton1Motion
Definition Buttons.h:20
@ kButton1Up
Definition Buttons.h:19
@ kButton1Down
Definition Buttons.h:17
@ kMove
Definition GuiTypes.h:374
Handle_t Window_t
Window handle.
Definition GuiTypes.h:29
#define h(i)
Definition RSha256.hxx:106
unsigned short UShort_t
Unsigned Short integer 2 bytes (unsigned short)
Definition RtypesCore.h:54
int Int_t
Signed integer 4 bytes (int)
Definition RtypesCore.h:59
long Longptr_t
Integer large enough to hold a pointer (platform-dependent)
Definition RtypesCore.h:89
long Long_t
Signed long integer 4 bytes (long). Size depends on architecture.
Definition RtypesCore.h:68
constexpr Bool_t kFALSE
Definition RtypesCore.h:108
double Double_t
Double 8 bytes.
Definition RtypesCore.h:73
constexpr Bool_t kTRUE
Definition RtypesCore.h:107
const char Option_t
Option string (const char)
Definition RtypesCore.h:80
static UShort_t gRedRainbow[12]
static UShort_t gBlueRainbow[12]
static UShort_t gGreenRainbow[12]
static const char * gFileTypes[]
ROOT::Detail::TRangeCast< T, true > TRangeDynCast
TRangeDynCast is an adapter class that allows the typed iteration through a TCollection.
#define gDirectory
Definition TDirectory.h:385
void Error(const char *location, const char *msgfmt,...)
Use this function in case an error occurred.
Definition TError.cxx:208
EButtonState
Definition TGButton.h:52
@ kButtonDown
Definition TGButton.h:54
@ kButtonDisabled
Definition TGButton.h:56
@ kButtonUp
Definition TGButton.h:53
#define gClient
Definition TGClient.h:157
@ kFDOpen
@ kFDSave
Option_t Option_t option
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void data
Option_t Option_t SetLineWidth
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void pixel
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize wid
Option_t Option_t SetLineColor
Option_t Option_t TPoint TPoint const char y2
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t button
Option_t Option_t TPoint TPoint const char y1
#define gROOT
Definition TROOT.h:411
#define gPad
#define gVirtualX
Definition TVirtualX.h:337
Int_t GET_MSG(Long_t val)
@ kCM_COMBOBOX
@ kC_COMMAND
@ kCM_BUTTON
@ kCM_RADIOBUTTON
@ kCM_CHECKBUTTON
Int_t GET_SUBMSG(Long_t val)
Image class.
Definition TASImage.h:31
static const ASVisual * GetVisual()
Return visual.
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.
void Paint(Option_t *option="") override
Paint the limit lines.
LimitLine(Coord_t x, Coord_t y1, Coord_t y2, TASPaletteEditor *gui)
The blue limit line in the pixel value histogram.
void ExecuteEvent(Int_t event, Int_t px, Int_t py) override
Execute action corresponding to an event at (px,py).
void Paint(Option_t *option="") override
Actually paint the paletter.
This is a GUI window to edit a color palette.
void UpdateScreen(Bool_t histoUpdate)
All widgets of the screen are updated with the current palette.
PaintPalette * fPaintPalette
void UpdateRange()
Updates the range of the palette.
TGTextButton * fUnDoButton
TVirtualPad * fImagePad
TImagePalette * fPalette
current palette
TGCheckButton * fStepButton
TGTextButton * fReDoButton
Double_t fMinValue
min value of image
void Open()
Opens either a ROOT file or an ASCII file and reads a palette.
TList * fPaletteList
list of palettes for undo and redo
void ExpPalette()
The anchor points are rescaled by a exp operation.
void InsertNewPalette(TImagePalette *newPalette)
The newPalette is inserted in the list of palettes (fPaletteList) and fPalette is set to the newPalet...
void CloseWindow() override
Close editor.
TGRadioButton * fRamps[3]
TASPaletteEditor(TAttImage *attImage, UInt_t w, UInt_t h)
Palette editor constructor.
Bool_t ProcessMessage(Longptr_t msg, Longptr_t param1, Longptr_t param2) override
Process all editor mouse events.
TRootEmbeddedCanvas * fHistCanvas
canvas to draw the histogram
TGComboBox * fComboBox
TH1D * fHisto
histogram of image pixels
~TASPaletteEditor() override
Palette editor destructor. Deletes all frames and their layout hints.
void Save()
Saves the current palette either into a ROOT file or in an ASCII file.
TGCheckButton * fAutoUpdate
void NewPalette(Long_t id)
A new palette is created, depending on the id.
void LinPalette()
The anchor points are rescaled to be linar.
LimitLine * fLimitLine[2]
void SetRamp(Long_t ramp)
The palette is repeated up to 4 times.
void InvertPalette()
The palette is inverted.
void SetStep()
Create a step palette.
Double_t fMaxValue
max value of image
void LogPalette()
The anchor points are rescaled by a log operation.
TRootEmbeddedCanvas * fPaletteCanvas
canvas to draw the current palette
virtual void SetLabelSize(Float_t size=0.04)
Set size of axis labels.
Definition TAttAxis.cxx:184
virtual void SetLabelFont(Style_t font=62)
Set labels' font.
Definition TAttAxis.cxx:161
TImage attributes.
Definition TAttImage.h:59
virtual void SetPalette(const TImagePalette *palette)
Set a new palette for the image.
EImageQuality GetImageQuality() const
Definition TAttImage.h:87
virtual void Modify()
Change current line attributes if necessary.
Definition TAttLine.cxx:246
void Update() override
Update canvas pad buffers.
Definition TCanvas.cxx:2486
virtual void SetOwner(Bool_t enable=kTRUE)
Set whether this collection is the owner (enable==true) of its content.
Describe directory structure in memory.
Definition TDirectory.h:45
static TFile * Open(const char *name, Option_t *option="", const char *ftitle="", Int_t compress=ROOT::RCompressionSetting::EDefaults::kUseCompiledDefault, Int_t netopt=0)
Create / open a file.
Definition TFile.cxx:3764
virtual void SetToolTipText(const char *text, Long_t delayms=400)
Set tool tip text associated with this button.
Definition TGButton.cxx:439
virtual EButtonState GetState() const
Definition TGButton.h:112
virtual void SetState(EButtonState state, Bool_t emit=kFALSE)
Set button state.
Definition TGButton.cxx:229
Selects different options.
Definition TGButton.h:264
void SetState(EButtonState state, Bool_t emit=kFALSE) override
Set check button state.
A combobox (also known as a drop down listbox) allows the selection of one item out of a list of item...
Definition TGComboBox.h:47
virtual void AddEntry(TGString *s, Int_t id)
Definition TGComboBox.h:86
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...
virtual void SetLayoutManager(TGLayoutManager *l)
Set the layout manager for the composite frame.
Definition TGFrame.cxx:992
virtual void AddFrame(TGFrame *f, TGLayoutHints *l=nullptr)
Add frame to the composite frame using the specified layout hints.
Definition TGFrame.cxx:1109
void MapSubwindows() override
Map all sub windows that are part of the composite frame.
Definition TGFrame.cxx:1156
void Layout() override
Layout the elements of the composite frame.
Definition TGFrame.cxx:1249
TList * fList
container of frame elements
Definition TGFrame.h:294
This class creates a file selection dialog.
TGLayoutHints * fLayout
Definition TGLayout.h:114
TGFrame * fFrame
Definition TGLayout.h:112
void MapWindow() override
map window
Definition TGFrame.h:206
A composite frame with a border and a title.
Definition TGFrame.h:524
Defines top level windows that interact with the system Window Manager.
Definition TGFrame.h:399
void SetIconName(const char *name)
Set window icon name. This is typically done via the window manager.
Definition TGFrame.cxx:1793
void SetWindowName(const char *name=nullptr) override
Set window name. This is typically done via the window manager.
Definition TGFrame.cxx:1780
Selects different options.
Definition TGButton.h:321
void SetState(EButtonState state, Bool_t emit=kFALSE) override
Set radio button state.
Yield an action as soon as it is clicked.
Definition TGButton.h:142
virtual void Associate(const TGWindow *w)
Definition TGWidget.h:72
This layout hint must be used for the TGXYLayout manager!
Definition TGXYLayout.h:19
Is a layout manager where the position and the size of each widget in the frame are defined by X / Y ...
Definition TGXYLayout.h:58
1-D histogram with a double per channel (see TH1 documentation)
Definition TH1.h:927
TAxis * GetXaxis()
Definition TH1.h:572
virtual Double_t GetMaximum(Double_t maxval=FLT_MAX) const
Return maximum value smaller than maxval of bins in the range, unless the value has been overridden b...
Definition TH1.cxx:8586
virtual Int_t Fill(Double_t x)
Increment bin with abscissa X by 1.
Definition TH1.cxx:3326
TAxis * GetYaxis()
Definition TH1.h:573
void Draw(Option_t *option="") override
Draw this histogram with options.
Definition TH1.cxx:3048
A class to define a conversion from pixel values to pixel color.
Definition TAttImage.h:33
UShort_t * fColorRed
[fNumPoints] red color at each anchor point
Definition TAttImage.h:38
Double_t * fPoints
[fNumPoints] value of each anchor point [0..1]
Definition TAttImage.h:37
UShort_t * fColorGreen
[fNumPoints] green color at each anchor point
Definition TAttImage.h:39
UShort_t * fColorBlue
[fNumPoints] blue color at each anchor point
Definition TAttImage.h:40
UInt_t fNumPoints
number of anchor points
Definition TAttImage.h:36
UShort_t * fColorAlpha
[fNumPoints] alpha at each anchor point
Definition TAttImage.h:41
Use the TLine constructor to create a simple line.
Definition TLine.h:22
virtual void SetX2(Double_t x2)
Definition TLine.h:68
void Paint(Option_t *option="") override
Paint this line with its current attributes.
Definition TLine.cxx:418
virtual void SetX1(Double_t x1)
Definition TLine.h:67
Double_t GetX1() const
Definition TLine.h:50
A doubly linked list.
Definition TList.h:38
TObject * After(const TObject *obj) const override
Returns the object after object obj.
Definition TList.cxx:327
TObject * Before(const TObject *obj) const override
Returns the object before object obj.
Definition TList.cxx:368
void Add(TObject *obj) override
Definition TList.h:81
TObject * Remove(TObject *obj) override
Remove object from the list.
Definition TList.cxx:819
TObject * Last() const override
Return the last object in the list. Returns 0 when list is empty.
Definition TList.cxx:690
TObject * First() const override
Return the first object in the list. Returns 0 when list is empty.
Definition TList.cxx:656
virtual void Draw(Option_t *option="")
Default Draw method for all objects.
Definition TObject.cxx:293
void Modified(Bool_t flag=true) override
Mark pad modified Will be repainted when TCanvas::Update() will be called next time.
Definition TPad.cxx:7459
Edit the palette via a GUI.
Definition TAttImage.h:19
virtual void CloseWindow()
Closes the window and deletes itself.
TAttImage * fAttImage
Definition TAttImage.h:22
This class creates a TGCanvas in which a TCanvas is created.
TCanvas * GetCanvas() const
Basic string class.
Definition TString.h:138
virtual void Modified(Bool_t flag=1)=0
virtual void Update()=0
TPaveText * pt
Double_t x[n]
Definition legend1.C:17
Double_t Exp(Double_t x)
Returns the base-e exponential function of x, which is e raised to the power x.
Definition TMath.h:720
Double_t Log(Double_t x)
Returns the natural logarithm of x.
Definition TMath.h:767
Short_t Abs(Short_t d)
Returns the absolute value of parameter Short_t d.
Definition TMathBase.h:124