Logo ROOT   6.30.04
Reference Guide
 All Namespaces Files Pages
TGeoMaterialEditor.cxx
Go to the documentation of this file.
1 // @(#):$Id$
2 // Author: M.Gheata
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 /** \class TGeoMaterialEditor
13 \ingroup Geometry_builder
14 
15 Editors for materials.
16 
17 
18 */
19 
20 #include "TGeoMaterialEditor.h"
21 #include "TGeoTabManager.h"
22 #include "TGeoMaterial.h"
23 #include "TGeoManager.h"
24 #include "TVirtualGeoPainter.h"
25 #include "TPad.h"
26 #include "TView.h"
27 #include "TGTab.h"
28 #include "TGComboBox.h"
29 #include "TGButton.h"
30 #include "TGTextEntry.h"
31 #include "TGNumberEntry.h"
32 #include "TGLabel.h"
33 #include "TGListView.h"
34 
35 ClassImp(TGeoMaterialEditor);
36 
37 enum ETGeoMaterialWid {
38  kMATERIAL_NAME, kMATERIAL_A, kMATERIAL_Z, kMATERIAL_RHO,
39  kMATERIAL_RAD, kMATERIAL_ABS, kMATERIAL_STATE, kMATERIAL_TEMP, kMATERIAL_PRES,
40  kMATERIAL_APPLY, kMATERIAL_CANCEL, kMATERIAL_UNDO
41 };
42 
43 enum ETGeoMaterialStates {
44  kMAT_UNDEFINED, kMAT_SOLID, kMAT_LIQUID, kMAT_GAS
45 };
46 
47 enum ETGeoMixtureWid {
48  kMIX_ELEM, kMIX_CHK1, kMIX_FRAC, kMIX_CHK2, kMIX_NATOMS, kMIX_ADDELEM
49 };
50 
51 ////////////////////////////////////////////////////////////////////////////////
52 /// Constructor for material editor.
53 
54 TGeoMaterialEditor::TGeoMaterialEditor(const TGWindow *p, Int_t width,
55  Int_t height, UInt_t options, Pixel_t back)
56  : TGeoGedFrame(p, width, height, options | kVerticalFrame, back)
57 {
58  fMaterial = 0;
59  fAi = fZi = 0;
60  fDensityi = 0.0;
61  fNamei = "";
62  fIsModified = kFALSE;
63  fIsMaterialEditable = kTRUE;
64 
65  // TextEntry for material name
66  MakeTitle("Name");
67  fMaterialName = new TGTextEntry(this, new TGTextBuffer(50), kMATERIAL_NAME);
68  fMaterialName->SetDefaultSize(135, fMaterialName->GetDefaultHeight());
69  fMaterialName->SetToolTipText("Enter the material name");
70  fMaterialName->Associate(this);
71  AddFrame(fMaterialName, new TGLayoutHints(kLHintsLeft | kLHintsExpandX, 1, 1, 2, 5));
72 
73  TGTextEntry *nef;
74  MakeTitle("Material properties");
75  TGCompositeFrame *f1 = new TGCompositeFrame(this, 118, 10, kHorizontalFrame |
76  kFixedWidth | kOwnBackground);
77  f1->AddFrame(new TGLabel(f1, "A"), new TGLayoutHints(kLHintsLeft, 1, 1, 6, 0));
78  fMatA = new TGNumberEntry(f1, 0., 6, kMATERIAL_A, TGNumberFormat::kNESRealThree);
79  nef = (TGTextEntry*)fMatA->GetNumberEntry();
80  nef->SetToolTipText("Enter the atomic mass");
81  fMatA->Associate(this);
82  f1->AddFrame(fMatA, new TGLayoutHints(kLHintsLeft, 2, 2, 4, 4));
83  f1->AddFrame(new TGLabel(f1, "Z"), new TGLayoutHints(kLHintsLeft, 1, 1, 6, 0));
84  fMatZ = new TGNumberEntry(f1, 0., 4, kMATERIAL_Z, TGNumberFormat::kNESInteger);
85  nef = (TGTextEntry*)fMatZ->GetNumberEntry();
86  nef->SetToolTipText("Enter the atomic charge");
87  fMatZ->Associate(this);
88  f1->AddFrame(fMatZ, new TGLayoutHints(kLHintsLeft, 2, 2, 4, 4));
89  f1->Resize(150,30);
90  AddFrame(f1, new TGLayoutHints(kLHintsLeft, 1, 1, 1, 1));
91 
92 
93  TGCompositeFrame *compxyz = new TGCompositeFrame(this, 118, 30, kVerticalFrame | kRaisedFrame | kDoubleBorder);
94  // Combo box for material state
95  f1 = new TGCompositeFrame(compxyz, 118, 10, kHorizontalFrame |
96  kLHintsExpandX | kFixedWidth | kOwnBackground);
97  f1->AddFrame(new TGLabel(f1, "State"), new TGLayoutHints(kLHintsLeft, 1, 1, 6, 0));
98  fMatState = new TGComboBox(f1, kMATERIAL_STATE);
99  fMatState->AddEntry("Undefined", TGeoMaterial::kMatStateUndefined);
100  fMatState->AddEntry("Solid", TGeoMaterial::kMatStateSolid);
101  fMatState->AddEntry("Liquid", TGeoMaterial::kMatStateLiquid);
102  fMatState->AddEntry("Gas", TGeoMaterial::kMatStateGas);
103  fMatState->Resize(90, fMaterialName->GetDefaultHeight());
104  f1->AddFrame(fMatState, new TGLayoutHints(kLHintsRight , 2, 2, 1, 1));
105  compxyz->AddFrame(f1, new TGLayoutHints(kLHintsLeft | kLHintsExpandX , 2, 2, 1, 1));
106 
107  // Number entry for density
108  f1 = new TGCompositeFrame(compxyz, 118, 10, kHorizontalFrame |
109  kLHintsExpandX | kFixedWidth | kOwnBackground);
110  f1->AddFrame(new TGLabel(f1, "Density"), new TGLayoutHints(kLHintsLeft, 1, 1, 6, 0));
111  fMatDensity = new TGNumberEntry(f1, 0., 5, kMATERIAL_RHO, TGNumberFormat::kNESRealThree);
112  fMatDensity->Resize(90, fMaterialName->GetDefaultHeight());
113  nef = (TGTextEntry*)fMatDensity->GetNumberEntry();
114  nef->SetToolTipText("Enter material density in [g/cm3]");
115  fMatDensity->Associate(this);
116  f1->AddFrame(fMatDensity, new TGLayoutHints(kLHintsRight, 2, 2, 1, 1));
117  compxyz->AddFrame(f1, new TGLayoutHints(kLHintsLeft | kLHintsExpandX , 2, 2, 1, 1));
118 
119  // Number entry for temperature
120  f1 = new TGCompositeFrame(compxyz, 118, 10, kHorizontalFrame |
121  kLHintsExpandX | kFixedWidth | kOwnBackground);
122  f1->AddFrame(new TGLabel(f1, "Temperature"), new TGLayoutHints(kLHintsLeft, 1, 1, 6, 0));
123  fMatTemperature = new TGNumberEntry(f1, 0., 5, kMATERIAL_TEMP, TGNumberFormat::kNESRealTwo);
124  fMatTemperature->Resize(90, fMaterialName->GetDefaultHeight());
125  nef = (TGTextEntry*)fMatTemperature->GetNumberEntry();
126  nef->SetToolTipText("Enter material temperature in [Kelvin]");
127  fMatTemperature->Associate(this);
128  f1->AddFrame(fMatTemperature, new TGLayoutHints(kLHintsRight, 2, 2, 1, 1));
129  compxyz->AddFrame(f1, new TGLayoutHints(kLHintsLeft | kLHintsExpandX , 2, 2, 1, 1));
130 
131  // Number entry for pressure
132  f1 = new TGCompositeFrame(compxyz, 118, 10, kHorizontalFrame |
133  kLHintsExpandX | kFixedWidth | kOwnBackground);
134  f1->AddFrame(new TGLabel(f1, "Pressure"), new TGLayoutHints(kLHintsLeft, 1, 1, 6, 0));
135  fMatPressure = new TGNumberEntry(f1, 0., 5, kMATERIAL_PRES, TGNumberFormat::kNESRealThree);
136  fMatPressure->Resize(90, fMaterialName->GetDefaultHeight());
137  nef = (TGTextEntry*)fMatPressure->GetNumberEntry();
138  nef->SetToolTipText("Enter material pressure in [bar]");
139  fMatPressure->Associate(this);
140  f1->AddFrame(fMatPressure, new TGLayoutHints(kLHintsRight, 2, 2, 1, 1));
141  compxyz->AddFrame(f1, new TGLayoutHints(kLHintsLeft | kLHintsExpandX , 2, 2, 1, 1));
142 
143  // Number entry for radiation length
144  f1 = new TGCompositeFrame(compxyz, 118, 10, kHorizontalFrame |
145  kLHintsExpandX | kFixedWidth | kOwnBackground);
146  f1->AddFrame(new TGLabel(f1, "RadLen"), new TGLayoutHints(kLHintsLeft, 1, 1, 6, 0));
147  fMatRadLen = new TGNumberEntry(f1, 0., 5, kMATERIAL_RAD);
148  fMatRadLen->Resize(90, fMaterialName->GetDefaultHeight());
149  nef = (TGTextEntry*)fMatRadLen->GetNumberEntry();
150  nef->SetToolTipText("Computed radiation length");
151  fMatRadLen->Associate(this);
152  f1->AddFrame(fMatRadLen, new TGLayoutHints(kLHintsRight, 2, 2, 1, 1));
153  compxyz->AddFrame(f1, new TGLayoutHints(kLHintsLeft | kLHintsExpandX , 2, 2, 1, 1));
154 
155  // Number entry for absorption length
156  f1 = new TGCompositeFrame(compxyz, 118, 10, kHorizontalFrame |
157  kLHintsExpandX | kFixedWidth | kOwnBackground);
158  f1->AddFrame(new TGLabel(f1, "AbsLen"), new TGLayoutHints(kLHintsLeft, 1, 1, 6, 0));
159  fMatAbsLen = new TGNumberEntry(f1, 0., 5, kMATERIAL_ABS);
160  fMatAbsLen->Resize(90, fMaterialName->GetDefaultHeight());
161  nef = (TGTextEntry*)fMatAbsLen->GetNumberEntry();
162  nef->SetToolTipText("Absorption length");
163  fMatAbsLen->Associate(this);
164  f1->AddFrame(fMatAbsLen, new TGLayoutHints(kLHintsRight, 2, 2, 1, 1));
165  compxyz->AddFrame(f1, new TGLayoutHints(kLHintsLeft | kLHintsExpandX , 2, 2, 1, 1));
166 
167  compxyz->Resize(150,30);
168  AddFrame(compxyz, new TGLayoutHints(kLHintsLeft, 0, 0, 2, 2));
169 
170  // Buttons
171  f23 = new TGCompositeFrame(this, 118, 20, kHorizontalFrame | kSunkenFrame | kDoubleBorder);
172  fApply = new TGTextButton(f23, "Apply");
173  f23->AddFrame(fApply, new TGLayoutHints(kLHintsLeft, 2, 2, 1, 1));
174  fApply->Associate(this);
175  fUndo = new TGTextButton(f23, " Undo ");
176  f23->AddFrame(fUndo, new TGLayoutHints(kLHintsRight , 2, 2, 1, 1));
177  fUndo->Associate(this);
178  AddFrame(f23, new TGLayoutHints(kLHintsLeft, 0, 0, 4, 4));
179  fUndo->SetSize(fApply->GetSize());
180 }
181 
182 ////////////////////////////////////////////////////////////////////////////////
183 /// Destructor
184 
185 TGeoMaterialEditor::~TGeoMaterialEditor()
186 {
187  TGFrameElement *el;
188  TIter next(GetList());
189  while ((el = (TGFrameElement *)next())) {
190  if (el->fFrame->IsComposite())
191  TGeoTabManager::Cleanup((TGCompositeFrame*)el->fFrame);
192  }
193  Cleanup();
194 }
195 
196 ////////////////////////////////////////////////////////////////////////////////
197 /// Connect signals to slots.
198 
199 void TGeoMaterialEditor::ConnectSignals2Slots()
200 {
201  fApply->Connect("Clicked()", "TGeoMaterialEditor", this, "DoApply()");
202  fUndo->Connect("Clicked()", "TGeoMaterialEditor", this, "DoUndo()");
203  fMaterialName->Connect("TextChanged(const char *)", "TGeoMaterialEditor", this, "DoName()");
204  fMatA->Connect("ValueSet(Long_t)", "TGeoMaterialEditor", this, "DoA()");
205  fMatZ->Connect("ValueSet(Long_t)", "TGeoMaterialEditor", this, "DoZ()");
206  fMatState->Connect("Selected(Int_t)", "TGeoMaterialEditor", this, "DoState(Int_t)");
207  fMatDensity->Connect("ValueSet(Long_t)", "TGeoMaterialEditor", this, "DoDensity()");
208  fMatTemperature->Connect("ValueSet(Long_t)", "TGeoMaterialEditor", this, "DoTemperature()");
209  fMatPressure->Connect("ValueSet(Long_t)", "TGeoMaterialEditor", this, "DoPressure()");
210  fMatRadLen->Connect("ValueSet(Long_t)", "TGeoMaterialEditor", this, "DoRadAbs()");
211  fMatAbsLen->Connect("ValueSet(Long_t)", "TGeoMaterialEditor", this, "DoRadAbs()");
212  fInit = kFALSE;
213 }
214 
215 ////////////////////////////////////////////////////////////////////////////////
216 /// Connect to the selected material.
217 
218 void TGeoMaterialEditor::SetModel(TObject* obj)
219 {
220  if (obj == 0 || !(obj->InheritsFrom(TGeoMaterial::Class()))) {
221  SetActive(kFALSE);
222  return;
223  }
224  fMaterial = (TGeoMaterial*)obj;
225  fAi = fMaterial->GetA();
226  fZi = (Int_t)fMaterial->GetZ();
227  fStatei = (Int_t)fMaterial->GetState();
228  fDensityi = fMaterial->GetDensity();
229  fTempi = fMaterial->GetTemperature();
230  fPresi = fMaterial->GetPressure()/6.2415e+8;
231  fNamei = fMaterial->GetName();
232  fMaterialName->SetText(fMaterial->GetName());
233  fMatA->SetNumber(fAi);
234  fMatZ->SetNumber(fZi);
235  fMatState->Select(fStatei);
236  fMatDensity->SetNumber(fDensityi);
237  fMatTemperature->SetNumber(fTempi);
238  fMatPressure->SetNumber(fPresi);
239  fMatRadLen->SetNumber(fMaterial->GetRadLen());
240  fMatAbsLen->SetNumber(fMaterial->GetIntLen());
241  fApply->SetEnabled(kFALSE);
242  fUndo->SetEnabled(kFALSE);
243 
244  if (fInit) ConnectSignals2Slots();
245  SetActive();
246 }
247 
248 ////////////////////////////////////////////////////////////////////////////////
249 /// Perform name change.
250 
251 void TGeoMaterialEditor::DoName()
252 {
253  DoModified();
254 }
255 
256 ////////////////////////////////////////////////////////////////////////////////
257 /// Slot for atomic mass.
258 
259 void TGeoMaterialEditor::DoA()
260 {
261  if (fMaterial->IsMixture()) {
262  fMatA->SetNumber(fMaterial->GetA());
263  return;
264  }
265  DoModified();
266 }
267 
268 ////////////////////////////////////////////////////////////////////////////////
269 /// Slot for charge.
270 
271 void TGeoMaterialEditor::DoZ()
272 {
273  if (fMaterial->IsMixture()) {
274  fMatZ->SetNumber(fMaterial->GetZ());
275  return;
276  }
277  Int_t z = (Int_t)fMatZ->GetNumber();
278  TGeoElementTable *table = gGeoManager->GetElementTable();
279  if (z >= table->GetNelements()) {
280  z = table->GetNelements()-1;
281  fMatZ->SetNumber(z);
282  }
283  TGeoElement *elem = table->GetElement(z);
284  if (!elem) return;
285  Double_t a = elem->A();
286  fMatA->SetNumber(a);
287  DoModified();
288 }
289 
290 ////////////////////////////////////////////////////////////////////////////////
291 /// Slot for material state.
292 
293 void TGeoMaterialEditor::DoState(Int_t /*state*/)
294 {
295  DoModified();
296 }
297 
298 ////////////////////////////////////////////////////////////////////////////////
299 /// Slot for material temperature.
300 
301 void TGeoMaterialEditor::DoTemperature()
302 {
303  DoModified();
304 }
305 
306 ////////////////////////////////////////////////////////////////////////////////
307 /// Slot for material pressure.
308 
309 void TGeoMaterialEditor::DoPressure()
310 {
311  DoModified();
312 }
313 
314 ////////////////////////////////////////////////////////////////////////////////
315 /// Slot for density.
316 /// fMatDensity->SetNumber(fDensityi);
317 
318 void TGeoMaterialEditor::DoDensity()
319 {
320  DoModified();
321 }
322 
323 ////////////////////////////////////////////////////////////////////////////////
324 /// Slot for radiation/absorption length.
325 
326 void TGeoMaterialEditor::DoRadAbs()
327 {
328  fMatRadLen->SetNumber(fMaterial->GetRadLen());
329  fMatAbsLen->SetNumber(fMaterial->GetIntLen());
330  DoModified();
331 }
332 
333 ////////////////////////////////////////////////////////////////////////////////
334 /// Slot for applying modifications.
335 
336 void TGeoMaterialEditor::DoApply()
337 {
338  const char *name = fMaterialName->GetText();
339  fMaterial->SetName(name);
340 
341  fMaterial->SetA(fMatA->GetNumber());
342  fMaterial->SetZ(fMatZ->GetNumber());
343  fMaterial->SetDensity(fMatDensity->GetNumber());
344  fMaterial->SetTemperature(fMatTemperature->GetNumber());
345  fMaterial->SetPressure(6.2415e+8*fMatPressure->GetNumber());
346  fMaterial->SetState((TGeoMaterial::EGeoMaterialState)fMatState->GetSelected());
347  fMaterial->SetRadLen(fMatRadLen->GetNumber(), fMatAbsLen->GetNumber());
348  fMatRadLen->SetNumber(fMaterial->GetRadLen());
349  fMatAbsLen->SetNumber(fMaterial->GetIntLen());
350  fUndo->SetEnabled();
351  fApply->SetEnabled(kFALSE);
352 }
353 
354 ////////////////////////////////////////////////////////////////////////////////
355 /// Slot for cancelling current modifications.
356 
357 void TGeoMaterialEditor::DoUndo()
358 {
359  fMaterialName->SetText(fNamei.Data());
360  fMaterial->SetName(fNamei.Data());
361  fMatA->SetNumber(fAi);
362  fMaterial->SetA(fAi);
363  fMatZ->SetNumber(fZi);
364  fMaterial->SetZ(fZi);
365  fMatState->Select(fStatei);
366  fMaterial->SetState((TGeoMaterial::EGeoMaterialState)fStatei);
367  fMatDensity->SetNumber(fDensityi);
368  fMaterial->SetDensity(fDensityi);
369  fMatTemperature->SetNumber(fTempi);
370  fMaterial->SetTemperature(fTempi);
371  fMatPressure->SetNumber(fPresi);
372  fMaterial->SetPressure(fPresi*6.2415e+8);
373  fMatRadLen->SetNumber(fMaterial->GetRadLen());
374  fMatAbsLen->SetNumber(fMaterial->GetIntLen());
375  fApply->SetEnabled(kFALSE);
376  fUndo->SetEnabled(kFALSE);
377 }
378 
379 ////////////////////////////////////////////////////////////////////////////////
380 /// Slot for signaling modifications.
381 
382 void TGeoMaterialEditor::DoModified()
383 {
384  fApply->SetEnabled();
385 }
386 
387 /** \class TGeoMixtureEditor
388 \ingroup Geometry_builder
389 
390 Editors for mixtures.
391 
392 */
393 
394 ClassImp(TGeoMixtureEditor);
395 
396 ////////////////////////////////////////////////////////////////////////////////
397 /// Constructor for mixture editor.
398 
399 TGeoMixtureEditor::TGeoMixtureEditor(const TGWindow *p, Int_t width,
400  Int_t height, UInt_t options, Pixel_t back)
401  : TGeoMaterialEditor(p, width, height, options | kVerticalFrame, back)
402 {
403  fMixture = 0;
404  TGCompositeFrame *compxyz=0, *f1=0;
405  TGTextEntry *nef;
406  MakeTitle("Mixture settings");
407  fNelem = new TGLabel(this, "Number of elements: 0");
408  AddFrame(fNelem, new TGLayoutHints(kLHintsLeft , 6, 2, 2, 2));
409  compxyz = new TGCompositeFrame(this, 118, 30, kVerticalFrame | kRaisedFrame | kDoubleBorder);
410  // Combo box for selecting elements
411  f1 = new TGCompositeFrame(compxyz, 118, 10, kHorizontalFrame |
412  kLHintsExpandX | kFixedWidth | kOwnBackground);
413  fMixElem = new TGComboBox(f1, kMIX_ELEM);
414  TGeoElementTable *table = gGeoManager->GetElementTable();
415  if (table) {
416  TGeoElement *element;
417  for (Int_t i=0; i<table->GetNelements(); i++) {
418  element = table->GetElement(i);
419  if (element) fMixElem->AddEntry(element->GetTitle(),i);
420  }
421  }
422  fMixElem->Select(0);
423  fMixElem->Resize(90, fMaterialName->GetDefaultHeight());
424  f1->AddFrame(fMixElem, new TGLayoutHints(kLHintsLeft , 2, 2, 1, 1));
425  TGCompositeFrame *comp1 = new TGCompositeFrame(f1, 118, 30, kVerticalFrame);
426  fAelem = new TGLabel(comp1, "A = 0");
427  comp1->AddFrame(fAelem, new TGLayoutHints(kLHintsRight , 2, 2, 2, 0));
428  fZelem = new TGLabel(comp1, "Z = 0");
429  comp1->AddFrame(fZelem, new TGLayoutHints(kLHintsRight , 2, 2, 2, 0));
430  f1->AddFrame(comp1, new TGLayoutHints(kLHintsLeft | kLHintsExpandX| kLHintsExpandY , 2, 2, 0, 0));
431  compxyz->AddFrame(f1, new TGLayoutHints(kLHintsLeft | kLHintsExpandX , 2, 2, 0, 0));
432 
433  // Fraction by weight
434  f1 = new TGCompositeFrame(compxyz, 118, 10, kHorizontalFrame |
435  kLHintsExpandX | kFixedWidth | kOwnBackground);
436  fChkFraction = new TGCheckButton(f1, "% weight");
437  fChkFraction->SetDown(kTRUE);
438  f1->AddFrame(fChkFraction, new TGLayoutHints(kLHintsLeft , 2, 2, 6, 1));
439  fNEFraction = new TGNumberEntry(f1, 0., 5, kMIX_FRAC, TGNumberFormat::kNESRealThree);
440  fNEFraction->SetFormat(TGNumberFormat::kNESRealThree, TGNumberFormat::kNEANonNegative);
441  fNEFraction->Resize(65, fMaterialName->GetDefaultHeight());
442  nef = (TGTextEntry*)fNEFraction->GetNumberEntry();
443  nef->SetToolTipText("Enter fraction by weight of this element");
444  fNEFraction->SetNumber(0.);
445  fNEFraction->Associate(this);
446  f1->AddFrame(fNEFraction, new TGLayoutHints(kLHintsRight, 2, 2, 1, 1));
447  compxyz->AddFrame(f1, new TGLayoutHints(kLHintsLeft | kLHintsExpandX , 2, 2, 1, 1));
448 
449  // Fraction by number of atoms
450  f1 = new TGCompositeFrame(compxyz, 118, 10, kHorizontalFrame |
451  kLHintsExpandX | kFixedWidth | kOwnBackground);
452  fChkNatoms = new TGCheckButton(f1, "N. atoms");
453  fChkNatoms->SetDown(kFALSE);
454  f1->AddFrame(fChkNatoms, new TGLayoutHints(kLHintsLeft, 2, 2, 6, 1));
455  fNENatoms = new TGNumberEntry(f1, 0., 5, kMIX_NATOMS);
456  fNENatoms->SetFormat(TGNumberFormat::kNESInteger, TGNumberFormat::kNEANonNegative);
457  fNENatoms->Resize(65, fMaterialName->GetDefaultHeight());
458  nef = (TGTextEntry*)fNENatoms->GetNumberEntry();
459  nef->SetToolTipText("Enter number of atoms for this element");
460  fNENatoms->SetNumber(0);
461  fNENatoms->Associate(this);
462  f1->AddFrame(fNENatoms, new TGLayoutHints(kLHintsRight, 2, 2, 1, 1));
463  compxyz->AddFrame(f1, new TGLayoutHints(kLHintsLeft | kLHintsExpandX , 2, 2, 1, 1));
464 
465  // Button for adding the element
466  fBAddElem = new TGTextButton(compxyz, "Add component");
467  fBAddElem->Associate(this);
468  compxyz->AddFrame(fBAddElem, new TGLayoutHints(kLHintsRight , 2, 2, 2, 0));
469 
470  compxyz->Resize(150,30);
471  AddFrame(compxyz, new TGLayoutHints(kLHintsLeft, 0, 0, 1, 1));
472 
473  // List view with all components
474  fComps = new TGCompositeFrame(this, 150, 100, kVerticalFrame | kSunkenFrame);
475  AddFrame(fComps, new TGLayoutHints(kLHintsLeft | kLHintsExpandX | kLHintsExpandY, 0, 2, 1, 2));
476 
477  TGeoTabManager::MoveFrame(f23, this);
478 }
479 
480 ////////////////////////////////////////////////////////////////////////////////
481 /// Connect signals to slots.
482 
483 void TGeoMixtureEditor::ConnectSignals2Slots()
484 {
485  fApply->Connect("Clicked()", "TGeoMixtureEditor", this, "DoApply1()");
486  fUndo->Connect("Clicked()", "TGeoMixtureEditor", this, "DoUndo1()");
487  fChkFraction->Connect("Clicked()", "TGeoMixtureEditor", this, "DoChkFraction()");
488  fChkNatoms->Connect("Clicked()", "TGeoMixtureEditor", this, "DoChkNatoms()");
489  fNEFraction->Connect("ValueSet(Long_t)", "TGeoMixtureEditor", this, "DoFraction()");
490  fNENatoms->Connect("ValueSet(Long_t)", "TGeoMixtureEditor", this, "DoNatoms()");
491  fMixElem->Connect("Selected(Int_t)", "TGeoMixtureEditor", this, "DoSelectElement(Int_t)");
492  fBAddElem->Connect("Clicked()", "TGeoMixtureEditor", this, "DoAddElem()");
493  fMaterialName->Connect("TextChanged(const char *)", "TGeoMaterialEditor", this, "DoName()");
494  fMatA->Connect("ValueSet(Long_t)", "TGeoMaterialEditor", this, "DoA()");
495  fMatZ->Connect("ValueSet(Long_t)", "TGeoMaterialEditor", this, "DoZ()");
496  fMatState->Connect("Selected(Int_t)", "TGeoMaterialEditor", this, "DoState(Int_t)");
497  fMatDensity->Connect("ValueSet(Long_t)", "TGeoMaterialEditor", this, "DoDensity()");
498  fMatTemperature->Connect("ValueSet(Long_t)", "TGeoMaterialEditor", this, "DoTemperature()");
499  fMatPressure->Connect("ValueSet(Long_t)", "TGeoMaterialEditor", this, "DoPressure()");
500  fMatRadLen->Connect("ValueSet(Long_t)", "TGeoMaterialEditor", this, "DoRadAbs()");
501  fMatAbsLen->Connect("ValueSet(Long_t)", "TGeoMaterialEditor", this, "DoRadAbs()");
502  fInit = kFALSE;
503 }
504 
505 ////////////////////////////////////////////////////////////////////////////////
506 /// Connect to the selected mixture.
507 
508 void TGeoMixtureEditor::SetModel(TObject* obj)
509 {
510  if (obj == 0 || !(obj->InheritsFrom(TGeoMixture::Class()))) {
511  SetActive(kFALSE);
512  return;
513  }
514  TGeoMaterialEditor::SetModel(obj);
515  fMixture = (TGeoMixture*)fMaterial;
516  UpdateElements();
517 }
518 
519 ////////////////////////////////////////////////////////////////////////////////
520 /// Check button state changed for fraction.
521 
522 void TGeoMixtureEditor::DoChkFraction()
523 {
524  if (fMixture->GetNelements() && fMixture->GetNmixt()) {
525  fChkFraction->SetDown(kFALSE);
526  fChkNatoms->SetDown(kTRUE);
527  return;
528  }
529  Bool_t isDown = fChkFraction->IsDown();
530  fChkNatoms->SetDown(!isDown);
531 }
532 
533 ////////////////////////////////////////////////////////////////////////////////
534 /// Check button state changed for natoms.
535 
536 void TGeoMixtureEditor::DoChkNatoms()
537 {
538  if (fMixture->GetNelements() && !fMixture->GetNmixt()) {
539  fChkFraction->SetDown(kTRUE);
540  fChkNatoms->SetDown(kFALSE);
541  return;
542  }
543  Bool_t isDown = fChkNatoms->IsDown();
544  fChkFraction->SetDown(!isDown);
545 }
546 
547 ////////////////////////////////////////////////////////////////////////////////
548 /// Fraction changed.
549 
550 void TGeoMixtureEditor::DoFraction()
551 {
552  if (fMixture->GetNelements() && fMixture->GetNmixt()) return;
553  fChkFraction->SetDown(kTRUE);
554  fChkNatoms->SetDown(kFALSE);
555 }
556 
557 ////////////////////////////////////////////////////////////////////////////////
558 /// Natoms changed.
559 
560 void TGeoMixtureEditor::DoNatoms()
561 {
562  if (fMixture->GetNelements() && !fMixture->GetNmixt()) return;
563  fChkFraction->SetDown(kFALSE);
564  fChkNatoms->SetDown(kTRUE);
565 }
566 
567 ////////////////////////////////////////////////////////////////////////////////
568 /// Slot for selecting an element.
569 
570 void TGeoMixtureEditor::DoSelectElement(Int_t ielem)
571 {
572  TGeoElement *el = gGeoManager->GetElementTable()->GetElement(ielem);
573  if (!el) {
574  Error("DoSelectElement", "No element at index %d", ielem);
575  return;
576  }
577  TString z = TString::Format("Z=%d",el->Z());
578  TString a = TString::Format("A=%d",(Int_t)el->A());
579  fAelem->SetText(a.Data());
580  fZelem->SetText(z.Data());
581 }
582 
583 ////////////////////////////////////////////////////////////////////////////////
584 /// Slot for adding an element. No undo.
585 
586 void TGeoMixtureEditor::DoAddElem()
587 {
588  Bool_t byfraction = fChkFraction->IsDown();
589  Int_t natoms = (Int_t)fNENatoms->GetNumber();
590  if (!byfraction && natoms<=0) return;
591  Double_t frac = fNEFraction->GetNumber();
592  if (byfraction && frac<=0) return;
593  TGeoElement *el = gGeoManager->GetElementTable()->GetElement(fMixElem->GetSelected());
594  if (!el) return;
595  if (byfraction) fMixture->AddElement(el, frac);
596  else fMixture->AddElement(el, natoms);
597  fTabMgr->GetMaterialEditor(fMixture);
598 }
599 
600 ////////////////////////////////////////////////////////////////////////////////
601 /// Slot for applying modifications.
602 
603 void TGeoMixtureEditor::DoApply1()
604 {
605  const char *name = fMaterialName->GetText();
606  fMaterial->SetName(name);
607 
608  fMaterial->SetDensity(fMatDensity->GetNumber());
609  fMaterial->SetTemperature(fMatTemperature->GetNumber());
610  fMaterial->SetPressure(6.2415e+8*fMatPressure->GetNumber());
611  fMaterial->SetState((TGeoMaterial::EGeoMaterialState)fMatState->GetSelected());
612 // fMaterial->SetRadLen(fMatRadLen->GetNumber(), fMatAbsLen->GetNumber());
613  fMatRadLen->SetNumber(fMaterial->GetRadLen());
614  fMatAbsLen->SetNumber(fMaterial->GetIntLen());
615  fUndo->SetEnabled();
616  fApply->SetEnabled(kFALSE);
617 }
618 
619 ////////////////////////////////////////////////////////////////////////////////
620 /// Slot for undoing all changes.
621 
622 void TGeoMixtureEditor::DoUndo1()
623 {
624  fMaterialName->SetText(fNamei.Data());
625  fMaterial->SetName(fNamei.Data());
626  fMatState->Select(fStatei);
627  fMaterial->SetState((TGeoMaterial::EGeoMaterialState)fStatei);
628  fMatDensity->SetNumber(fDensityi);
629  fMaterial->SetDensity(fDensityi);
630  fMatTemperature->SetNumber(fTempi);
631  fMaterial->SetTemperature(fTempi);
632  fMatPressure->SetNumber(fPresi);
633  fMaterial->SetPressure(fPresi*6.2415e+8);
634  fMatRadLen->SetNumber(fMaterial->GetRadLen());
635  fMatAbsLen->SetNumber(fMaterial->GetIntLen());
636  fApply->SetEnabled(kFALSE);
637  fUndo->SetEnabled(kFALSE);
638 }
639 
640 ////////////////////////////////////////////////////////////////////////////////
641 /// Update the list of elements in the TGCanvas.
642 
643 void TGeoMixtureEditor::UpdateElements()
644 {
645  fComps->RemoveAll();
646  Int_t nelem = fMixture->GetNelements();
647  for (Int_t i=0; i<nelem; i++) {
648  TString s;
649  Bool_t byfrac = (fMixture->GetNmixt())?kFALSE:kTRUE;
650  if (byfrac)
651  s.TString::Format("%d-%s-%d: Wmass = %g %%", (Int_t)fMixture->GetZmixt()[i], fMixture->GetElement(i)->GetName(),
652  (Int_t)fMixture->GetAmixt()[i],fMixture->GetWmixt()[i]);
653  else
654  s.TString::Format("%d-%s-%d: Natoms = %d", (Int_t)fMixture->GetZmixt()[i], fMixture->GetElement(i)->GetName(),
655  (Int_t)fMixture->GetAmixt()[i],fMixture->GetNmixt()[i]);
656 
657  TGLabel *label = new TGLabel(fComps, s);
658  label->SetTextJustify(kTextLeft | kTextCenterY);
659  fComps->AddFrame(label, new TGLayoutHints(kLHintsLeft | kLHintsExpandX, 1, 1, 0, 0));
660  }
661  fComps->MapSubwindows();
662 }