00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035 #include "TGComboBox.h"
00036 #include "TGButtonGroup.h"
00037 #include "TGraphEditor.h"
00038 #include "TGTextEntry.h"
00039 #include "TGToolTip.h"
00040 #include "TGLabel.h"
00041 #include "TGraph.h"
00042 #include "TVirtualPad.h"
00043 #include "TGraphErrors.h"
00044
00045 ClassImp(TGraphEditor)
00046
00047 enum EGraphWid {
00048 kShape = 0,
00049 kSHAPE_NOLINE,
00050 kSHAPE_SMOOTH,
00051 kSHAPE_SIMPLE,
00052 kSHAPE_BAR,
00053 kSHAPE_FILL,
00054 kMARKER_ONOFF,
00055 kGRAPH_TITLE,
00056 kGRAPH_LINE_WIDTH,
00057 kGRAPH_LINE_SIDE
00058 };
00059
00060
00061
00062 TGraphEditor::TGraphEditor(const TGWindow *p, Int_t width,
00063 Int_t height, UInt_t options, Pixel_t back)
00064 : TGedFrame(p, width, height, options | kVerticalFrame, back)
00065 {
00066
00067
00068 fGraph = 0;
00069
00070 MakeTitle("Title");
00071
00072 fTitlePrec = 2;
00073 fTitle = new TGTextEntry(this, new TGTextBuffer(50), kGRAPH_TITLE);
00074 fTitle->Resize(135, fTitle->GetDefaultHeight());
00075 fTitle->SetToolTipText("Enter the graph title string");
00076
00077 AddFrame(fTitle, new TGLayoutHints(kLHintsLeft, 3, 1, 2, 5));
00078
00079
00080 TGCompositeFrame *f2 = new TGCompositeFrame(this, 80, 20, kVerticalFrame);
00081 fgr = new TGButtonGroup(f2,3,1,3,5,"Shape");
00082 fgr->SetRadioButtonExclusive(kTRUE);
00083 fShape = new TGRadioButton(fgr,"No Line",kSHAPE_NOLINE);
00084 fShape->SetToolTipText("The points are not connected by a line");
00085 fShape0 = new TGRadioButton(fgr,"Smooth Line ",kSHAPE_SMOOTH);
00086 fShape0->SetToolTipText("Draw a smooth graph curve");
00087 fShape1 = new TGRadioButton(fgr,"Simple Line ",kSHAPE_SIMPLE);
00088 fShape1->SetToolTipText("Draw a simple poly-line between the graph points");
00089 fShape2 = new TGRadioButton(fgr,"Bar Chart",kSHAPE_BAR);
00090 fShape2->SetToolTipText("Draw a bar chart at each graph point");
00091 fShape3 = new TGRadioButton(fgr,"Fill area",kSHAPE_FILL);
00092 fShape3->SetToolTipText("A fill area is drawn");
00093
00094 fgr->SetLayoutHints(fShape1lh=new TGLayoutHints(kLHintsLeft, 0,3,0,0), fShape1);
00095 fgr->Show();
00096 fgr->ChangeOptions(kFitWidth|kChildFrame|kVerticalFrame);
00097 f2->AddFrame(fgr, new TGLayoutHints(kLHintsLeft, 4, 0, 0, 0));
00098
00099
00100 fMarkerOnOff = new TGCheckButton(f2,"Show Marker",kMARKER_ONOFF);
00101 fMarkerOnOff->SetToolTipText("Make Marker visible/invisible");
00102 f2->AddFrame(fMarkerOnOff, new TGLayoutHints(kLHintsTop, 5, 1, 0, 3));
00103 AddFrame(f2, new TGLayoutHints(kLHintsTop, 1, 1, 0, 0));
00104
00105
00106 MakeTitle("Exclusion Zone");
00107 TGCompositeFrame *f3 = new TGCompositeFrame(this, 80, 20, kHorizontalFrame);
00108 AddFrame(f3, new TGLayoutHints(kLHintsTop, 1, 1, 5, 0));
00109
00110 fExSide = new TGCheckButton(f3,"+-",kGRAPH_LINE_SIDE);
00111 fExSide->SetToolTipText("Zone is drawing side");
00112 f3->AddFrame(fExSide, new TGLayoutHints(kLHintsTop, 5, 1, 0, 0));
00113
00114 fWidthCombo = new TGLineWidthComboBox(f3, kGRAPH_LINE_WIDTH,
00115 kHorizontalFrame | kSunkenFrame | kDoubleBorder,
00116 GetWhitePixel(), kTRUE);
00117 fWidthCombo->Resize(91, 20);
00118 f3->AddFrame(fWidthCombo, new TGLayoutHints(kLHintsLeft, 7, 1, 1, 1));
00119 fWidthCombo->Associate(f3);
00120 }
00121
00122
00123
00124 TGraphEditor::~TGraphEditor()
00125 {
00126
00127
00128
00129 delete fShape;
00130 delete fShape0;
00131 delete fShape1;
00132 delete fShape2;
00133 delete fShape3;
00134 delete fShape1lh;
00135 }
00136
00137
00138
00139 void TGraphEditor::ConnectSignals2Slots()
00140 {
00141
00142
00143 fTitle->Connect("TextChanged(const char *)","TGraphEditor",this,"DoTitle(const char *)");
00144 fgr->Connect("Clicked(Int_t)","TGraphEditor",this,"DoShape()");
00145 fMarkerOnOff->Connect("Toggled(Bool_t)","TGraphEditor",this,"DoMarkerOnOff(Bool_t)");
00146 fWidthCombo->Connect("Selected(Int_t)", "TGraphEditor", this, "DoGraphLineWidth()");
00147 fExSide->Connect("Clicked()","TGraphEditor",this,"DoGraphLineWidth()");
00148
00149 fInit = kFALSE;
00150 }
00151
00152
00153
00154 void TGraphEditor::SetModel(TObject* obj)
00155 {
00156
00157
00158 fGraph = (TGraph *)obj;
00159 fAvoidSignal = kTRUE;
00160
00161
00162 const char *text = fGraph->GetTitle();
00163 fTitle->SetText(text);
00164
00165 TString opt = GetDrawOption();
00166 opt.ToUpper();
00167 Int_t i=0;
00168 Bool_t make=kFALSE;
00169
00170 TString dum = opt;
00171 Int_t l = opt.Length()-1;
00172 while (i < l) {
00173 dum.Remove(dum.First(opt[i]),1);
00174 if (dum.Contains(opt[i])){
00175 opt.Remove(opt.First(opt[i]),1);
00176 l--;
00177 i--;
00178 make=kTRUE;
00179 }
00180 i++;
00181 }
00182
00183 if (opt.Contains("C")) {
00184 fgr->SetButton(kSHAPE_SMOOTH, kTRUE);
00185 fDrawShape='C';
00186 } else if (opt.Contains("L")) {
00187 fgr->SetButton(kSHAPE_SIMPLE, kTRUE);
00188 fDrawShape='L';
00189 } else if (opt.Contains("B")){
00190 fgr->SetButton(kSHAPE_BAR, kTRUE);
00191 fDrawShape='B';
00192 } else if (opt.Contains("F")){
00193 fgr->SetButton(kSHAPE_FILL, kTRUE);
00194 fDrawShape='F';
00195 } else {
00196 fgr->SetButton(kSHAPE_NOLINE, kTRUE);
00197 fDrawShape=' ';
00198 }
00199 if (make) SetDrawOption(opt);
00200
00201
00202
00203 if (opt=="A" || opt=="AP" || opt=="PA" || opt == "P") {
00204 if (!opt.Contains("P"))
00205 opt +="P";
00206 fMarkerOnOff->SetState(kButtonDisabled);
00207 } else if (opt.Contains("P")) {
00208 fMarkerOnOff->SetState(kButtonDown);
00209 } else fMarkerOnOff->SetState(kButtonUp);
00210
00211
00212 if (fGraph->GetLineWidth()<0) fExSide->SetState(kButtonDown, kFALSE);
00213 else fExSide->SetState(kButtonUp, kFALSE);
00214 fWidthCombo->Select(TMath::Abs(Int_t(fGraph->GetLineWidth()/100)), kFALSE);
00215
00216 if (fInit) ConnectSignals2Slots();
00217 fAvoidSignal = kFALSE;
00218 }
00219
00220
00221
00222 void TGraphEditor::DoTitle(const char *text)
00223 {
00224
00225
00226 if (fAvoidSignal) return;
00227 fGraph->SetTitle(text);
00228 Update();
00229 }
00230
00231
00232
00233 void TGraphEditor::DoShape()
00234 {
00235
00236
00237 if (fAvoidSignal) return;
00238 TString opt;
00239 if (fGraph->InheritsFrom(TGraphErrors::Class()))
00240 opt = fGraph->GetDrawOption();
00241 else
00242 opt = GetDrawOption();
00243
00244 opt.ToUpper();
00245 Int_t s = 0;
00246 if (fShape->GetState() == kButtonDown) s = kSHAPE_NOLINE;
00247 else if (fShape0->GetState() == kButtonDown) s = kSHAPE_SMOOTH;
00248 else if (fShape1->GetState() == kButtonDown) s = kSHAPE_SIMPLE;
00249 else if (fShape2->GetState() == kButtonDown) s = kSHAPE_BAR;
00250 else s = kSHAPE_FILL;
00251
00252 switch (s) {
00253
00254
00255 case kSHAPE_NOLINE: {
00256 if (opt.Contains(fDrawShape))
00257 opt.Remove(opt.First(fDrawShape),1);
00258 fDrawShape = ' ';
00259 fMarkerOnOff->SetState(kButtonDisabled);
00260 break;
00261 }
00262
00263
00264 case kSHAPE_SMOOTH: {
00265 if (fDrawShape == ' ')
00266 opt +="C";
00267 else if (opt.Contains(fDrawShape))
00268 opt.Replace(opt.First(fDrawShape),1,'C');
00269 fDrawShape = 'C';
00270 break;
00271 }
00272
00273
00274 case kSHAPE_SIMPLE: {
00275 if (fDrawShape == ' ')
00276 opt +="L";
00277 else if (opt.Contains(fDrawShape))
00278 opt.Replace(opt.First(fDrawShape),1,'L');
00279 fDrawShape='L';
00280 break;
00281 }
00282
00283
00284 case kSHAPE_BAR: {
00285 if (fDrawShape == ' ')
00286 opt +="B";
00287 else if (opt.Contains(fDrawShape))
00288 opt.Replace(opt.First(fDrawShape),1,'B');
00289 fDrawShape='B';
00290 break;
00291 }
00292
00293
00294 case kSHAPE_FILL: {
00295 if (fDrawShape == ' ')
00296 opt +="F";
00297 else if (opt.Contains(fDrawShape))
00298 opt.Replace(opt.First(fDrawShape),1,'F');
00299 fDrawShape='F';
00300 break;
00301 }
00302 }
00303
00304 if (gPad) gPad->GetVirtCanvas()->SetCursor(kWatch);
00305 gVirtualX->SetCursor(GetId(), gVirtualX->CreateCursor(kWatch));
00306
00307
00308 if (opt.Contains("P"))
00309 fMarkerOnOff->SetState(kButtonDown);
00310 else
00311 fMarkerOnOff->SetState(kButtonUp);
00312 if (opt=="A" || opt=="AP" || opt=="PA" || opt == "P") {
00313 if (!opt.Contains("P"))
00314 opt +="P";
00315 fMarkerOnOff->SetState(kButtonDisabled);
00316 }
00317
00318
00319 if (opt.Contains("L") || opt.Contains("C")) {
00320 if (fGraph->GetLineWidth()<0) fExSide->SetState(kButtonDown, kFALSE);
00321 else fExSide->SetState(kButtonUp, kFALSE);
00322 fWidthCombo->SetEnabled(kTRUE);
00323 } else {
00324 fExSide->SetState(kButtonDisabled);
00325 fWidthCombo->SetEnabled(kFALSE);
00326 }
00327
00328 SetDrawOption(opt);
00329 if (gPad) gPad->GetVirtCanvas()->SetCursor(kPointer);
00330 gVirtualX->SetCursor(GetId(), gVirtualX->CreateCursor(kPointer));
00331 }
00332
00333
00334
00335 void TGraphEditor::DoMarkerOnOff(Bool_t on)
00336 {
00337
00338
00339 if (fAvoidSignal) return;
00340 TString t = GetDrawOption();
00341 t.ToUpper();
00342
00343
00344 if (on) {
00345 if (!t.Contains("P")) t+="P";
00346 fShape->SetState(kButtonEngaged);
00347 } else {
00348
00349 while (t.Contains("P")) t.Remove(t.First("P"),1);
00350 fShape->SetState(kButtonDisabled);
00351 }
00352 SetDrawOption(t);
00353 }
00354
00355
00356
00357 void TGraphEditor::DoGraphLineWidth()
00358 {
00359
00360
00361 if (fAvoidSignal) return;
00362 Int_t width = fWidthCombo->GetSelected();
00363 Int_t lineWidth = TMath::Abs(fGraph->GetLineWidth()%100);
00364 Int_t side = 1;
00365 if (fExSide->GetState() == kButtonDown) side = -1;
00366 fGraph->SetLineWidth(side*(100*width+lineWidth));
00367 Update();
00368 }
00369