Logo ROOT   6.30.04
Reference Guide
 All Namespaces Files Pages
TGColorSelect.cxx
Go to the documentation of this file.
1 // @(#)root/gui:$Id$
2 // Author: Bertrand Bellenot + Fons Rademakers 22/08/02
3 
4 /*************************************************************************
5  * Copyright (C) 1995-2002, Rene Brun and Fons Rademakers. *
6  * All rights reserved. *
7  * *
8  * For the licensing terms see $ROOTSYS/LICENSE. *
9  * For the list of contributors see $ROOTSYS/README/CREDITS. *
10  *************************************************************************/
11 /**************************************************************************
12 
13  This source is based on Xclass95, a Win95-looking GUI toolkit.
14  Copyright (C) 1996, 1997 David Barth, Ricky Ralston, Hector Peraza.
15 
16  Xclass95 is free software; you can redistribute it and/or
17  modify it under the terms of the GNU Library General Public
18  License as published by the Free Software Foundation; either
19  version 2 of the License, or (at your option) any later version.
20 
21 **************************************************************************/
22 
23 //////////////////////////////////////////////////////////////////////////
24 // //
25 // TGColorFrame, TG16ColorSelector, TGColorPopup and TGColorSelect. //
26 // //
27 // The TGColorFrame is a small frame with border showing a specific //
28 // color. //
29 // //
30 // The TG16ColorSelector is a composite frame with 16 TGColorFrames. //
31 // //
32 // The TGColorPopup is a popup containing a TG16ColorSelector and a //
33 // "More..." button which popups up a TGColorDialog allowing custom //
34 // color selection. //
35 // //
36 // The TGColorSelect widget is like a checkbutton but instead of the //
37 // check mark there is color area with a little down arrow. When //
38 // clicked on the arrow the TGColorPopup pops up. //
39 // //
40 // Selecting a color in this widget will generate the event: //
41 // kC_COLORSEL, kCOL_SELCHANGED, widget id, pixel. //
42 // and the signal: //
43 // ColorSelected(Pixel_t color) //
44 // //
45 //////////////////////////////////////////////////////////////////////////
46 
47 #include "TGClient.h"
48 #include "TGMsgBox.h"
49 #include "TGGC.h"
50 #include "TGColorSelect.h"
51 #include "TGColorDialog.h"
52 #include "TGResourcePool.h"
53 #include "RConfigure.h"
54 #include "TG3DLine.h"
55 #include "TColor.h"
56 #include "Riostream.h"
57 
58 ClassImp(TGColorFrame);
59 ClassImp(TG16ColorSelector);
60 ClassImp(TGColorPopup);
61 ClassImp(TGColorSelect);
62 
63 
64 ////////////////////////////////////////////////////////////////////////////////
65 /// TGColorFrame constructor.
66 /// The TGColorFrame is a small frame with border showing a specific color.
67 
68 TGColorFrame::TGColorFrame(const TGWindow *p, ULong_t color, Int_t /*n*/) :
69  TGFrame(p, 20, 20, kOwnBackground, color)
70 {
71  SetBackgroundColor(color);
72 
73  fPixel = fColor = color;
74 
75  AddInput(kButtonPressMask | kButtonReleaseMask);
76  fMsgWindow = p;
77  fActive = kFALSE;
78 
79  fGrayGC = GetShadowGC()();
80  fEditDisabled = kEditDisable;
81 }
82 
83 ////////////////////////////////////////////////////////////////////////////////
84 /// Handle button events in TGColorFrame.
85 
86 Bool_t TGColorFrame::HandleButton(Event_t *event)
87 {
88  if (event->fType == kButtonPress) {
89  SendMessage(fMsgWindow, MK_MSG(kC_COLORSEL, kCOL_CLICK), event->fCode, fColor);
90  } else { // kButtonRelease
91  SendMessage(fMsgWindow, MK_MSG(kC_COLORSEL, kCOL_SELCHANGED), event->fCode, fColor);
92  }
93 
94  return kTRUE;
95 }
96 
97 ////////////////////////////////////////////////////////////////////////////////
98 /// Draw TGColorFrame border.
99 
100 void TGColorFrame::DrawBorder()
101 {
102  gVirtualX->DrawRectangle(fId, GetBckgndGC()(), 0, 0, fWidth - 1, fHeight - 1);
103  Draw3dRectangle(kDoubleBorder | kSunkenFrame, 1, 1, fWidth - 2, fHeight - 2);
104 }
105 
106 ////////////////////////////////////////////////////////////////////////////////
107 /// TG16ColorSelector constructor.
108 /// The TG16ColorSelector is a composite frame with 16 TGColorFrames.
109 
110 TG16ColorSelector::TG16ColorSelector(const TGWindow *p) :
111  TGCompositeFrame(p, 10, 10)
112 {
113  SetLayoutManager(new TGMatrixLayout(this, 4, 4, 1, 1));
114 
115  fCe[0] = new TGColorFrame(this, TColor::Number2Pixel(0), 0);
116  fCe[1] = new TGColorFrame(this, TColor::Number2Pixel(1), 1);
117  fCe[2] = new TGColorFrame(this, TColor::Number2Pixel(2), 2);
118  fCe[3] = new TGColorFrame(this, TColor::Number2Pixel(3), 3);
119  fCe[4] = new TGColorFrame(this, TColor::Number2Pixel(4), 4);
120  fCe[5] = new TGColorFrame(this, TColor::Number2Pixel(5), 5);
121  fCe[6] = new TGColorFrame(this, TColor::Number2Pixel(6), 6);
122  fCe[7] = new TGColorFrame(this, TColor::Number2Pixel(7), 7);
123  fCe[8] = new TGColorFrame(this, TColor::Number2Pixel(8), 8);
124  fCe[9] = new TGColorFrame(this, TColor::Number2Pixel(9), 9);
125  fCe[10] = new TGColorFrame(this, TColor::Number2Pixel(30), 10);
126  fCe[11] = new TGColorFrame(this, TColor::Number2Pixel(38), 11);
127  fCe[12] = new TGColorFrame(this, TColor::Number2Pixel(41), 12);
128  fCe[13] = new TGColorFrame(this, TColor::Number2Pixel(42), 13);
129  fCe[14] = new TGColorFrame(this, TColor::Number2Pixel(50), 14);
130  fCe[15] = new TGColorFrame(this, TColor::Number2Pixel(51), 15);
131 
132  for (Int_t i = 0; i < 16; i++)
133  AddFrame(fCe[i], new TGLayoutHints(kLHintsCenterX | kLHintsCenterY));
134 
135  fMsgWindow = p;
136  fActive = -1;
137 
138  SetEditDisabled(kEditDisable);
139 }
140 
141 ////////////////////////////////////////////////////////////////////////////////
142 /// TG16ColorSelector destructor.
143 
144 TG16ColorSelector::~TG16ColorSelector()
145 {
146  Cleanup();
147 }
148 
149 ////////////////////////////////////////////////////////////////////////////////
150 /// Set active color frame.
151 
152 void TG16ColorSelector::SetActive(Int_t newat)
153 {
154  if (fActive != newat) {
155  if ((fActive >= 0) && (fActive < 16)) {
156  fCe[fActive]->SetActive(kFALSE);
157  }
158  fActive = newat;
159  if ((fActive >= 0) && (fActive < 16)) {
160  fCe[fActive]->SetActive(kTRUE);
161  }
162  }
163 }
164 
165 ////////////////////////////////////////////////////////////////////////////////
166 /// Process messages for TG16ColorSelector.
167 
168 Bool_t TG16ColorSelector::ProcessMessage(Long_t msg, Long_t parm1, Long_t parm2)
169 {
170  switch (GET_MSG(msg)) {
171  case kC_COLORSEL:
172  switch (GET_SUBMSG(msg)) {
173  case kCOL_SELCHANGED:
174  switch (parm1) {
175  case kButton1:
176  SendMessage(fMsgWindow,
177  MK_MSG(kC_COLORSEL, kCOL_SELCHANGED),
178  parm1, parm2);
179  break;
180  }
181  break;
182 
183  case kCOL_CLICK:
184  switch (parm1) {
185  case kButton1:
186  SetActive(parm2);
187  break;
188  }
189  break;
190  }
191  }
192 
193  return kTRUE;
194 }
195 
196 ////////////////////////////////////////////////////////////////////////////////
197 /// TGColorPopup constructor.
198 /// The TGColorPopup is a popup containing a TG16ColorSelector and a "More..."
199 /// button which popups up a TGColorDialog allowing custom color selection.
200 
201 TGColorPopup::TGColorPopup(const TGWindow *p, const TGWindow *m, ULong_t color) :
202  TGCompositeFrame(p, 10, 10, kDoubleBorder | kRaisedFrame | kOwnBackground,
203  GetDefaultFrameBackground())
204 {
205  fMsgWindow = m;
206  fCurrentColor = color;
207 
208  SetWindowAttributes_t wattr;
209 
210  wattr.fMask = kWAOverrideRedirect; // | kWASaveUnder ;
211  wattr.fOverrideRedirect = kTRUE;
212  //wattr.fSaveUnder = kTRUE;
213  gVirtualX->ChangeWindowAttributes(fId, &wattr);
214 
215  AddInput(kStructureNotifyMask);
216 
217  fActive = -1;
218  fLaunchDialog = kFALSE;
219 
220  TG16ColorSelector *cs = new TG16ColorSelector(this);
221  AddFrame(cs, new TGLayoutHints(kLHintsCenterX, 1, 1, 1, 1));
222  AddFrame(new TGHorizontal3DLine(this),
223  new TGLayoutHints(kLHintsExpandX | kLHintsCenterY, 2, 2, 2, 2));
224  TGTextButton *other = new TGTextButton(this, "Other...", 102);
225  other->SetToolTipText("Popups up Color Selector");
226  other->Associate(this);
227  AddFrame(other, new TGLayoutHints(kLHintsCenterX | kLHintsExpandX, 2, 2, 2, 2));
228 
229  MapSubwindows();
230 
231  Resize(cs->GetDefaultWidth() + 6, cs->GetDefaultHeight() +
232  other->GetDefaultHeight());
233  SetEditDisabled(kEditDisable);
234 }
235 
236 ////////////////////////////////////////////////////////////////////////////////
237 /// TGColorPopup destructor.
238 
239 TGColorPopup::~TGColorPopup()
240 {
241  Cleanup();
242 }
243 
244 ////////////////////////////////////////////////////////////////////////////////
245 /// Ungrab pointer and unmap window.
246 
247 void TGColorPopup::EndPopup()
248 {
249  gVirtualX->GrabPointer(0, 0, 0, 0, kFALSE); // ungrab pointer
250  UnmapWindow();
251 }
252 
253 ////////////////////////////////////////////////////////////////////////////////
254 /// Popup TGColorPopup at x,y position
255 
256 void TGColorPopup::PlacePopup(Int_t x, Int_t y, UInt_t w, UInt_t h)
257 {
258  Int_t rx, ry;
259  UInt_t rw, rh;
260 
261  // Parent is root window for the popup:
262  gVirtualX->GetWindowSize(fParent->GetId(), rx, ry, rw, rh);
263 
264  if (gVirtualX->InheritsFrom("TGWin32")) {
265  if ((x > 0) && ((x + abs(rx) + (Int_t)fWidth) > (Int_t)rw))
266  x = rw - abs(rx) - fWidth;
267  if ((y > 0) && (y + abs(ry) + (Int_t)fHeight > (Int_t)rh))
268  y = rh - fHeight;
269  } else {
270  if (x < 0) x = 0;
271  if (x + fWidth > rw) x = rw - fWidth;
272  if (y < 0) y = 0;
273  if (y + fHeight > rh) y = rh - fHeight;
274  }
275 
276  MoveResize(x, y, w, h);
277  MapSubwindows();
278  Layout();
279  MapRaised();
280 
281  gVirtualX->GrabPointer(fId, kButtonPressMask | kButtonReleaseMask |
282  kPointerMotionMask, kNone,
283  fClient->GetResourcePool()->GetGrabCursor());
284 
285  fLaunchDialog = kFALSE;
286 
287  gClient->WaitForUnmap(this);
288  EndPopup();
289 
290  if (fLaunchDialog) {
291  Int_t retc;
292  ULong_t color = fCurrentColor;
293 
294  new TGColorDialog(gClient->GetDefaultRoot(), this, &retc, &color);
295 
296  if (retc == kMBOk) {
297  fCurrentColor = color;
298  SendMessage(fMsgWindow, MK_MSG(kC_COLORSEL, kCOL_SELCHANGED),
299  -1, color);
300  }
301  }
302  DeleteWindow();
303 }
304 
305 ////////////////////////////////////////////////////////////////////////////////
306 /// Handle mouse button events for TGColorPopup.
307 
308 Bool_t TGColorPopup::HandleButton(Event_t *event)
309 {
310  if (event->fX < 0 || event->fX >= (Int_t) fWidth ||
311  event->fY < 0 || event->fY >= (Int_t) fHeight) {
312  if (event->fType == kButtonRelease)
313  UnmapWindow();
314  } else {
315  TGFrame *f = GetFrameFromPoint(event->fX, event->fY);
316  if (f && f != this) {
317  TranslateCoordinates(f, event->fX, event->fY, event->fX, event->fY);
318  f->HandleButton(event);
319  }
320  }
321  return kTRUE;
322 }
323 
324 ////////////////////////////////////////////////////////////////////////////////
325 /// Process messages for TGColorPopup.
326 
327 Bool_t TGColorPopup::ProcessMessage(Long_t msg, Long_t parm1, Long_t parm2)
328 {
329  switch (GET_MSG(msg)) {
330  case kC_COLORSEL:
331  switch (GET_SUBMSG(msg)) {
332  case kCOL_SELCHANGED:
333  SendMessage(fMsgWindow, MK_MSG(kC_COLORSEL, kCOL_SELCHANGED),
334  parm1, parm2);
335  UnmapWindow();
336  break;
337 
338  default:
339  break;
340  }
341  break;
342 
343  case kC_COMMAND:
344  switch (GET_SUBMSG(msg)) {
345  case kCM_BUTTON:
346  if (parm1 == 102) {
347  fLaunchDialog = kTRUE;
348  UnmapWindow();
349  }
350  break;
351  }
352  break;
353  }
354  return kTRUE;
355 }
356 
357 ////////////////////////////////////////////////////////////////////////////////
358 /// Emit a signal to see preview.
359 
360 void TGColorPopup::PreviewColor(Pixel_t color)
361 {
362  if (fClient->IsEditable()) return;
363 
364  fCurrentColor = color;
365  SendMessage(fMsgWindow, MK_MSG(kC_COLORSEL, kCOL_SELCHANGED), -1, color);
366 }
367 
368 ////////////////////////////////////////////////////////////////////////////////
369 /// Emit a signal to see preview.
370 
371 void TGColorPopup::PreviewAlphaColor(ULong_t color)
372 {
373  if (fClient->IsEditable()) return;
374 
375  TColor *tcolor = (TColor *)color;
376  fCurrentColor = tcolor->GetPixel();
377  SendMessage(fMsgWindow, MK_MSG(kC_COLORSEL, kCOL_SELCHANGED), 0, (ULong_t)tcolor);
378 }
379 
380 ////////////////////////////////////////////////////////////////////////////////
381 /// TGColorSelect constructor.
382 /// The TGColorSelect widget is like a checkbutton but instead of the check
383 /// mark there is color area with a little down arrow.
384 /// When clicked on the arrow the TGColorPopup pops up.
385 
386 TGColorSelect::TGColorSelect(const TGWindow *p, ULong_t color, Int_t id) :
387  TGCheckButton(p, "", id)
388 {
389  if (!p && fClient->IsEditable() && !color) {
390  color = TColor::Number2Pixel(6); // magenta
391  }
392 
393  fColor = color;
394  fColorPopup = 0;
395  fDrawGC = *fClient->GetResourcePool()->GetFrameGC();
396 
397  Enable();
398  SetState(kButtonUp);
399  AddInput(kButtonPressMask | kButtonReleaseMask);
400  SetColor(fColor);
401 
402  fEditDisabled = kEditDisable;
403 }
404 
405 ////////////////////////////////////////////////////////////////////////////////
406 /// TGColorSelect destructor.
407 
408 TGColorSelect::~TGColorSelect()
409 {
410  delete fColorPopup;
411 }
412 
413 ////////////////////////////////////////////////////////////////////////////////
414 /// Process messages for TGColorSelect.
415 
416 Bool_t TGColorSelect::ProcessMessage(Long_t msg, Long_t parm1, Long_t parm2)
417 {
418  switch (GET_MSG(msg)) {
419  case kC_COLORSEL:
420  switch (GET_SUBMSG(msg)) {
421  case kCOL_SELCHANGED:
422  {
423  if (parm1 == 0) {
424  SetAlphaColor((ULong_t)parm2);
425  parm1 = (Long_t)fWidgetId; // parm1 needs to pass the widget Id
426  SendMessage(fMsgWindow, MK_MSG(kC_COLORSEL, kCOL_SELCHANGED),
427  parm1, parm2);
428  }
429  else {
430  SetColor(parm2);
431  parm1 = (Long_t)fWidgetId; // parm1 needs to pass the widget Id
432  SendMessage(fMsgWindow, MK_MSG(kC_COLORSEL, kCOL_SELCHANGED),
433  parm1, parm2);
434  }
435  }
436  break;
437 
438  default:
439  break;
440  }
441  break;
442  }
443  return kTRUE;
444 }
445 
446 ////////////////////////////////////////////////////////////////////////////////
447 /// Handle button events for TGColorSelect.
448 
449 Bool_t TGColorSelect::HandleButton(Event_t *event)
450 {
451  TGFrame::HandleButton(event);
452  if (!IsEnabled()) return kTRUE;
453 
454  if (event->fCode != kButton1) return kFALSE;
455 
456  if ((event->fType == kButtonPress) && HasFocus())
457  WantFocus();
458 
459  if (event->fType == kButtonPress) {
460  fPressPos.fX = fX;
461  fPressPos.fY = fY;
462 
463  if (fState != kButtonDown) {
464  fPrevState = fState;
465  SetState(kButtonDown);
466  }
467  } else {
468  if (fState != kButtonUp) {
469  SetState(kButtonUp);
470 
471  // case when it was dragged during guibuilding
472  if ((fPressPos.fX != fX) || (fPressPos.fY != fY)) {
473  return kFALSE;
474  }
475  Window_t wdummy;
476  Int_t ax, ay;
477 
478  if (!fColorPopup)
479  fColorPopup = new TGColorPopup(gClient->GetDefaultRoot(), this, fColor);
480 
481  gVirtualX->TranslateCoordinates(fId, gClient->GetDefaultRoot()->GetId(),
482  0, fHeight, ax, ay, wdummy);
483 
484 #ifdef R__HAS_COCOA
485  gVirtualX->SetWMTransientHint(fColorPopup->GetId(), GetId());
486 #endif
487  fColorPopup->PlacePopup(ax, ay, fColorPopup->GetDefaultWidth(),
488  fColorPopup->GetDefaultHeight());
489  fColorPopup = 0;
490  }
491  }
492  return kTRUE;
493 }
494 
495 ////////////////////////////////////////////////////////////////////////////////
496 /// Set state of widget as enabled.
497 
498 void TGColorSelect::Enable(Bool_t on)
499 {
500  if (on) {
501  SetFlags(kWidgetIsEnabled);
502  } else {
503  ClearFlags(kWidgetIsEnabled);
504  }
505  fClient->NeedRedraw(this);
506 }
507 
508 ////////////////////////////////////////////////////////////////////////////////
509 /// Set state of widget as disabled.
510 
511 void TGColorSelect::Disable()
512 {
513  ClearFlags(kWidgetIsEnabled);
514  fClient->NeedRedraw(this);
515 }
516 
517 ////////////////////////////////////////////////////////////////////////////////
518 /// Redraw TGColorSelect widget.
519 
520 void TGColorSelect::DoRedraw()
521 {
522  Int_t x, y;
523  UInt_t w, h;
524 
525  TGButton::DoRedraw();
526 
527  if (IsEnabled()) {
528 
529  // color rectangle
530 
531  x = fBorderWidth + 2;
532  y = fBorderWidth + 2; // 1;
533  w = 22;
534  h = fHeight - (fBorderWidth * 2) - 4; // -3; // 14
535 
536  if (fState == kButtonDown) { ++x; ++y; }
537 
538 #ifdef R__HAS_COCOA
539  //Adjustment for Quartz 2D is required:
540  //first, I DO not try to fit filled rectangle into outline - this
541  //simply DOES NOT work (with retina/non-retina display, for example.
542  //First - fill rectable, then draw outline.
543  gVirtualX->FillRectangle(fId, fDrawGC(), x + 1, y + 1, w - 1, h - 1);
544  gVirtualX->DrawRectangle(fId, GetShadowGC()(), x + 1, y + 1, w - 1, h - 1);
545 #else
546  gVirtualX->DrawRectangle(fId, GetShadowGC()(), x, y, w - 1, h - 1);
547  gVirtualX->FillRectangle(fId, fDrawGC(), x + 1, y + 1, w - 2, h - 2);
548 #endif
549 
550  // separator
551 
552  x = fWidth - 6 - fBorderWidth - 6;
553  y = fBorderWidth + 1;
554  h = fHeight - fBorderWidth - 1; // actually y1
555 
556  if (fState == kButtonDown) { ++x; ++y; }
557 
558  gVirtualX->DrawLine(fId, GetShadowGC()(), x, y, x, h - 2);
559  gVirtualX->DrawLine(fId, GetHilightGC()(), x + 1, y, x + 1, h - 1);
560  gVirtualX->DrawLine(fId, GetHilightGC()(), x, h - 1, x + 1, h - 1);
561 
562  // arrow
563 
564  x = fWidth - 6 - fBorderWidth - 2;
565  y = (fHeight - 4) / 2 + 1;
566 
567  if (fState == kButtonDown) { ++x; ++y; }
568 
569  DrawTriangle(GetBlackGC()(), x, y);
570 
571  } else {
572 
573  // sunken rectangle
574 
575  x = fBorderWidth + 2;
576  y = fBorderWidth + 2; // 1;
577  w = 22;
578  h = fHeight - (fBorderWidth * 2) - 4; // 3;
579 
580  Draw3dRectangle(kSunkenFrame, x, y, w, h);
581 
582  // separator
583 
584  x = fWidth - 6 - fBorderWidth - 6;
585  y = fBorderWidth + 1;
586  h = fHeight - fBorderWidth - 1; // actually y1
587 
588  gVirtualX->DrawLine(fId, GetShadowGC()(), x, y, x, h - 2);
589  gVirtualX->DrawLine(fId, GetHilightGC()(), x + 1, y, x + 1, h - 1);
590  gVirtualX->DrawLine(fId, GetHilightGC()(), x, h - 1, x + 1, h - 1);
591 
592  // sunken arrow
593 
594  x = fWidth - 6 - fBorderWidth - 2;
595  y = (fHeight - 4) / 2 + 1;
596 
597  DrawTriangle(GetHilightGC()(), x + 1, y + 1);
598  DrawTriangle(GetShadowGC()(), x, y);
599  }
600 }
601 
602 ////////////////////////////////////////////////////////////////////////////////
603 /// Draw triangle (arrow) on which user can click to open TGColorPopup.
604 
605 void TGColorSelect::DrawTriangle(GContext_t gc, Int_t x, Int_t y)
606 {
607  Point_t points[3];
608 
609 #ifdef R__HAS_COCOA
610  //When it comes to tiny pixel-precise objects like this,
611  //Quartz is not really good: triangle is ugly and wrong.
612  //I have to adjust pixels manually.
613  points[0].fX = x;
614  points[0].fY = y;
615  points[1].fX = x + 6;
616  points[1].fY = y;
617  points[2].fX = x + 3;
618  points[2].fY = y + 3;
619 #else
620  points[0].fX = x;
621  points[0].fY = y;
622  points[1].fX = x + 5;
623  points[1].fY = y;
624  points[2].fX = x + 2;
625  points[2].fY = y + 3;
626 #endif
627 
628  gVirtualX->FillPolygon(fId, gc, points, 3);
629 }
630 
631 ////////////////////////////////////////////////////////////////////////////////
632 /// Set color.
633 
634 void TGColorSelect::SetColor(ULong_t color, Bool_t emit)
635 {
636  fColor = color;
637  fDrawGC.SetForeground(color);
638  gClient->NeedRedraw(this);
639  if (emit)
640  ColorSelected(fColor); // emit a signal
641 }
642 
643 ////////////////////////////////////////////////////////////////////////////////
644 /// Set color.
645 
646 void TGColorSelect::SetAlphaColor(ULong_t color, Bool_t emit)
647 {
648  if (emit) {
649  AlphaColorSelected(color); //emit opacity signal
650  }
651 }
652 
653 
654 ////////////////////////////////////////////////////////////////////////////////
655 /// Save a color select widget as a C++ statement(s) on output stream out
656 
657 void TGColorSelect::SavePrimitive(std::ostream &out, Option_t *option /*= ""*/)
658 {
659  char quote = '"';
660  static Int_t nn = 1;
661  TString cvar = TString::Format("ColPar%d",nn);
662 
663  ULong_t color = GetColor();
664  const char *colorname = TColor::PixelAsHexString(color);
665  gClient->GetColorByName(colorname, color);
666 
667  out << std::endl << " // color select widget" << std::endl;
668  out << " ULong_t " << cvar.Data() << ";" << std::endl;
669  out << " gClient->GetColorByName(" << quote << colorname << quote
670  << ", " << cvar.Data() << ");" << std::endl;
671 
672  out <<" TGColorSelect *";
673  out << GetName() << " = new TGColorSelect(" << fParent->GetName()
674  << ", " << cvar.Data() << ", " << WidgetId() << ");" << std::endl;
675  nn++;
676 
677  if (option && strstr(option, "keep_names"))
678  out << " " << GetName() << "->SetName(\"" << GetName() << "\");" << std::endl;
679 
680  if (!IsEnabled()) {
681  out << " " << GetName() << "->Disable();" << std::endl;
682  }
683  out << std::endl;
684 }
685