#include <stdlib.h>
#include "TGLabel.h"
#include "TGMsgBox.h"         
#include "TGLayout.h"
#include "TGGC.h"
#include "KeySymbols.h"
#include "TGColorDialog.h"
#include "TGTextEntry.h"
#include "TGButton.h"
#include "TGResourcePool.h"
#include "TColor.h"
#include "TColorWheel.h"
#include "TGColorSelect.h"
#include "TGTab.h"
#include "TRootEmbeddedCanvas.h"
#include "TCanvas.h"
#include "TROOT.h"
ClassImp(TGColorPalette)
ClassImp(TGColorPick)
ClassImp(TGColorDialog)
enum EColorDialog {
   kCDLG_OK       = 100,
   kCDLG_CANCEL,
   kCDLG_PREVIEW,
   kCDLG_ADD,
   kCDLG_SPALETTE = 200,
   kCDLG_CPALETTE,
   kCDLG_COLORPICK,
   kCDLG_HTE      = 300,
   kCDLG_LTE,
   kCDLG_STE,
   kCDLG_RTE,
   kCDLG_GTE,
   kCDLG_BTE
};
enum EColorPick {
   kCLICK_NONE,
   kCLICK_HS,
   kCLICK_L
};
enum EColorImage {
   kIMG_HS,
   kIMG_L
};
static ULong_t gUcolor[24] = { 0xff000000 };
TGColorPalette::TGColorPalette(const TGWindow *p, Int_t cols, Int_t rows, Int_t id) :
   TGFrame(p, 10, 10, kChildFrame)
{
   
   
   
   fWidgetId    = id;
   fWidgetFlags = kWidgetIsEnabled;
   fMsgWindow   = p;
   fDrawGC      = *fClient->GetResourcePool()->GetFrameGC();
   fCw = 20;
   fCh = 17;
   fRows = rows;
   fCols = cols;
   fCx = fCy = 0;
   fPixels = new ULong_t[fRows * fCols];
   for (Int_t i = 0; i < fRows * fCols; ++i) {
      fPixels[i] = TColor::RGB2Pixel(255, 255, 255);
   }
   gVirtualX->GrabButton(fId, kAnyButton, kAnyModifier,
                         kButtonPressMask | kButtonReleaseMask |
                         kPointerMotionMask, kNone, kNone);
   AddInput(kKeyPressMask | kEnterWindowMask | kLeaveWindowMask |
            kFocusChangeMask | kStructureNotifyMask);
   fEditDisabled = kEditDisable;
}
TGColorPalette::~TGColorPalette()
{
   
   delete [] fPixels;
}
Bool_t TGColorPalette::HandleButton(Event_t *event)
{
   
   if (event->fCode != kButton1)
      return kFALSE;
   if ((event->fType == kButtonPress) && HasFocus())
      WantFocus();
   Int_t cx = event->fX / (fCw + 5);
   Int_t cy = event->fY / (fCh + 5);
   if (cx >= 0 && cx < fCols && cy >= 0 && cy < fRows) {
      DrawFocusHilite(kFALSE);
      fCx = cx;
      fCy = cy;
      DrawFocusHilite(kTRUE);
      SendMessage(fMsgWindow, MK_MSG(kC_COLORSEL, kCOL_CLICK), fWidgetId, 0);
      ColorSelected();
   }
   return kTRUE;
}
Bool_t TGColorPalette::HandleMotion(Event_t *event)
{
   
   if (!IsEnabled())
      return kTRUE;
   Int_t cx = event->fX / (fCw + 5);
   Int_t cy = event->fY / (fCh + 5);
   if (cx >= 0 && cx < fCols && cy >= 0 && cy < fRows) {
      DrawFocusHilite(kFALSE);
      fCx = cx;
      fCy = cy;
      DrawFocusHilite(kTRUE);
      SendMessage(fMsgWindow, MK_MSG(kC_COLORSEL, kCOL_CLICK), fWidgetId, 0);
      ColorSelected();
   }
   return kTRUE;
}
Bool_t TGColorPalette::HandleKey(Event_t *event)
{
   
   Char_t input[10];
   UInt_t keysym;
   if (event->fType == kGKeyPress) {
      gVirtualX->LookupString(event, input, sizeof(input), keysym);
      Int_t cx = fCx;
      Int_t cy = fCy;
      switch ((EKeySym)keysym) {
         case kKey_Left:
            if (cx > 0) --cx;
            break;
         case kKey_Right:
            if (cx < fCols - 1) ++cx;
            break;
         case kKey_Up:
            if (cy > 0) --cy;
            break;
         case kKey_Down:
            if (cy < fRows - 1) ++cy;
            break;
         case kKey_Home:
            cx = cy = 0;
            break;
         case kKey_End:
            cx = fCols - 1;
            cy = fRows - 1;
            break;
         default:
            break;
      }
      if (cx != fCx || cy != fCy) {
         DrawFocusHilite(kFALSE);
         fCx = cx;
         fCy = cy;
         DrawFocusHilite(kTRUE);
         SendMessage(fMsgWindow, MK_MSG(kC_COLORSEL, kCOL_CLICK), fWidgetId, 0);
         ColorSelected();
      }
   }
   return kTRUE;
}
void TGColorPalette::SetColors(ULong_t colors[])
{
   
   for (Int_t i = 0; i < fRows * fCols; ++i)
      SetColor(i, colors[i]);
   gClient->NeedRedraw(this);
}
void TGColorPalette::SetColor(Int_t ix, ULong_t color)
{
   
   fPixels[ix] = color;
   gClient->NeedRedraw(this);
}
void TGColorPalette::SetCurrentCellColor(ULong_t color)
{
   
   SetColor(fCy * fCols + fCx, color);
}
void TGColorPalette::SetCellSize(Int_t w, Int_t h)
{
   
   fCw = w;
   fCh = h;
   gClient->NeedRedraw(this);
}
ULong_t TGColorPalette::GetCurrentColor() const
{
   
   if (fCx >= 0 && fCy >= 0)
      return GetColorByIndex(fCy * fCols + fCx);
   else
      return TColor::RGB2Pixel(0, 0, 0);
}
void TGColorPalette::DoRedraw()
{
   
   Int_t i, j, k, x, y;
   k = 0;
   y = 2;
   for (i = 0; i < fRows; ++i) {
      x = 2;
      for (j = 0; j < fCols; ++j) {
         Draw3dRectangle(kSunkenFrame | kDoubleBorder, x, y, fCw, fCh);
         fDrawGC.SetForeground(fPixels[k++]);
         gVirtualX->FillRectangle(fId, fDrawGC(), x + 2, y + 2, fCw - 4, fCh - 4);
         x += fCw + 5;
      }
      y += fCh + 5;
   }
   DrawFocusHilite(kTRUE);
}
void TGColorPalette::GotFocus()
{
   
   AddInput(kKeyPressMask | kKeyReleaseMask);
}
void TGColorPalette::LostFocus()
{
   
   RemoveInput(kKeyPressMask | kKeyReleaseMask);
   gClient->NeedRedraw(this);
}
void TGColorPalette::DrawFocusHilite(Int_t onoff)
{
   
   if (fCx >= 0 && fCy >= 0) {
      GContext_t gc = onoff ? GetShadowGC()() : GetBckgndGC()();
      gVirtualX->DrawRectangle(fId, gc, fCx * (fCw + 5) + 0, fCy * (fCh + 5) + 0,
                               fCw + 3, fCh + 3);
   }
}
TGColorPick::TGColorPick(const TGWindow *p, Int_t w, Int_t h, Int_t id) :
   TGFrame(p, w, h, kChildFrame), fCursorGC(GetBlackGC())
{
   
   
   
   
   
   UInt_t iw, ih;
   fWidgetId    = id;
   fWidgetFlags = kWidgetIsEnabled;
   fMsgWindow   = p;
   fColormapRect.fX = 1;
   fColormapRect.fY = 1;
   fColormapRect.fWidth = w - 33 - 2;
   fColormapRect.fHeight = h - 2;
   fSliderRect.fX = w - 18 - 2;
   fSliderRect.fY = 1;
   fSliderRect.fWidth = 10;
   fSliderRect.fHeight = h - 2;
   fNColors = 0;
   if (!p) {
      MakeZombie();
      return;
   }
   CreateImages();
   gVirtualX->GetImageSize(fLimage, iw, ih);
   fCx = 0;
   fCy = 0;
   fCz = (Int_t)ih / 2;
   fClick = kCLICK_NONE;
   UpdateCurrentColor();
   InitImages();
   gVirtualX->GrabButton(fId, kAnyButton, kAnyModifier,
                         kButtonPressMask | kButtonReleaseMask |
                         kPointerMotionMask, kNone, kNone);
   AddInput(kKeyPressMask | kEnterWindowMask | kLeaveWindowMask |
            kFocusChangeMask | kStructureNotifyMask);
   fEditDisabled = kEditDisable;
}
TGColorPick::~TGColorPick()
{
   
   if (IsZombie()) return;
   gVirtualX->DeleteImage(fHSimage);
   gVirtualX->DeleteImage(fLimage);
   FreeColors();
}
Bool_t TGColorPick::HandleButton(Event_t *event)
{
   
   if (event->fCode != kButton1) return kFALSE;
   if (event->fType == kButtonPress) {
      if ((event->fX > fColormapRect.fX) && (event->fX < fColormapRect.fX + fColormapRect.fWidth) &&
          (event->fY > fColormapRect.fY) && (event->fY < fColormapRect.fY + fColormapRect.fHeight)) {
         fClick = kCLICK_HS;
         SetHScursor(event->fX - fColormapRect.fX, event->fY - fColormapRect.fY);
      } else if (event->fX > fSliderRect.fX) {
         fClick = kCLICK_L;
         SetLcursor(event->fY - fSliderRect.fY);
      }
   } else {  
      fClick = kCLICK_NONE;
   }
   UpdateCurrentColor();
   if (fClick == kCLICK_HS) SetSliderColor();
   SendMessage(fMsgWindow, MK_MSG(kC_COLORSEL, kCOL_CLICK), fWidgetId, kFALSE);
   ColorSelected();
   return kTRUE;
}
Bool_t TGColorPick::HandleMotion(Event_t *event)
{
   
   if (!IsEnabled())
      return kTRUE;
   if (fClick == kCLICK_HS) {
      SetHScursor(event->fX - fColormapRect.fX, event->fY - fColormapRect.fY);
   } else if (fClick == kCLICK_L) {
      SetLcursor(event->fY - fSliderRect.fY);
   } else {
      return kTRUE;
   }
   UpdateCurrentColor();
   if (fClick == kCLICK_HS) SetSliderColor();
   SendMessage(fMsgWindow, MK_MSG(kC_COLORSEL, kCOL_CLICK), fWidgetId, kFALSE);
   ColorSelected();
   return kTRUE;
}
void TGColorPick::CreateImages()
{
   
   UInt_t width, height;
   width = fColormapRect.fWidth;
   height = fColormapRect.fHeight;
   fHSimage = gVirtualX->CreateImage(width, height);
   width = fSliderRect.fWidth;
   height = fSliderRect.fHeight;
   fLimage = gVirtualX->CreateImage(width, height);
}
void TGColorPick::AllocColors()
{
   
   
   ColorStruct_t color;
   Int_t i;
   for (i = 0; i < 64; ++i) {
      Int_t cc[4] = { 0, 21845, 43691, 65535 };
      color.fPixel = 0;
      color.fRed   = cc[i & 0x3];
      color.fGreen = cc[(i >> 2) & 0x3];
      color.fBlue  = cc[(i >> 4) & 0x3];
      if (gVirtualX->AllocColor(gVirtualX->GetColormap(), color) == 0)
         break;
      fColormap[i][0] = color.fRed / 256;
      fColormap[i][1] = color.fGreen / 256;
      fColormap[i][2] = color.fBlue / 256;
      fPixel[i] = color.fPixel;
   }
   fNColors = i;
   if (fNColors == 64) return;  
   
   FreeColors();
   for (i = 0; i < 27; ++i) {
      Int_t cc[3] = { 0, 32768, 65535 };
      color.fPixel = 0;
      color.fRed   = cc[i % 3];
      color.fGreen = cc[(i / 3) % 3];
      color.fBlue  = cc[(i / 9) % 3];
      if (gVirtualX->AllocColor(gVirtualX->GetColormap(), color) == 0)
         break;
      fColormap[i][0] = color.fRed / 256;
      fColormap[i][1] = color.fGreen / 256;
      fColormap[i][2] = color.fBlue / 256;
      fPixel[i] = color.fPixel;
   }
   fNColors = i;
   if (fNColors == 27) return;  
   
   FreeColors();
   for (i = 0; i < 8; ++i) {
      color.fPixel = 0;
      color.fRed   = (i & 1) * 65535;
      color.fGreen = ((i >> 1) & 1) * 65535;
      color.fBlue  = ((i >> 2) & 1) * 65535;
      if (gVirtualX->AllocColor(gVirtualX->GetColormap(), color) == 0)
         break;
      fColormap[i][0] = color.fRed / 256;
      fColormap[i][1] = color.fGreen / 256;
      fColormap[i][2] = color.fBlue / 256;
      fPixel[i] = color.fPixel;
   }
   fNColors = i;
   if (fNColors == 8) return;  
   
   
   
   FreeColors();
   for (i = 0; i < 8; ++i) {
      color.fPixel = 0;
      color.fRed   = (i & 1) * 65535;
      color.fGreen = ((i >> 1) & 1) * 65535;
      color.fBlue  = ((i >> 2) & 1) * 65535;
      if (gVirtualX->AllocColor(gVirtualX->GetColormap(), color) != 0) {
         fColormap[fNColors][0] = color.fRed / 256;
         fColormap[fNColors][1] = color.fGreen / 256;
         fColormap[fNColors][2] = color.fBlue / 256;
         fPixel[fNColors++] = color.fPixel;
      }
   }
   
}
void TGColorPick::FreeColors()
{
   
   for (Int_t i = 0; i < fNColors; i++)
      gVirtualX->FreeColor(gVirtualX->GetColormap(), fPixel[i]);
   fNColors = 0;
}
void TGColorPick::CreateDitheredImage(Pixmap_t image, Int_t which)
{
   
   
   
   
   const Int_t kWidth = 20;
   ColorStruct_t line[kWidth];
   struct { Int_t r, g, b; } ed[kWidth], ef;
   Int_t  x, y, c, v, e[4], nc = 0;
   Int_t  r, g, b;
   Int_t h, l, s;
   Long_t dist, sdist;
   Int_t iw, ih;
   gVirtualX->GetImageSize(image, (UInt_t&) iw, (UInt_t&) ih);
   for (x = 0; x < iw; ++x) {
      ed[x].r = ed[x].g = ed[x].b = 0;
   }
   if (fNColors == 0) AllocColors();
   for (y = 0; y < ih; ++y) {
      if (which == kIMG_HS) {
         for (x = 0; x < iw; ++x) {
            h = x * 255 / iw;
            l = 128;
            s = (ih - y) * 255 / ih;
            TColor::HLS2RGB(h, l, s, r, g, b);
            line[x].fRed   = r;
            line[x].fGreen = g;
            line[x].fBlue  = b;
         }
      } else if (which == kIMG_L) {
         TColor::Pixel2RGB(fCurrentColor, r, g, b);
         TColor::RGB2HLS(r, g, b, h, l, s);
         Int_t l = (ih - y) * 255 / ih;
         TColor::HLS2RGB(h, l, s, r, g, b);
         for (Int_t x = 0; x < iw; ++x) {
            line[x].fRed   = r;
            line[x].fGreen = g;
            line[x].fBlue  = b;
         }
      } else {
         return;
      }
      ef.r = ef.g = ef.b = 0;        
      for (x = 0; x < iw; ++x) {
         
         v = line[x].fRed + ed[x].r;
         if (v < 0) v = 0; else if (v > 255) v = 255;
         line[x].fRed = v;
         v = line[x].fGreen + ed[x].g;
         if (v < 0) v = 0; else if (v > 255) v = 255;
         line[x].fGreen = v;
         v = line[x].fBlue + ed[x].b;
         if (v < 0) v = 0; else if (v > 255) v = 255;
         line[x].fBlue = v;
      }
      for (x = 0; x < iw; ++x) {
         
         v = line[x].fRed + ef.r;
         if (v < 0) v = 0; else if (v > 255) v = 255;
         line[x].fRed = v;
         v = line[x].fGreen + ef.g;
         if (v < 0) v = 0; else if (v > 255) v = 255;
         line[x].fGreen = v;
         v = line[x].fBlue + ef.b;
         if (v < 0) v = 0; else if (v > 255) v = 255;
         line[x].fBlue = v;
         
         sdist = 255L * 255L * 255L;
         for (c = 0; c < fNColors; ++c) {
            Int_t dr = line[x].fRed   - fColormap[c][0];
            Int_t dg = line[x].fGreen - fColormap[c][1];
            Int_t db = line[x].fBlue  - fColormap[c][2];
            dist = dr * dr + dg * dg + db * db;
            if (dist < sdist) {
               nc = c;
               sdist = dist;
            }
         }
         gVirtualX->PutPixel(image, x, y, fPixel[nc]);
#define FILTER(v) \
      e[0] = (7 * v) >> 4; \
      e[1] = v >> 4;       \
      e[2] = (5 * v) >> 4; \
      e[3] = (3 * v) >> 4;
         v = line[x].fRed - fColormap[nc][0];
         FILTER(v)
         ef.r = e[0];
         if (x < iw-1) ed[x+1].r = e[1];
         if (x == 0) ed[x].r = e[2]; else ed[x].r += e[2];
         if (x > 0) ed[x-1].r += e[3];
         v = line[x].fGreen - fColormap[nc][1];
         FILTER(v)
         ef.g = e[0];
         if (x < iw-1) ed[x+1].g = e[1];
         if (x == 0) ed[x].g = e[2]; else ed[x].g += e[2];
         if (x > 0) ed[x-1].g += e[3];
         v = line[x].fBlue - fColormap[nc][2];
         FILTER(v)
         ef.b = e[0];
         if (x < iw-1) ed[x+1].b = e[1];
         if (x == 0) ed[x].b = e[2]; else ed[x].b += e[2];
         if (x > 0) ed[x-1].b += e[3];
      }
   }
}
void TGColorPick::InitImages()
{
   
   Int_t width, height;
   Int_t h, l, s;
   Int_t r, g, b;
   gVirtualX->GetImageSize(fHSimage, (UInt_t&) width, (UInt_t&) height);
   
   Int_t ncolors = gVirtualX->GetDepth();
   if (ncolors > 8) {
      for (Int_t y = 0; y < height; ++y) {
         for (Int_t x = 0; x < width; ++x) {
            r = g = b = 0;
            h = x * 255 / width;
            l = 128;
            s = (height - y) * 255 / height;
            TColor::HLS2RGB(h, l, s, r, g, b);
            ULong_t pixel = TColor::RGB2Pixel(r, g, b);
            gVirtualX->PutPixel(fHSimage, x, y, pixel);
         }
      }
   } else {
      CreateDitheredImage(fHSimage, kIMG_HS);
   }
   
   SetSliderColor();
}
void TGColorPick::SetSliderColor()
{
   
   Int_t width, height;
   Int_t h, l, s;
   Int_t r, g, b;
   gVirtualX->GetImageSize(fLimage, (UInt_t&) width, (UInt_t&) height);
   Int_t ncolors = gVirtualX->GetDepth();
   if (ncolors > 8) {
      for (Int_t y = 0; y < height; ++y) {
         TColor::Pixel2RGB(fCurrentColor, r, g, b);
         TColor::RGB2HLS(r, g, b, h, l, s);
         l = (height - y) * 255 / height;
         TColor::HLS2RGB(h, l, s, r, g, b);
         ULong_t pixel = TColor::RGB2Pixel(r, g, b);
         for (Int_t x = 0; x < width; ++x) {
            gVirtualX->PutPixel(fLimage, x, y, pixel);
         }
      }
   } else {
      CreateDitheredImage(fLimage, kIMG_L);
   }
   gClient->NeedRedraw(this);
}
void TGColorPick::SetColor(ULong_t color)
{
   
   UInt_t width, height;
   Int_t h, l, s;
   Int_t r, g, b;
   gVirtualX->GetImageSize(fHSimage, width, height);
   fCurrentColor = color;
   TColor::Pixel2RGB(fCurrentColor, r, g, b);
   TColor::RGB2HLS(r, g, b, h, l, s);
   SetHScursor(h * (Int_t)width / 256, (255 - s) * (Int_t)height / 256);
   gVirtualX->GetImageSize(fLimage, width, height);
   SetLcursor((255 - l) * (Int_t)height / 256);
   SetSliderColor();
}
void TGColorPick::UpdateCurrentColor()
{
   
   UInt_t lwidth, lheight;
   UInt_t swidth, sheight;
   Int_t r, g, b;
   Int_t h, l, s;
   gVirtualX->GetImageSize(fLimage, lwidth, lheight);
   gVirtualX->GetImageSize(fHSimage, swidth, sheight);
   h = Int_t(fCx * 255 / swidth);
   l = Int_t((lheight - fCz) * 255 / lheight);
   s = Int_t((sheight - fCy) * 255 / sheight);
   TColor::HLS2RGB(h, l, s, r, g, b);
   fCurrentColor = TColor::RGB2Pixel(r, g, b);
}
void TGColorPick::DoRedraw()
{
   
   UInt_t lwidth, lheight;
   UInt_t swidth, sheight;
   gVirtualX->GetImageSize(fLimage, lwidth, lheight);
   gVirtualX->GetImageSize(fHSimage, swidth, sheight);
   DrawBorder();
   Draw3dRectangle(kSunkenFrame, fColormapRect.fX - 1, fColormapRect.fY - 1,
                   fColormapRect.fWidth + 2, fColormapRect.fHeight + 2);
   gVirtualX->PutImage(fId, GetBckgndGC()(), fHSimage,
                       fColormapRect.fX, fColormapRect.fY, 0, 0, swidth, sheight);
   Draw3dRectangle(kSunkenFrame, fSliderRect.fX - 1, fSliderRect.fY - 1,
                   fSliderRect.fWidth + 2, fSliderRect.fHeight + 2);
   gVirtualX->PutImage(fId, GetBckgndGC()(), fLimage,
                       fSliderRect.fX, fSliderRect.fY, 0, 0, lwidth, lheight);
   DrawHScursor(kTRUE);
   DrawLcursor(kTRUE);
}
void TGColorPick::SetHScursor(Int_t x, Int_t y)
{
   
   UInt_t width, height;
   gVirtualX->GetImageSize(fHSimage, width, height);
   DrawHScursor(kFALSE);
   fCx = x;
   fCy = y;
   if (fCx < 0)
      fCx = 0;
   else if (fCx >= (Int_t)width)
      fCx = (Int_t)width - 1;
   if (fCy < 0)
      fCy = 0;
   else if (fCy >= (Int_t)height)
      fCy = (Int_t)height - 1;
   DrawHScursor(kTRUE);
}
void TGColorPick::SetLcursor(Int_t z)
{
   
   UInt_t width, height;
   gVirtualX->GetImageSize(fLimage, width, height);
   DrawLcursor(kFALSE);
   fCz = z - fSliderRect.fY;
   if (fCz < 0)
      fCz = 0;
   else if (fCz >= (Int_t)height)
      fCz = (Int_t)height - 1;
   DrawLcursor(kTRUE);
}
void TGColorPick::DrawHScursor(Int_t onoff)
{
   
   UInt_t width, height;
   gVirtualX->GetImageSize(fHSimage, width, height);
   if (onoff) {
      Int_t x, y;
      Rectangle_t rect;
      x = fCx + fColormapRect.fX;
      y = fCy + fColormapRect.fY;
      rect.fX = fColormapRect.fX;
      rect.fY = fColormapRect.fX;
      rect.fWidth = fColormapRect.fWidth;
      rect.fHeight = fColormapRect.fHeight;
      gVirtualX->SetClipRectangles(fCursorGC(), 0, 0, &rect, 1);
      gVirtualX->FillRectangle(fId, fCursorGC(), x - 9, y - 1, 5, 3);
      gVirtualX->FillRectangle(fId, fCursorGC(), x - 1, y - 9, 3, 5);
      gVirtualX->FillRectangle(fId, fCursorGC(), x + 5, y - 1, 5, 3);
      gVirtualX->FillRectangle(fId, fCursorGC(), x - 1, y + 5, 3, 5);
   } else {
      Int_t  x, y;
      UInt_t w, h;
      x = fCx - 9; w = 19;
      y = fCy - 9; h = 19;
      if (x < 0) { w += x; x = 0; }
      if (y < 0) { h += y; y = 0; }
      if (x + w > width) w = width - x;
      if (y + h > width) h = height - y;
      gVirtualX->PutImage(fId, GetBckgndGC()(), fHSimage, x, y,
                          fColormapRect.fX + x, fColormapRect.fY + y, w, h);
   }
}
void TGColorPick::DrawLcursor(Int_t onoff)
{
   
   Int_t l = fSliderRect.fX + fSliderRect.fWidth + 3;
   Int_t r = l + 5;
   Int_t t = fCz - 5 + fSliderRect.fY;
   Int_t b = t + 10;
   Point_t points[3];
   Int_t m = (t + b) >> 1;
   points[0].fX = r;
   points[0].fY = t;
   points[1].fX = r;
   points[1].fY = b;
   points[2].fX = l;
   points[2].fY = m;
   GContext_t gc = onoff ? GetShadowGC()() : GetBckgndGC()();
   gVirtualX->FillPolygon(fId, gc, points, 3);
}
TGColorDialog::TGColorDialog(const TGWindow *p, const TGWindow *m,
                             Int_t *retc, ULong_t *color, Bool_t wait) :
   TGTransientFrame(p, m, 200, 150)
{
   
   
   
   const Int_t kC_X = 175;  
   const Int_t kC_Y = 180;  
   Int_t i;
   fRetc = retc;
   fRetColor = color;
   fWaitFor = wait;
   fInitColor = *fRetColor;
   if (fRetc) *fRetc = kMBCancel;
   TGHorizontalFrame *hftop = new TGHorizontalFrame(this, 10, 10);
   hftop->SetCleanup();
   AddFrame(hftop, new TGLayoutHints(kLHintsTop | kLHintsLeft, 5, 5, 10, 5));
   fTab = new TGTab(hftop, 300, 300);
   hftop->AddFrame(fTab);
   TGCompositeFrame *cf = new TGCompositeFrame(hftop, 10, 10);
   cf->SetCleanup();
   hftop->AddFrame(cf, new TGLayoutHints(kLHintsLeft | kLHintsTop, 5, 0, 30, 0));
   TGCompositeFrame *cf1 = new TGCompositeFrame(cf, 10, 10);
   cf1->SetCleanup();
   cf->AddFrame(cf1, new TGLayoutHints(kLHintsLeft | kLHintsTop, 5, 0, 30, 0));
   cf1->SetLayoutManager(new TGMatrixLayout(cf1, 0, 2, 4));
   cf1->AddFrame(new TGLabel(cf1, new TGHotString("Red:")));
   cf1->AddFrame(fRte = new TGTextEntry(cf1, fRtb = new TGTextBuffer(5), kCDLG_RTE),0);
   fRte->Resize(40, fRte->GetDefaultHeight());
   cf1->AddFrame(new TGLabel(cf1, new TGHotString("Green:")),0);
   cf1->AddFrame(fGte = new TGTextEntry(cf1, fGtb = new TGTextBuffer(5), kCDLG_GTE),0);
   fGte->Resize(40, fGte->GetDefaultHeight());
   cf1->AddFrame(new TGLabel(cf1, new TGHotString("Blue:")));
   cf1->AddFrame(fBte = new TGTextEntry(cf1, fBtb = new TGTextBuffer(5), kCDLG_BTE),0);
   fBte->Resize(40, fBte->GetDefaultHeight());
   TGCompositeFrame *cf2 = new TGCompositeFrame(cf, 10, 10);
   cf2->SetCleanup();
   cf->AddFrame(cf2, new TGLayoutHints(kLHintsLeft | kLHintsTop, 5, 0, 30, 0));
   cf2->SetLayoutManager(new TGMatrixLayout(cf2, 0, 2, 4));
   cf2->AddFrame(new TGLabel(cf2, new TGHotString("Hue:")),0);
   cf2->AddFrame(fHte = new TGTextEntry(cf2, fHtb = new TGTextBuffer(5), kCDLG_HTE),0);
   fHte->Resize(40, fHte->GetDefaultHeight());
   cf2->AddFrame(new TGLabel(cf2, new TGHotString("Sat:")),0);
   cf2->AddFrame(fSte = new TGTextEntry(cf2, fStb = new TGTextBuffer(5), kCDLG_STE),0);
   fSte->Resize(40, fSte->GetDefaultHeight());
   cf2->AddFrame(new TGLabel(cf2, new TGHotString("Lum:")),0);
   cf2->AddFrame(fLte = new TGTextEntry(cf2, fLtb = new TGTextBuffer(5), kCDLG_LTE),0);
   fLte->Resize(40, fLte->GetDefaultHeight());
   fHte->Associate(this);
   fLte->Associate(this);
   fSte->Associate(this);
   fRte->Associate(this);
   fGte->Associate(this);
   fBte->Associate(this);
   if (color) {
      UpdateRGBentries(color);
      UpdateHLSentries(color);
      fCurrentColor = *color;
   } else {
      gClient->GetColorByName("red", fCurrentColor);
   }
   
   
   TGCompositeFrame *cf3 = new TGCompositeFrame(cf, 10, 10);
   cf3->SetCleanup();
   cf3->SetLayoutManager(new TGMatrixLayout(cf3, 0, 1, 0));
   cf3->AddFrame(fColorInfo = new TGLabel(cf3, new TGString("New: not set         ")),0);
   fColorInfo->SetTextJustify(kTextLeft);
   cf3->AddFrame(fSample = new TGFrame(cf3, 50, 25, kOwnBackground),0);
   cf3->AddFrame(fSampleOld = new TGFrame(cf3, 50, 25, kOwnBackground),0);
   cf3->AddFrame(new TGLabel(cf3, new TGString("Current")),0);
   cf->AddFrame(cf3, new TGLayoutHints(kLHintsLeft | kLHintsTop, 5, 5, 20, 0));
   fSample->SetBackgroundColor(fCurrentColor);
   fSampleOld->SetBackgroundColor(fCurrentColor);
   TGCompositeFrame *tf = fTab->AddTab("Color Wheel");
   TGCompositeFrame *tf1 = new TGCompositeFrame(tf, 60, 20, kHorizontalFrame);
   tf->AddFrame(tf1);
   fEcanvas = new TRootEmbeddedCanvas("wheel", tf1, 360, 360);
   tf1->AddFrame(fEcanvas);
   TCanvas *wcan = fEcanvas->GetCanvas();
   wcan->SetBit(kNoContextMenu);
   fColorWheel = new TColorWheel();
   fColorWheel->SetCanvas(wcan);
   fColorWheel->Draw();
   wcan->Update();
   wcan->Connect("ProcessedEvent(Int_t,Int_t,Int_t,TObject*)","TGColorDialog",this, 
                 "SetColorInfo(Int_t,Int_t,Int_t,TObject*)");
   tf = fTab->AddTab("Basic Colors");
   TGCompositeFrame *tf2 = new TGCompositeFrame(tf, 60, 20, kHorizontalFrame);
   tf->AddFrame(tf2);
   TGVerticalFrame *vf1 = new TGVerticalFrame(tf2, 20, 20);
   vf1->SetCleanup();
   TGVerticalFrame *vf2 = new TGVerticalFrame(tf2, 20, 20);
   vf2->SetCleanup();
   tf2->AddFrame(vf1, new TGLayoutHints(kLHintsLeft | kLHintsExpandY));
   tf2->AddFrame(vf2, new TGLayoutHints(kLHintsLeft | kLHintsExpandY));
   
   
   fPalette = new TGColorPalette(vf1, 6, 8, kCDLG_SPALETTE);
   vf1->AddFrame(fPalette, new TGLayoutHints(kLHintsNormal, 5, 5, 15, 0));
   fPalette->Associate(this);
   for (i = 0; i < 48; ++i)
      fPalette->SetColor(i, TColor::Number2Pixel(i+10));  
      
      
   
   fPalette->SetColor(47, TGFrame::GetDefaultFrameBackground());
   Float_t r, g, b;
   r = 232./255;
   g = 232./255;
   b = 222./255;
   
   Pixel_t pixel = TColor::RGB2Pixel(r, g, b);
   fPalette->SetColor(46, pixel);
   r = 230./255;
   g = 230./255;
   b = 230./255;
   
   pixel = TColor::RGB2Pixel(r, g, b);
   fPalette->SetColor(45, pixel);
   r = 172./255;
   g = 174./255;
   b = 205./255;
   
   pixel = TColor::RGB2Pixel(r, g, b);
   fPalette->SetColor(44, pixel);
   r = 205./255;
   g = 195./255;
   b = 175./255;
   
   pixel = TColor::RGB2Pixel(r, g, b);
   fPalette->SetColor(43, pixel);
   
   vf1->AddFrame(new TGLabel(vf1, new TGHotString("&Custom Colors:")),
                 new TGLayoutHints(kLHintsNormal, 5, 0, 15, 2));
   fCpalette = new TGColorPalette(vf1, 6, 4, kCDLG_CPALETTE);
   vf1->AddFrame(fCpalette, new TGLayoutHints(kLHintsNormal, 5, 5, 5, 0));
   fCpalette->Associate(this);
   if (gUcolor[0] == 0xff000000) {
      for (i = 0; i < 24; i++)
         gUcolor[i] = TColor::RGB2Pixel(255, 255, 255);
   }
   fCpalette->SetColors(gUcolor);
   
   TGHorizontalFrame *hf = new TGHorizontalFrame(this, 10, 10, kFixedWidth);
   hf->SetCleanup();
   AddFrame(hf, new TGLayoutHints(kLHintsBottom | kLHintsRight, 5, 5, 10, 5));
   TGTextButton *ok = new TGTextButton(hf, new TGHotString("OK"), kCDLG_OK);
   TGTextButton *cancel = new TGTextButton(hf, new TGHotString("Cancel"), kCDLG_CANCEL);
   TGTextButton *fPreview = new TGTextButton(hf, new TGHotString("&Preview"), kCDLG_PREVIEW);
   fPreview->Connect("Clicked()", "TGColorDialog", this, "DoPreview()");
   
   hf->AddFrame(ok, new TGLayoutHints(kLHintsBottom | kLHintsExpandX, 0, 3, 0, 0));
   hf->AddFrame(cancel, new TGLayoutHints(kLHintsBottom | kLHintsExpandX,3, 0, 0, 0));
   hf->AddFrame(fPreview, new TGLayoutHints(kLHintsBottom | kLHintsExpandX,3, 0, 0, 0));
   UInt_t w = ok->GetDefaultWidth();
   w = TMath::Max(w, cancel->GetDefaultWidth());
   hf->Resize(3 * (w + 30), hf->GetDefaultHeight());
   ok->Associate(this);
   cancel->Associate(this);
   
   
   fColors = new TGColorPick(vf2, kC_X + 23, kC_Y, kCDLG_COLORPICK);
   vf2->AddFrame(fColors, new TGLayoutHints(kLHintsLeft | kLHintsTop, 5, 0, 15, 5));
   fColors->Associate(this);
   if (color)
      fColors->SetColor(*color);
   TGTextButton *add = new TGTextButton(vf2, new TGHotString("&Add to Custom Colors"),
                                        kCDLG_ADD);
   vf2->AddFrame(add, new TGLayoutHints(kLHintsBottom | kLHintsExpandX,
                                        5, 10, 0, 5));
   add->Associate(this);
   MapSubwindows();
   Resize(GetDefaultSize());
   SetEditDisabled(kEditDisable);
   
   SetWMSize(fWidth, fHeight);
   SetWMSizeHints(fWidth, fHeight, fWidth, fHeight, 0, 0);
   SetWindowName("Color Selector");
   SetIconName("Color Selector");
   SetClassHints("ColorSelector", "ColorSelector");
   SetMWMHints(kMWMDecorAll | kMWMDecorResizeH | kMWMDecorMaximize |
                              kMWMDecorMinimize | kMWMDecorMenu,
               kMWMFuncAll  | kMWMFuncResize    | kMWMFuncMaximize |
                              kMWMFuncMinimize,
               kMWMInputModeless);
   
   if (fClient->IsEditable()) {
      const TGWindow *main = fMain;
      fMain = fClient->GetRoot();
      CenterOnParent(kTRUE, TGTransientFrame::kRight);
      fMain = main;
   } else {
      CenterOnParent();
   }
   if (fWaitFor) {
      MapWindow();
      fClient->WaitForUnmap(this);
      DeleteWindow();
   }
}
TGColorDialog::~TGColorDialog()
{
   
   
   fEcanvas->GetCanvas()->Disconnect("ProcessedEvent(Int_t,Int_t,Int_t,TObject*)");
   delete fEcanvas; 
   Cleanup();
}
void TGColorDialog::SetCurrentColor(Pixel_t col)
{
   
   if (fCurrentColor == col) {
      return;
   }
   fInitColor = *fRetColor = col;
   fCurrentColor = col;
   fColors->SetColor(col);
   fSample->SetBackgroundColor(col);
   ColorSelected(col);
}
void TGColorDialog::ColorSelected(Pixel_t color)
{
   
   Emit("ColorSelected(Pixel_t)", color);
}
void TGColorDialog::CloseWindow()
{
   
   
   for (Int_t i = 0; i < 24; ++i)
      gUcolor[i] = fCpalette->GetColorByIndex(i);
   if (*fRetc != kMBOk) {
      ColorSelected(fInitColor);
   } else {
      ColorSelected(*fRetColor);
   }
   
   
   UnmapWindow();
}
void TGColorDialog::UpdateRGBentries(ULong_t *c)
{
   
   Char_t tmp[20];
   Int_t r, g, b;
   TColor::Pixel2RGB(*c, r, g, b);
   sprintf(tmp, "%d", r);
   fRtb->Clear();
   fRtb->AddText(0, tmp);
   gClient->NeedRedraw(fRte);
   sprintf(tmp, "%d", g);
   fGtb->Clear();
   fGtb->AddText(0, tmp);
   gClient->NeedRedraw(fGte);
   sprintf(tmp, "%d", b);
   fBtb->Clear();
   fBtb->AddText(0, tmp);
   gClient->NeedRedraw(fBte);
}
void TGColorDialog::UpdateHLSentries(ULong_t *c)
{
   
   Char_t tmp[20];
   Int_t h, l, s;
   Int_t r, g, b;
   TColor::Pixel2RGB(*c, r, g, b);
   TColor::RGB2HLS(r, g, b, h, l, s);
   sprintf(tmp, "%d", h);
   fHtb->Clear();
   fHtb->AddText(0, tmp);
   gClient->NeedRedraw(fHte);
   sprintf(tmp, "%d", l);
   fLtb->Clear();
   fLtb->AddText(0, tmp);
   gClient->NeedRedraw(fLte);
   sprintf(tmp, "%d", s);
   fStb->Clear();
   fStb->AddText(0, tmp);
   gClient->NeedRedraw(fSte);
}
Bool_t TGColorDialog::ProcessMessage(Long_t msg, Long_t parm1, Long_t )
{
   
   ULong_t color;
   Int_t h, l, s;
   Int_t r, g, b;
   switch (GET_MSG(msg)) {
      case kC_COMMAND:
         switch (GET_SUBMSG(msg)) {
            case kCM_BUTTON:
               switch(parm1) {
                  case kCDLG_ADD:
                     fCpalette->SetCurrentCellColor(fCurrentColor);
                     break;
                  case kCDLG_OK:
                     *fRetc = kMBOk;
                     *fRetColor = TColor::RGB2Pixel(atoi(fRtb->GetString()),
                                                    atoi(fGtb->GetString()),
                                                    atoi(fBtb->GetString()));
                     CloseWindow();
                     break;
                  case kCDLG_CANCEL:
                     if (!fClient->IsEditable()) {
                        TGColorPopup *p = (TGColorPopup *)GetMain();
                        p->PreviewColor(fSampleOld->GetBackground());
                     }
                     CloseWindow();
                     break;
               }
               break;
         }
         break;
      case kC_COLORSEL:
         switch (GET_SUBMSG(msg)) {
            case kCOL_CLICK:
               switch (parm1) {
                  case kCDLG_SPALETTE:
                     color = fPalette->GetCurrentColor();
                     fSample->SetBackgroundColor(color);
                     ColorSelected(color);
                     gClient->NeedRedraw(fSample);
                     fCurrentColor = color;
                     fColors->SetColor(color);
                     UpdateRGBentries(&color);
                     UpdateHLSentries(&color);
                     break;
                  case kCDLG_CPALETTE:
                     color = fCpalette->GetCurrentColor();
                     fSample->SetBackgroundColor(color);
                     ColorSelected(color);
                     gClient->NeedRedraw(fSample);
                     fCurrentColor = color;
                     fColors->SetColor(color);
                     UpdateRGBentries(&color);
                     UpdateHLSentries(&color);
                     break;
                  case kCDLG_COLORPICK:
                     color = fColors->GetCurrentColor();
                     fSample->SetBackgroundColor(color);
                     ColorSelected(color);
                     gClient->NeedRedraw(fSample);
                     fCurrentColor = color;
                     UpdateRGBentries(&color);
                     UpdateHLSentries(&color);
                     break;
               }
               break;
         }
         break;
      case kC_TEXTENTRY:
         switch (GET_SUBMSG(msg)) {
            case kTE_TEXTCHANGED:
               switch (parm1) {
                  case kCDLG_HTE:
                  case kCDLG_LTE:
                  case kCDLG_STE:
                     h = atoi(fHtb->GetString());
                     l = atoi(fLtb->GetString());
                     s = atoi(fStb->GetString());
                     TColor::HLS2RGB(h, l, s, r, g, b);
                     color = TColor::RGB2Pixel(r, g, b);
                     fSample->SetBackgroundColor(color);
                     ColorSelected(color);
                     gClient->NeedRedraw(fSample);
                     fCurrentColor = color;
                     fColors->SetColor(color);
                     UpdateRGBentries(&color);
                     break;
                  case kCDLG_RTE:
                  case kCDLG_GTE:
                  case kCDLG_BTE:
                     color = TColor::RGB2Pixel(atoi(fRtb->GetString()),
                                               atoi(fGtb->GetString()),
                                               atoi(fBtb->GetString()));
                     fSample->SetBackgroundColor(color);
                     ColorSelected(color);
                     gClient->NeedRedraw(fSample);
                     fCurrentColor = color;
                     fColors->SetColor(color);
                     UpdateHLSentries(&color);
                     break;
               }
               break;
         }
         break;
   }
   
   return kTRUE;
}
void TGColorDialog::SetColorInfo(Int_t event, Int_t px, Int_t py, TObject *object)
{
   
   if (object == fColorWheel) {
      Int_t n = fColorWheel->GetColor(px,py);
      if (n < 0) return;
      TColor *color = gROOT->GetColor(n);
      if (!color) return;
      ULong_t pcolor = color->GetPixel();
      if (event == kButton1Down) {
         UpdateRGBentries(&pcolor);
         UpdateHLSentries(&pcolor);
         fSample->SetBackgroundColor(pcolor);
         fColorInfo->SetText(Form("New: %s",color->GetName()));
         gClient->NeedRedraw(fSample);
         gClient->NeedRedraw(fColorInfo);
         fCurrentColor = pcolor;
         fColors->SetColor(pcolor);
         ColorSelected(pcolor);
      }
   }
}
void TGColorDialog::DoPreview()
{
   
   if (fClient->IsEditable()) {
      ColorSelected(fSample->GetBackground());
      return;
   }
   TGColorPopup *p = (TGColorPopup *)GetMain();
   p->PreviewColor(fSample->GetBackground());
}
This page has been automatically generated. If you have any comments or suggestions about the page layout send a mail to ROOT support, or contact the developers with any questions or problems regarding ROOT.