// @(#):$Id$ // Author: M.Gheata /************************************************************************* * Copyright (C) 1995-2002, Rene Brun and Fons Rademakers. * * All rights reserved. * * * * For the licensing terms see $ROOTSYS/LICENSE. * * For the list of contributors see $ROOTSYS/README/CREDITS. * *************************************************************************/ ////////////////////////////////////////////////////////////////////////// // // // TGeoHypeEditor // // // ////////////////////////////////////////////////////////////////////////// //Begin_Html /* */ //End_Html //Begin_Html /* */ //End_Html #include "TGeoHypeEditor.h" #include "TGeoTabManager.h" #include "TGeoHype.h" #include "TGeoManager.h" #include "TVirtualGeoPainter.h" #include "TPad.h" #include "TView.h" #include "TMath.h" #include "TGTab.h" #include "TGComboBox.h" #include "TGButton.h" #include "TGTextEntry.h" #include "TGNumberEntry.h" #include "TGLabel.h" ClassImp(TGeoHypeEditor) enum ETGeoHypeWid { kHYPE_NAME, kHYPE_RIN, kHYPE_ROUT, kHYPE_DZ, kHYPE_STIN, kHYPE_STOUT, kHYPE_APPLY, kHYPE_UNDO }; //______________________________________________________________________________ TGeoHypeEditor::TGeoHypeEditor(const TGWindow *p, Int_t width, Int_t height, UInt_t options, Pixel_t back) : TGeoGedFrame(p, width, height, options | kVerticalFrame, back) { // Constructor for Hype editor fShape = 0; fRini = fRouti = fStIni = fStOuti = 0.0; fNamei = ""; fIsModified = kFALSE; fIsShapeEditable = kTRUE; // TextEntry for shape name MakeTitle("Name"); fShapeName = new TGTextEntry(this, new TGTextBuffer(50), kHYPE_NAME); fShapeName->Resize(135, fShapeName->GetDefaultHeight()); fShapeName->SetToolTipText("Enter the hyperboloid name"); fShapeName->Associate(this); AddFrame(fShapeName, new TGLayoutHints(kLHintsLeft, 3, 1, 2, 5)); TGTextEntry *nef; MakeTitle("Dimensions"); // Number entry for Rin TGCompositeFrame *f1 = new TGCompositeFrame(this, 155, 10, kHorizontalFrame | kFixedWidth); f1->AddFrame(new TGLabel(f1, "Rin"), new TGLayoutHints(kLHintsLeft, 1, 1, 6, 0)); fERin = new TGNumberEntry(f1, 0., 5, kHYPE_RIN); fERin->SetNumAttr(TGNumberFormat::kNEAPositive); fERin->Resize(100, fERin->GetDefaultHeight()); nef = (TGTextEntry*)fERin->GetNumberEntry(); nef->SetToolTipText("Enter the inner radius "); fERin->Associate(this); f1->AddFrame(fERin, new TGLayoutHints(kLHintsRight, 2, 2, 4, 4)); AddFrame(f1, new TGLayoutHints(kLHintsLeft, 2, 2, 4, 4)); // Number entry for Rout f1 = new TGCompositeFrame(this, 155, 10, kHorizontalFrame | kFixedWidth); f1->AddFrame(new TGLabel(f1, "Rout"), new TGLayoutHints(kLHintsLeft, 1, 1, 6, 0)); fERout = new TGNumberEntry(f1, 0., 5, kHYPE_ROUT); fERout->SetNumAttr(TGNumberFormat::kNEAPositive); fERout->Resize(100, fERout->GetDefaultHeight()); nef = (TGTextEntry*)fERout->GetNumberEntry(); nef->SetToolTipText("Enter the outer radius"); fERout->Associate(this); f1->AddFrame(fERout, new TGLayoutHints(kLHintsRight, 2, 2, 4, 4)); AddFrame(f1, new TGLayoutHints(kLHintsLeft, 2, 2, 4, 4)); // Number entry for Dz f1 = new TGCompositeFrame(this, 155, 10, kHorizontalFrame | kFixedWidth); f1->AddFrame(new TGLabel(f1, "Dz"), new TGLayoutHints(kLHintsLeft, 1, 1, 6, 0)); fEDz = new TGNumberEntry(f1, 0., 5, kHYPE_DZ); fEDz->SetNumAttr(TGNumberFormat::kNEAPositive); fEDz->Resize(100, fEDz->GetDefaultHeight()); nef = (TGTextEntry*)fEDz->GetNumberEntry(); nef->SetToolTipText("Enter the half-lenth in Dz"); fEDz->Associate(this); f1->AddFrame(fEDz, new TGLayoutHints(kLHintsRight, 2, 2, 4, 4)); AddFrame(f1, new TGLayoutHints(kLHintsLeft, 2, 2, 4, 4)); // Number entry for StIn. f1 = new TGCompositeFrame(this, 155, 10, kHorizontalFrame | kFixedWidth); f1->AddFrame(new TGLabel(f1, "StIn"), new TGLayoutHints(kLHintsLeft, 1, 1, 6, 0)); fEStIn = new TGNumberEntry(f1, 0., 5, kHYPE_STIN); fEStIn->Resize(100, fEStIn->GetDefaultHeight()); nef = (TGTextEntry*)fEStIn->GetNumberEntry(); nef->SetToolTipText("Enter the stereo angle for inner surface"); fEStIn->Associate(this); f1->AddFrame(fEStIn, new TGLayoutHints(kLHintsRight, 2, 2, 4, 4)); AddFrame(f1, new TGLayoutHints(kLHintsLeft, 2, 2, 4, 4)); // Number entry for StOut. f1 = new TGCompositeFrame(this, 155, 10, kHorizontalFrame | kFixedWidth); f1->AddFrame(new TGLabel(f1, "StOut"), new TGLayoutHints(kLHintsLeft, 1, 1, 6, 0)); fEStOut = new TGNumberEntry(f1, 0., 5, kHYPE_STOUT); fEStOut->SetNumAttr(TGNumberFormat::kNEAPositive); fEStOut->Resize(100, fEStOut->GetDefaultHeight()); nef = (TGTextEntry*)fEStOut->GetNumberEntry(); nef->SetToolTipText("Enter the stereo angle for outer surface"); fEStOut->Associate(this); f1->AddFrame(fEStOut, new TGLayoutHints(kLHintsRight, 2, 2, 4, 4)); AddFrame(f1, new TGLayoutHints(kLHintsLeft, 2, 2, 4, 4)); // Delayed draw f1 = new TGCompositeFrame(this, 155, 10, kHorizontalFrame | kFixedWidth | kSunkenFrame); fDelayed = new TGCheckButton(f1, "Delayed draw"); f1->AddFrame(fDelayed, new TGLayoutHints(kLHintsLeft , 2, 2, 4, 4)); AddFrame(f1, new TGLayoutHints(kLHintsLeft, 6, 6, 4, 4)); // Buttons f1 = new TGCompositeFrame(this, 155, 10, kHorizontalFrame | kFixedWidth); fApply = new TGTextButton(f1, "Apply"); f1->AddFrame(fApply, new TGLayoutHints(kLHintsLeft, 2, 2, 4, 4)); fApply->Associate(this); fUndo = new TGTextButton(f1, "Undo"); f1->AddFrame(fUndo, new TGLayoutHints(kLHintsRight , 2, 2, 4, 4)); fUndo->Associate(this); AddFrame(f1, new TGLayoutHints(kLHintsLeft, 6, 6, 4, 4)); fUndo->SetSize(fApply->GetSize()); } //______________________________________________________________________________ TGeoHypeEditor::~TGeoHypeEditor() { // Destructor TGFrameElement *el; TIter next(GetList()); while ((el = (TGFrameElement *)next())) { if (el->fFrame->IsComposite()) TGeoTabManager::Cleanup((TGCompositeFrame*)el->fFrame); } Cleanup(); } //______________________________________________________________________________ void TGeoHypeEditor::ConnectSignals2Slots() { // Connect signals to slots. fApply->Connect("Clicked()", "TGeoHypeEditor", this, "DoApply()"); fUndo->Connect("Clicked()", "TGeoHypeEditor", this, "DoUndo()"); fShapeName->Connect("TextChanged(const char *)", "TGeoHypeEditor", this, "DoModified()"); fERin->Connect("ValueSet(Long_t)", "TGeoHypeEditor", this, "DoRin()"); fERout->Connect("ValueSet(Long_t)", "TGeoHypeEditor", this, "DoRout()"); fEDz->Connect("ValueSet(Long_t)", "TGeoHypeEditor", this, "DoDz()"); fEStIn->Connect("ValueSet(Long_t)", "TGeoHypeEditor", this, "DoStIn()"); fEStOut->Connect("ValueSet(Long_t)", "TGeoHypeEditor", this, "DoStOut()"); fERin->GetNumberEntry()->Connect("TextChanged(const char *)", "TGeoHypeEditor", this, "DoModified()"); fERout->GetNumberEntry()->Connect("TextChanged(const char *)", "TGeoHypeEditor", this, "DoModified()"); fEDz->GetNumberEntry()->Connect("TextChanged(const char *)", "TGeoHypeEditor", this, "DoModified()"); fEStIn->GetNumberEntry()->Connect("TextChanged(const char *)", "TGeoHypeEditor", this, "DoModified()"); fEStOut->GetNumberEntry()->Connect("TextChanged(const char *)", "TGeoHypeEditor", this, "DoModified()"); fInit = kFALSE; } //______________________________________________________________________________ void TGeoHypeEditor::SetModel(TObject* obj) { // Connect to the selected object. if (obj == 0 || (obj->IsA()!=TGeoHype::Class())) { SetActive(kFALSE); return; } fShape = (TGeoHype*)obj; fRini = fShape->GetRmin(); fRouti = fShape->GetRmax(); fDzi = fShape->GetDz(); fStIni = fShape->GetStIn(); fStOuti = fShape->GetStOut(); const char *sname = fShape->GetName(); if (!strcmp(sname, fShape->ClassName())) fShapeName->SetText("-no_name"); else { fShapeName->SetText(sname); fNamei = sname; } fERin->SetNumber(fRini); fERout->SetNumber(fRouti); fEDz->SetNumber(fDzi); fEStIn->SetNumber(fStIni); fEStOut->SetNumber(fStOuti); fApply->SetEnabled(kFALSE); fUndo->SetEnabled(kFALSE); if (fInit) ConnectSignals2Slots(); SetActive(); } //______________________________________________________________________________ Bool_t TGeoHypeEditor::IsDelayed() const { // Check if shape drawing is delayed. return (fDelayed->GetState() == kButtonDown); } //______________________________________________________________________________ void TGeoHypeEditor::DoName() { // Slot for name. DoModified(); } //______________________________________________________________________________ void TGeoHypeEditor::DoApply() { // Slot for applying current settings. const char *name = fShapeName->GetText(); if (strcmp(name,fShape->GetName())) fShape->SetName(name); Double_t rin = fERin->GetNumber(); Double_t rout = fERout->GetNumber(); Double_t dz = fEDz->GetNumber(); Double_t stin = fEStIn->GetNumber(); Double_t stout = fEStOut->GetNumber(); Double_t tin = TMath::Tan(stin*TMath::DegToRad()); Double_t tout = TMath::Tan(stout*TMath::DegToRad()); if ((dz<=0) || (rin<0) || (rin>rout) || (rin*rin+tin*tin*dz*dz > rout*rout+tout*tout*dz*dz)) { fUndo->SetEnabled(); fApply->SetEnabled(kFALSE); return; } Double_t param[5]; param[0] = dz; param[1] = rin; param[2] = stin; param[3] = rout; param[4] = stout; fShape->SetDimensions(param); fShape->ComputeBBox(); fUndo->SetEnabled(); fApply->SetEnabled(kFALSE); if (fPad) { if (gGeoManager && gGeoManager->GetPainter() && gGeoManager->GetPainter()->IsPaintingShape()) { TView *view = fPad->GetView(); if (!view) { fShape->Draw(); fPad->GetView()->ShowAxis(); } else { view->SetRange(-fShape->GetDX(), -fShape->GetDY(), -fShape->GetDZ(), fShape->GetDX(), fShape->GetDY(), fShape->GetDZ()); Update(); } } else Update(); } } //______________________________________________________________________________ void TGeoHypeEditor::DoModified() { // Slot for notifying modifications. fApply->SetEnabled(); } //______________________________________________________________________________ void TGeoHypeEditor::DoUndo() { // Slot for undoing last operation. fERin->SetNumber(fRini); fERout->SetNumber(fRouti); fEDz->SetNumber(fDzi); fEStIn->SetNumber(fStIni); fEStOut->SetNumber(fStOuti); DoApply(); fUndo->SetEnabled(kFALSE); fApply->SetEnabled(kFALSE); } //______________________________________________________________________________ void TGeoHypeEditor::DoRin() { // Slot for Rin. Double_t rin = fERin->GetNumber(); Double_t rout = fERout->GetNumber(); Double_t dz = fEDz->GetNumber(); Double_t stin = fEStIn->GetNumber(); Double_t stout = fEStOut->GetNumber(); Double_t tin = TMath::Tan(stin*TMath::DegToRad()); Double_t tout = TMath::Tan(stout*TMath::DegToRad()); if (rin<0) { rin = 0; fERin->SetNumber(rin); } Double_t rinmax = TMath::Sqrt((rout*rout+tout*tout*dz*dz)/(tin*tin*dz*dz)); rinmax = TMath::Min(rinmax, rout); if (rin > rinmax) { rin = rinmax-1.e-6; fERin->SetNumber(rin); } DoModified(); if (!IsDelayed()) DoApply(); } //______________________________________________________________________________ void TGeoHypeEditor::DoRout() { // Slot for Rout. Double_t rin = fERin->GetNumber(); Double_t rout = fERout->GetNumber(); Double_t dz = fEDz->GetNumber(); Double_t stin = fEStIn->GetNumber(); Double_t stout = fEStOut->GetNumber(); Double_t tin = TMath::Tan(stin*TMath::DegToRad()); Double_t tout = TMath::Tan(stout*TMath::DegToRad()); Double_t routmin = TMath::Sqrt((rin*rin+tin*tin*dz*dz)/(tout*tout*dz*dz)); routmin = TMath::Max(routmin,rin); if (rout < routmin) { rout = routmin+1.e-6; fERout->SetNumber(rout); } DoModified(); if (!IsDelayed()) DoApply(); } //______________________________________________________________________________ void TGeoHypeEditor::DoDz() { // Slot for Z. Double_t rin = fERin->GetNumber(); Double_t rout = fERout->GetNumber(); Double_t dz = fEDz->GetNumber(); Double_t stin = fEStIn->GetNumber(); Double_t stout = fEStOut->GetNumber(); if (TMath::Abs(stin-stout)<1.e-6) { stin = stout+1.; fEStIn->SetNumber(stin); } Double_t tin = TMath::Tan(stin*TMath::DegToRad()); Double_t tout = TMath::Tan(stout*TMath::DegToRad()); if (dz<=0) { dz = 0.1; fEDz->SetNumber(dz); } Double_t dzmax = TMath::Sqrt((rout*rout-rin*rin)/(tin*tin-tout*tout)); if (dz>dzmax) { dz = dzmax; fEDz->SetNumber(dz); } DoModified(); if (!IsDelayed()) DoApply(); } //______________________________________________________________________________ void TGeoHypeEditor::DoStIn() { // Slot for StIn. Double_t rin = fERin->GetNumber(); Double_t rout = fERout->GetNumber(); Double_t dz = fEDz->GetNumber(); Double_t stin = fEStIn->GetNumber(); Double_t stout = fEStOut->GetNumber(); if (stin >= 90) { stin = 89.; fEStIn->SetNumber(stin); } Double_t tin = TMath::Tan(stin*TMath::DegToRad()); Double_t tout = TMath::Tan(stout*TMath::DegToRad()); Double_t tinmax = TMath::Sqrt(tout*tout+(rout*rout-rin*rin)/(dz*dz)); if (tin>tinmax) { tin = tinmax-1.e-6; stin = TMath::RadToDeg()*TMath::ATan(tin); fEStIn->SetNumber(stin); } DoModified(); if (!IsDelayed()) DoApply(); } //______________________________________________________________________________ void TGeoHypeEditor::DoStOut() { // Slot for StOut. Double_t rin = fERin->GetNumber(); Double_t rout = fERout->GetNumber(); Double_t dz = fEDz->GetNumber(); Double_t stin = fEStIn->GetNumber(); Double_t stout = fEStOut->GetNumber(); if (stout > 90) { stout = 89; fEStOut->SetNumber(stout); } Double_t tin = TMath::Tan(stin*TMath::DegToRad()); Double_t tout = TMath::Tan(stout*TMath::DegToRad()); Double_t tinmin = TMath::Sqrt((rout*rout-rin*rin)/(dz*dz)); if (tin < tinmin) { tin = tinmin; stin = TMath::RadToDeg()*TMath::ATan(tin); fEStIn->SetNumber(stin); } Double_t toutmin = TMath::Sqrt(tin*tin -tinmin*tinmin); if (tout < toutmin) { tout = toutmin+1.e-6; stout = TMath::RadToDeg()*TMath::ATan(tout); fEStOut->SetNumber(stout); } DoModified(); if (!IsDelayed()) DoApply(); }