Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2023-10-25 09:46:24

0001 /*
0002     All access to this colour picker goes through FWColorSelect.
0003     Widget creation: new FWColorSelect(p, n, col, cols, id)
0004                         p: parent window
0005                         n: the name of the popup
0006                       col: initially selected colour (in Pixel_t)
0007                      cols: a vector<Pixel_t> of colour values
0008                        id: window ID
0009 
0010     After creation, connect to signal method ColorSelected(Pixel_t) in
0011     FWColorSelect to receive colour changes.
0012  */
0013 #include <functional>
0014 
0015 #include "TGLayout.h"
0016 #include "TGClient.h"
0017 #include "TGGC.h"
0018 #include "TGColorDialog.h"
0019 #include "TColor.h"
0020 #include "TVirtualX.h"
0021 
0022 #include "Fireworks/Core/src/FWColorSelect.h"
0023 #include "Fireworks/Core/interface/FWColorManager.h"
0024 
0025 //------------------------------Constants------------------------------//
0026 
0027 enum FWCSelConstants {
0028   kCFWidth = 15,
0029   kCFPadLeft = 4,
0030   kCFPadAbove = 8,
0031   kCFHeight = 15,
0032   kCFPadRight = 4,
0033   kCFPadBelow = 8,
0034 
0035   kHLOffsetX = 3,
0036   kHLExtraWidth = 5,
0037   kHLOffsetY = 3,
0038   kHLExtraHeight = 5,
0039 
0040   kCROffsetX = 5,
0041   kCRPadAbove = 3,
0042   kCROffsetY = 5,
0043   kCRPadBelow = 6,
0044 
0045   kColorPopupGray = 0xcccccc
0046 };
0047 
0048 //------------------------------FWColorFrame------------------------------//
0049 
0050 FWColorFrame::FWColorFrame(const TGWindow *p, Color_t ci) : TGFrame(p, 20, 20, kOwnBackground) {
0051   SetColor(ci);
0052   Resize(kCFWidth, kCFHeight);
0053 }
0054 
0055 Bool_t FWColorFrame::HandleButton(Event_t *event) {
0056   if (event->fType == kButtonRelease) {
0057     ColorSelected(fColor);
0058   }
0059   return kTRUE;
0060 }
0061 
0062 void FWColorFrame::SetColor(Color_t ci) {
0063   fColor = ci;
0064   SetBackgroundColor(TColor::Number2Pixel(fColor));
0065 }
0066 
0067 void FWColorFrame::ColorSelected(Color_t ci) { Emit("ColorSelected(Color_t)", ci); }
0068 
0069 //------------------------------FWColorRow------------------------------//
0070 
0071 FWColorRow::FWColorRow(const TGWindow *p)
0072     : TGHorizontalFrame(p, 10, 10, kOwnBackground, TGFrame::GetBlackPixel()), fBackgroundIsBlack(kTRUE) {
0073   fSelectedIndex = -1;
0074 }
0075 
0076 FWColorRow::~FWColorRow() { Cleanup(); }
0077 
0078 void FWColorRow::SetBackgroundToBlack(Bool_t toBlack) {
0079   fBackgroundIsBlack = toBlack;
0080   if (fBackgroundIsBlack) {
0081     SetBackgroundColor(TGFrame::GetBlackPixel());
0082   } else {
0083     SetBackgroundColor(TGFrame::GetWhitePixel());
0084   }
0085 }
0086 
0087 void FWColorRow::DoRedraw() {
0088   TGCompositeFrame::DoRedraw();
0089   DrawHighlight();
0090 }
0091 
0092 void FWColorRow::DrawHighlight() {
0093   if (fSelectedIndex >= 0) {
0094     Int_t x = fSelectedIndex * (fCc.at(fSelectedIndex)->GetWidth() + kCFPadLeft + kCFPadRight) + kCFPadLeft;
0095     Int_t y = kCFPadBelow;
0096     Int_t w = fCc.at(fSelectedIndex)->GetWidth();
0097     Int_t h = fCc.at(fSelectedIndex)->GetHeight();
0098     gVirtualX->DrawRectangle(
0099         fId, GetShadowGC()(), x - kHLOffsetX, y - kHLOffsetY, w + kHLExtraWidth, h + kHLExtraHeight);
0100   }
0101 }
0102 
0103 void FWColorRow::AddColor(Color_t color) {
0104   fCc.push_back(new FWColorFrame(this, color));
0105   AddFrame(fCc.back(),
0106            new TGLayoutHints(kLHintsCenterX | kLHintsCenterY, kCFPadLeft, kCFPadRight, kCFPadAbove, kCFPadBelow));
0107   fCc.back()->Connect("ColorSelected(Color_t)", "FWColorRow", this, "ColorChanged(Color_t)");
0108 }
0109 
0110 void FWColorRow::ResetColor(Int_t iIndex, Color_t iColor) { fCc[iIndex]->SetColor(iColor); }
0111 
0112 Int_t FWColorRow::FindColorIndex(Color_t iColor) const {
0113   Int_t returnValue = -1;
0114   Int_t index = 0;
0115   for (std::vector<FWColorFrame *>::const_iterator it = fCc.begin(), itEnd = fCc.end(); it != itEnd; ++it, ++index) {
0116     if ((*it)->GetColor() == iColor)
0117       return index;
0118   }
0119   return returnValue;
0120 }
0121 
0122 void FWColorRow::ColorChanged(Color_t ci) { Emit("ColorChanged(Color_t)", ci); }
0123 
0124 //------------------------------FWColorPopup------------------------------//
0125 
0126 Bool_t FWColorPopup::fgFreePalette = kFALSE;
0127 
0128 Bool_t FWColorPopup::HasFreePalette() { return fgFreePalette; }
0129 void FWColorPopup::EnableFreePalette() { fgFreePalette = kTRUE; }
0130 
0131 FWColorPopup::FWColorPopup(const TGWindow *p, Color_t color)
0132     : TGVerticalFrame(p, 10, 10, kDoubleBorder | kRaisedFrame | kOwnBackground, kColorPopupGray), fShowWheel(kFALSE) {
0133   SetWindowAttributes_t wattr;
0134   wattr.fMask = kWAOverrideRedirect;
0135   wattr.fOverrideRedirect = kTRUE;
0136   gVirtualX->ChangeWindowAttributes(fId, &wattr);
0137   AddInput(kStructureNotifyMask);  // to notify the client for structure (i.e. unmap) changes
0138 
0139   fSelectedColor = color;
0140   fLabel = nullptr;
0141   fNumColors = 0;
0142 
0143   fFirstRow = new FWColorRow(this);
0144   fSecondRow = new FWColorRow(this);
0145   fFirstRow->Connect("ColorChanged(Color_t)", "FWColorPopup", this, "ColorSelected(Color_t)");
0146   fSecondRow->Connect("ColorChanged(Color_t)", "FWColorPopup", this, "ColorSelected(Color_t)");
0147 }
0148 
0149 FWColorPopup::~FWColorPopup() { Cleanup(); }
0150 
0151 Bool_t FWColorPopup::HandleButton(Event_t *event) {
0152   if (event->fX < 0 || event->fX >= (Int_t)fWidth || event->fY < 0 || event->fY >= (Int_t)fHeight) {
0153     if (event->fType == kButtonRelease)
0154       UnmapWindow();
0155   } else {
0156     TGFrame *f = GetFrameFromPoint(event->fX, event->fY);
0157     if (f && f != this) {
0158       TranslateCoordinates(f, event->fX, event->fY, event->fX, event->fY);
0159       f->HandleButton(event);
0160     }
0161   }
0162   return kTRUE;
0163 }
0164 
0165 void FWColorPopup::InitContent(const char *name, const std::vector<Color_t> &colors, bool backgroundIsBlack) {
0166   fLabel = new TGLabel(this, name);
0167   fLabel->SetBackgroundColor(GetBackground());
0168   SetColors(colors, backgroundIsBlack);
0169 
0170   AddFrame(
0171       fLabel,
0172       new TGLayoutHints(kLHintsCenterX | kLHintsCenterY, kCROffsetX, kCROffsetY, kCRPadAbove + 1, kCRPadBelow - 1));
0173   AddFrame(fFirstRow,
0174            new TGLayoutHints(kLHintsCenterX | kLHintsCenterY, kCROffsetX, kCROffsetY, kCRPadAbove, kCRPadBelow));
0175   AddFrame(fSecondRow,
0176            new TGLayoutHints(kLHintsCenterX | kLHintsCenterY, kCROffsetX, kCROffsetY, kCRPadAbove, kCRPadBelow));
0177 
0178   fFirstRow->MapSubwindows();
0179   fFirstRow->Resize(fFirstRow->GetDefaultSize());
0180 
0181   fSecondRow->MapSubwindows();
0182   fSecondRow->Resize(fSecondRow->GetDefaultSize());
0183 
0184   if (fgFreePalette) {
0185     TGTextButton *b = new TGTextButton(this, "Color wheel");
0186     AddFrame(b,
0187              new TGLayoutHints(
0188                  kLHintsTop | kLHintsCenterX | kLHintsExpandX, kCROffsetX, kCROffsetY, kCRPadAbove, 2 * kCRPadBelow));
0189     b->Connect("Clicked()", "FWColorPopup", this, "PopupColorWheel()");
0190   }
0191 }
0192 
0193 // ----
0194 
0195 void FWColorPopup::PopupColorWheel() {
0196   fShowWheel = kTRUE;
0197   UnmapWindow();
0198 }
0199 
0200 void FWColorPopup::ColorWheelSelected(Pixel_t pix) { ColorSelected(TColor::GetColor(pix)); }
0201 
0202 // ----
0203 
0204 void FWColorPopup::SetColors(const std::vector<Color_t> &colors, bool backgroundIsBlack) {
0205   fNumColors = colors.size();
0206   for (UInt_t i = 0; i < colors.size() / 2; i++) {
0207     fFirstRow->AddColor(colors.at(i));
0208   }
0209   for (UInt_t i = colors.size() / 2; i < colors.size(); i++) {
0210     fSecondRow->AddColor(colors.at(i));
0211   }
0212   fFirstRow->SetBackgroundToBlack(backgroundIsBlack);
0213   fSecondRow->SetBackgroundToBlack(backgroundIsBlack);
0214 }
0215 
0216 void FWColorPopup::ResetColors(const std::vector<Color_t> &colors, bool backgroundIsBlack) {
0217   fNumColors = colors.size();
0218   for (UInt_t i = 0; i < colors.size() / 2; i++) {
0219     fFirstRow->ResetColor(i, colors.at(i));
0220   }
0221   fFirstRow->SetBackgroundToBlack(backgroundIsBlack);
0222   UInt_t index = 0;
0223   for (UInt_t i = colors.size() / 2; i < colors.size(); i++, ++index) {
0224     fSecondRow->ResetColor(index, colors.at(i));
0225   }
0226   fSecondRow->SetBackgroundToBlack(backgroundIsBlack);
0227 }
0228 
0229 void FWColorPopup::PlacePopup(Int_t x, Int_t y, UInt_t w, UInt_t h) {
0230   // Popup TGColorPopup at x,y position
0231 
0232   Int_t rx, ry;
0233   UInt_t rw, rh;
0234 
0235   // Parent is root window for the popup:
0236   gVirtualX->GetWindowSize(fParent->GetId(), rx, ry, rw, rh);
0237 
0238   if (x < 0)
0239     x = 0;
0240   if (x + fWidth > rw)
0241     x = rw - fWidth;
0242   if (y < 0)
0243     y = 0;
0244   if (y + fHeight > rh)
0245     y = rh - fHeight;
0246 
0247   MoveResize(x, y, w, h);
0248   MapSubwindows();
0249   Layout();
0250   MapRaised();
0251 
0252   // find out if this is necessary
0253   gVirtualX->GrabPointer(fId, kButtonPressMask | kButtonReleaseMask | kPointerMotionMask, kNone, kNone);
0254 
0255   gClient->WaitForUnmap(this);
0256   gVirtualX->GrabPointer(0, 0, 0, 0, kFALSE);
0257 
0258   if (fShowWheel) {
0259     Int_t retc;
0260     Pixel_t pixel = TColor::Number2Pixel(fSelectedColor);
0261 
0262     TGColorDialog *cd = new TGColorDialog(gClient->GetDefaultRoot(), this, &retc, &pixel, kFALSE);
0263 
0264     cd->Connect("ColorSelected(Pixel_t)", "FWColorPopup", this, "ColorWheelSelected(Pixel_t");
0265 
0266     cd->MapWindow();
0267     fClient->WaitForUnmap(cd);
0268     cd->DeleteWindow();
0269 
0270     fShowWheel = kFALSE;
0271   }
0272 }
0273 
0274 void FWColorPopup::SetName(const char *iName) { fLabel->SetText(iName); }
0275 
0276 void FWColorPopup::SetSelection(Color_t iColor) {
0277   fFirstRow->SetSelectedIndex(fFirstRow->FindColorIndex(iColor));
0278   fSecondRow->SetSelectedIndex(fSecondRow->FindColorIndex(iColor));
0279 }
0280 
0281 void FWColorPopup::ColorSelected(Color_t ci) {
0282   UnmapWindow();
0283   fSelectedColor = ci;
0284   Emit("ColorSelected(Color_t)", ci);
0285 }
0286 
0287 //------------------------------FWColorSelect------------------------------//
0288 
0289 FWColorSelect::FWColorSelect(
0290     const TGWindow *p, const char *label, Color_t index, const FWColorManager *iManager, Int_t id)
0291     : TGColorSelect(p, TColor::Number2Pixel(index), id),
0292       fLabel(label),
0293       fSelectedColor(index),
0294       fFireworksPopup(nullptr),
0295       fColorManager(iManager) {
0296   std::vector<Color_t> colors;
0297   fColorManager->fillLimitedColors(colors);
0298 
0299   fFireworksPopup = new FWColorPopup(gClient->GetDefaultRoot(), fColor);
0300   fFireworksPopup->InitContent(fLabel.c_str(), colors);
0301   fFireworksPopup->Connect("ColorSelected(Color_t)", "FWColorSelect", this, "SetColorByIndex(Color_t)");
0302 
0303   fColorManager->colorsHaveChanged_.connect(std::bind(&FWColorSelect::UpdateColors, this));
0304 }
0305 
0306 FWColorSelect::~FWColorSelect() { delete fFireworksPopup; }
0307 
0308 Bool_t FWColorSelect::HandleButton(Event_t *event) {
0309   TGFrame::HandleButton(event);
0310   if (!IsEnabled())
0311     return kTRUE;
0312 
0313   if (event->fCode != kButton1)
0314     return kFALSE;
0315 
0316   if ((event->fType == kButtonPress) && HasFocus())
0317     WantFocus();
0318 
0319   if (event->fType == kButtonPress) {
0320     fPressPos.fX = fX;
0321     fPressPos.fY = fY;
0322 
0323     if (fState != kButtonDown) {
0324       fPrevState = fState;
0325       SetState(kButtonDown);
0326     }
0327   } else {
0328     if (fState != kButtonUp) {
0329       SetState(kButtonUp);
0330 
0331       // case when it was dragged during guibuilding
0332       if ((fPressPos.fX != fX) || (fPressPos.fY != fY)) {
0333         return kFALSE;
0334       }
0335 
0336       Window_t wdummy;
0337       Int_t ax, ay;
0338 
0339       std::vector<Color_t> colors;
0340       fColorManager->fillLimitedColors(colors);
0341 
0342       fFireworksPopup->ResetColors(colors, fColorManager->backgroundColorIndex() == FWColorManager::kBlackIndex);
0343       fFireworksPopup->SetSelection(fSelectedColor);
0344 
0345       gVirtualX->TranslateCoordinates(fId, gClient->GetDefaultRoot()->GetId(), 0, fHeight, ax, ay, wdummy);
0346       fFireworksPopup->PlacePopup(ax, ay, fFireworksPopup->GetDefaultWidth(), fFireworksPopup->GetDefaultHeight());
0347     }
0348   }
0349   return kTRUE;
0350 }
0351 
0352 void FWColorSelect::SetColorByIndex(Color_t iColor) { SetColorByIndex(iColor, kTRUE); }
0353 
0354 void FWColorSelect::SetColorByIndex(Color_t iColor, Bool_t iSendSignal) {
0355   fSelectedColor = iColor;
0356   SetColor(TColor::Number2Pixel(iColor), kFALSE);
0357   if (iSendSignal) {
0358     ColorChosen(fSelectedColor);
0359   }
0360 }
0361 
0362 void FWColorSelect::UpdateColors() { SetColor(fSelectedColor, kFALSE); }
0363 
0364 void FWColorSelect::ColorChosen(Color_t iColor) { Emit("ColorChosen(Color_t)", iColor); }