00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #ifndef ROOT_TPad
00013 #define ROOT_TPad
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #ifndef ROOT_TVirtualPad
00026 #include "TVirtualPad.h"
00027 #endif
00028
00029 class TVirtualViewer3D;
00030 class TVirtualPadPainter;
00031 class TBrowser;
00032 class TBox;
00033 class TLegend;
00034
00035 class TPad : public TVirtualPad {
00036
00037 private:
00038 TObject *fTip;
00039
00040 protected:
00041 Double_t fX1;
00042 Double_t fY1;
00043 Double_t fX2;
00044 Double_t fY2;
00045
00046 Double_t fXtoAbsPixelk;
00047 Double_t fXtoPixelk;
00048 Double_t fXtoPixel;
00049 Double_t fYtoAbsPixelk;
00050 Double_t fYtoPixelk;
00051 Double_t fYtoPixel;
00052
00053 Double_t fUtoAbsPixelk;
00054 Double_t fUtoPixelk;
00055 Double_t fUtoPixel;
00056 Double_t fVtoAbsPixelk;
00057 Double_t fVtoPixelk;
00058 Double_t fVtoPixel;
00059
00060 Double_t fAbsPixeltoXk;
00061 Double_t fPixeltoXk;
00062 Double_t fPixeltoX;
00063 Double_t fAbsPixeltoYk;
00064 Double_t fPixeltoYk;
00065 Double_t fPixeltoY;
00066
00067 Double_t fXlowNDC;
00068 Double_t fYlowNDC;
00069 Double_t fWNDC;
00070 Double_t fHNDC;
00071
00072 Double_t fAbsXlowNDC;
00073 Double_t fAbsYlowNDC;
00074 Double_t fAbsWNDC;
00075 Double_t fAbsHNDC;
00076
00077 Double_t fUxmin;
00078 Double_t fUymin;
00079 Double_t fUxmax;
00080 Double_t fUymax;
00081
00082 Double_t fTheta;
00083 Double_t fPhi;
00084
00085 Double_t fAspectRatio;
00086
00087 Int_t fPixmapID;
00088 Int_t fGLDevice;
00089 Bool_t fCopyGLDevice;
00090 Bool_t fEmbeddedGL;
00091 Int_t fNumber;
00092 Int_t fTickx;
00093 Int_t fTicky;
00094 Int_t fLogx;
00095 Int_t fLogy;
00096 Int_t fLogz;
00097 Int_t fPadPaint;
00098 Int_t fCrosshair;
00099 Int_t fCrosshairPos;
00100 Short_t fBorderSize;
00101 Short_t fBorderMode;
00102 Bool_t fModified;
00103 Bool_t fGridx;
00104 Bool_t fGridy;
00105 Bool_t fAbsCoord;
00106 Bool_t fEditable;
00107 Bool_t fFixedAspectRatio;
00108 TPad *fMother;
00109 TCanvas *fCanvas;
00110 TList *fPrimitives;
00111 TList *fExecs;
00112 TString fName;
00113 TString fTitle;
00114 TFrame *fFrame;
00115 TView *fView;
00116 TObject *fPadPointer;
00117 TObject *fPadView3D;
00118 static Int_t fgMaxPickDistance;
00119
00120
00121 TVirtualViewer3D *fViewer3D;
00122
00123 void DestroyExternalViewer3D();
00124 virtual Int_t DistancetoPrimitive(Int_t px, Int_t py);
00125 virtual void ExecuteEvent(Int_t event, Int_t px, Int_t py);
00126 virtual void HideToolTip(Int_t event);
00127 void PaintBorder(Color_t color, Bool_t tops);
00128 virtual void PaintBorderPS(Double_t xl,Double_t yl,Double_t xt,Double_t yt,Int_t bmode,Int_t bsize,Int_t dark,Int_t light);
00129 void PaintDate();
00130 virtual void SavePrimitive(ostream &out, Option_t *option = "");
00131 virtual void SetBatch(Bool_t batch=kTRUE);
00132
00133 private:
00134 TPad(const TPad &pad);
00135 TPad &operator=(const TPad &rhs);
00136
00137 void CopyBackgroundPixmap(Int_t x, Int_t y);
00138 void CopyBackgroundPixmaps(TPad *start, TPad *stop, Int_t x, Int_t y);
00139
00140 public:
00141
00142 enum {
00143 kFraming = BIT(6),
00144 kHori = BIT(9),
00145 kClipFrame = BIT(10),
00146 kPrintingPS = BIT(11),
00147 kCannotMove = BIT(12),
00148 kClearAfterCR = BIT(14)
00149 };
00150
00151 TPad();
00152 TPad(const char *name, const char *title, Double_t xlow,
00153 Double_t ylow, Double_t xup, Double_t yup,
00154 Color_t color=-1, Short_t bordersize=-1, Short_t bordermode=-2);
00155 virtual ~TPad();
00156 void AbsCoordinates(Bool_t set) { fAbsCoord = set; }
00157 Double_t AbsPixeltoX(Int_t px) {return fAbsPixeltoXk + px*fPixeltoX;}
00158 Double_t AbsPixeltoY(Int_t py) {return fAbsPixeltoYk + py*fPixeltoY;}
00159 virtual void AbsPixeltoXY(Int_t xpixel, Int_t ypixel, Double_t &x, Double_t &y);
00160 virtual void AddExec(const char *name, const char *command);
00161 virtual void AutoExec();
00162 virtual void Browse(TBrowser *b);
00163 virtual TLegend *BuildLegend(Double_t x1=0.5, Double_t y1=0.67, Double_t x2=0.88, Double_t y2=0.88, const char *title="");
00164 TVirtualPad* cd(Int_t subpadnumber=0);
00165 void Clear(Option_t *option="");
00166 virtual Int_t Clip(Float_t *x, Float_t *y, Float_t xclipl, Float_t yclipb, Float_t xclipr, Float_t yclipt);
00167 virtual Int_t Clip(Double_t *x, Double_t *y, Double_t xclipl, Double_t yclipb, Double_t xclipr, Double_t yclipt);
00168 virtual Int_t ClippingCode(Double_t x, Double_t y, Double_t xcl1, Double_t ycl1, Double_t xcl2, Double_t ycl2);
00169 virtual Int_t ClipPolygon(Int_t n, Double_t *x, Double_t *y, Int_t nn, Double_t *xc, Double_t *yc, Double_t xclipl, Double_t yclipb, Double_t xclipr, Double_t yclipt);
00170 virtual void Close(Option_t *option="");
00171 virtual void Closed() { Emit("Closed()"); }
00172 virtual void CopyPixmap();
00173 virtual void CopyPixmaps();
00174 virtual void DeleteExec(const char *name);
00175 virtual void Divide(Int_t nx=1, Int_t ny=1, Float_t xmargin=0.01, Float_t ymargin=0.01, Int_t color=0);
00176 virtual void Draw(Option_t *option="");
00177 virtual void DrawClassObject(const TObject *obj, Option_t *option="");
00178 static void DrawColorTable();
00179 virtual void DrawCrosshair();
00180 TH1F *DrawFrame(Double_t xmin, Double_t ymin, Double_t xmax, Double_t ymax, const char *title="");
00181
00182
00183
00184
00185 virtual void ExecuteEventAxis(Int_t event, Int_t px, Int_t py, TAxis *axis);
00186 virtual TObject *FindObject(const char *name) const;
00187 virtual TObject *FindObject(const TObject *obj) const;
00188 virtual void UseCurrentStyle();
00189 virtual Short_t GetBorderMode() const { return fBorderMode;}
00190 virtual Short_t GetBorderSize() const { return fBorderSize;}
00191 Int_t GetCrosshair() const;
00192 virtual Int_t GetCanvasID() const;
00193 virtual TCanvasImp *GetCanvasImp() const;
00194 TFrame *GetFrame();
00195 virtual Int_t GetEvent() const;
00196 virtual Int_t GetEventX() const;
00197 virtual Int_t GetEventY() const;
00198 virtual Color_t GetHighLightColor() const;
00199 virtual void GetRange(Double_t &x1, Double_t &y1, Double_t &x2, Double_t &y2);
00200 virtual void GetRangeAxis(Double_t &xmin, Double_t &ymin, Double_t &xmax, Double_t &ymax);
00201 virtual void GetPadPar(Double_t &xlow, Double_t &ylow, Double_t &xup, Double_t &yup);
00202 Double_t GetXlowNDC() const {return fXlowNDC;}
00203 Double_t GetYlowNDC() const {return fYlowNDC;}
00204 Double_t GetWNDC() const {return fWNDC;}
00205 Double_t GetHNDC() const {return fHNDC;}
00206 virtual UInt_t GetWw() const;
00207 virtual UInt_t GetWh() const;
00208 Double_t GetAbsXlowNDC() const {return fAbsXlowNDC;}
00209 Double_t GetAbsYlowNDC() const {return fAbsYlowNDC;}
00210 Double_t GetAbsWNDC() const {return fAbsWNDC;}
00211 Double_t GetAbsHNDC() const {return fAbsHNDC;}
00212 Double_t GetAspectRatio() const { return fAspectRatio; }
00213 Double_t GetPhi() const {return fPhi;}
00214 Double_t GetTheta() const {return fTheta;}
00215 Double_t GetUxmin() const {return fUxmin;}
00216 Double_t GetUymin() const {return fUymin;}
00217 Double_t GetUxmax() const {return fUxmax;}
00218 Double_t GetUymax() const {return fUymax;}
00219 Bool_t GetGridx() const {return fGridx;}
00220 Bool_t GetGridy() const {return fGridy;}
00221 Int_t GetNumber() const {return fNumber;}
00222 Int_t GetTickx() const {return fTickx;}
00223 Int_t GetTicky() const {return fTicky;}
00224 Double_t GetX1() const { return fX1; }
00225 Double_t GetX2() const { return fX2; }
00226 Double_t GetY1() const { return fY1; }
00227 Double_t GetY2() const { return fY2; }
00228 static Int_t GetMaxPickDistance();
00229 TList *GetListOfPrimitives() const {return fPrimitives;}
00230 TList *GetListOfExecs() const {return fExecs;}
00231 virtual TObject *GetPrimitive(const char *name) const;
00232 virtual TObject *GetSelected() const;
00233 virtual TVirtualPad *GetPad(Int_t subpadnumber) const;
00234 virtual TObject *GetPadPointer() const {return fPadPointer;}
00235 TVirtualPad *GetPadSave() const;
00236 TVirtualPad *GetSelectedPad() const;
00237 Int_t GetGLDevice();
00238 TView *GetView() const {return fView;}
00239 TObject *GetView3D() const {return fPadView3D;}
00240 Int_t GetLogx() const {return fLogx;}
00241 Int_t GetLogy() const {return fLogy;}
00242 Int_t GetLogz() const {return fLogz;}
00243 virtual TVirtualPad *GetMother() const {return fMother;}
00244 const char *GetName() const {return fName.Data();}
00245 const char *GetTitle() const {return fTitle.Data();}
00246 virtual TCanvas *GetCanvas() const { return fCanvas; }
00247 virtual TVirtualPad *GetVirtCanvas() const ;
00248 virtual TVirtualPadPainter *GetPainter();
00249 Int_t GetPadPaint() const {return fPadPaint;}
00250 Int_t GetPixmapID() const {return fPixmapID;}
00251 ULong_t Hash() const { return fName.Hash(); }
00252 virtual Bool_t HasCrosshair() const;
00253 void HighLight(Color_t col=kRed, Bool_t set=kTRUE);
00254 Bool_t HasFixedAspectRatio() const { return fFixedAspectRatio; }
00255 virtual Bool_t IsBatch() const;
00256 virtual Bool_t IsEditable() const {return fEditable;}
00257 Bool_t IsFolder() const {return kTRUE;}
00258 Bool_t IsModified() const {return fModified;}
00259 virtual Bool_t IsRetained() const;
00260 virtual Bool_t IsVertical() const {return !TestBit(kHori);}
00261 virtual void ls(Option_t *option="") const;
00262 void Modified(Bool_t flag=1);
00263 virtual Bool_t OpaqueMoving() const;
00264 virtual Bool_t OpaqueResizing() const;
00265 Double_t PadtoX(Double_t x) const;
00266 Double_t PadtoY(Double_t y) const;
00267 virtual void Paint(Option_t *option="");
00268 void PaintBox(Double_t x1, Double_t y1, Double_t x2, Double_t y2, Option_t *option="");
00269 void PaintFillArea(Int_t n, Float_t *x, Float_t *y, Option_t *option="");
00270 void PaintFillArea(Int_t n, Double_t *x, Double_t *y, Option_t *option="");
00271 void PaintFillAreaHatches(Int_t n, Double_t *x, Double_t *y, Int_t FillStyle);
00272 void PaintHatches(Double_t dy, Double_t angle, Int_t nn, Double_t *xx, Double_t *yy);
00273 void PaintPadFrame(Double_t xmin, Double_t ymin, Double_t xmax, Double_t ymax);
00274 void PaintLine(Double_t x1, Double_t y1, Double_t x2, Double_t y2);
00275 void PaintLineNDC(Double_t u1, Double_t v1,Double_t u2, Double_t v2);
00276 void PaintLine3D(Float_t *p1, Float_t *p2);
00277 void PaintLine3D(Double_t *p1, Double_t *p2);
00278 void PaintPolyLine(Int_t n, Float_t *x, Float_t *y, Option_t *option="");
00279 void PaintPolyLine(Int_t n, Double_t *x, Double_t *y, Option_t *option="");
00280 void PaintPolyLine3D(Int_t n, Double_t *p);
00281 void PaintPolyLineNDC(Int_t n, Double_t *x, Double_t *y, Option_t *option="");
00282 void PaintPolyMarker(Int_t n, Float_t *x, Float_t *y, Option_t *option="");
00283 void PaintPolyMarker(Int_t n, Double_t *x, Double_t *y, Option_t *option="");
00284 virtual void PaintModified();
00285 void PaintText(Double_t x, Double_t y, const char *text);
00286 void PaintTextNDC(Double_t u, Double_t v, const char *text);
00287 virtual TPad *Pick(Int_t px, Int_t py, TObjLink *&pickobj);
00288 Double_t PixeltoX(Int_t px);
00289 Double_t PixeltoY(Int_t py);
00290 virtual void PixeltoXY(Int_t xpixel, Int_t ypixel, Double_t &x, Double_t &y);
00291 virtual void Pop();
00292 virtual void Print(const char *filename="") const;
00293 virtual void Print(const char *filename, Option_t *option);
00294 virtual void Range(Double_t x1, Double_t y1, Double_t x2, Double_t y2);
00295 virtual void RangeChanged() { Emit("RangeChanged()"); }
00296 virtual void RangeAxis(Double_t xmin, Double_t ymin, Double_t xmax, Double_t ymax);
00297 virtual void RangeAxisChanged() { Emit("RangeAxisChanged()"); }
00298 virtual void RecursiveRemove(TObject *obj);
00299 virtual void RedrawAxis(Option_t *option="");
00300 virtual void ResetView3D(TObject *view=0){fPadView3D=view;}
00301 virtual void ResizePad(Option_t *option="");
00302 virtual void SaveAs(const char *filename="",Option_t *option="") const;
00303 virtual void SetBorderMode(Short_t bordermode) {fBorderMode = bordermode; Modified();}
00304 virtual void SetBorderSize(Short_t bordersize) {fBorderSize = bordersize; Modified();}
00305 void SetCanvas(TCanvas *c) { fCanvas = c; }
00306 virtual void SetCanvasSize(UInt_t ww, UInt_t wh);
00307 virtual void SetCrosshair(Int_t crhair=1);
00308 virtual void SetCursor(ECursor cursor);
00309 virtual void SetDoubleBuffer(Int_t mode=1);
00310 virtual void SetDrawOption(Option_t *option="");
00311 virtual void SetEditable(Bool_t mode=kTRUE);
00312 virtual void SetFixedAspectRatio(Bool_t fixed = kTRUE);
00313 virtual void SetGrid(Int_t valuex = 1, Int_t valuey = 1) {fGridx = valuex; fGridy = valuey; Modified();}
00314 virtual void SetGridx(Int_t value = 1) {fGridx = value; Modified();}
00315 virtual void SetGridy(Int_t value = 1) {fGridy = value; Modified();}
00316 virtual void SetFillStyle(Style_t fstyle);
00317 virtual void SetLogx(Int_t value = 1);
00318 virtual void SetLogy(Int_t value = 1);
00319 virtual void SetLogz(Int_t value = 1);
00320 virtual void SetNumber(Int_t number) {fNumber = number;}
00321 virtual void SetPad(const char *name, const char *title,
00322 Double_t xlow, Double_t ylow, Double_t xup,
00323 Double_t yup, Color_t color=35,
00324 Short_t bordersize=5, Short_t bordermode=-1);
00325 virtual void SetPad(Double_t xlow, Double_t ylow, Double_t xup, Double_t yup);
00326 virtual void SetAttFillPS(Color_t color, Style_t style);
00327 virtual void SetAttLinePS(Color_t color, Style_t style, Width_t lwidth);
00328 virtual void SetAttMarkerPS(Color_t color, Style_t style, Size_t msize);
00329 virtual void SetAttTextPS(Int_t align, Float_t angle, Color_t color, Style_t font, Float_t tsize);
00330 static void SetMaxPickDistance(Int_t maxPick=5);
00331 virtual void SetName(const char *name) {fName = name;}
00332 virtual void SetSelected(TObject *obj);
00333 virtual void SetTicks(Int_t valuex = 1, Int_t valuey = 1) {fTickx = valuex; fTicky = valuey; Modified();}
00334 virtual void SetTickx(Int_t value = 1) {fTickx = value; Modified();}
00335 virtual void SetTicky(Int_t value = 1) {fTicky = value; Modified();}
00336 virtual void SetTitle(const char *title="") {fTitle = title;}
00337 virtual void SetTheta(Double_t theta=30) {fTheta = theta; Modified();}
00338 virtual void SetPhi(Double_t phi=30) {fPhi = phi; Modified();}
00339 virtual void SetToolTipText(const char *text, Long_t delayms = 1000);
00340 virtual void SetVertical(Bool_t vert=kTRUE);
00341 virtual void SetView(TView *view = 0);
00342 virtual void SetViewer3D(TVirtualViewer3D *viewer3d) {fViewer3D = viewer3d;}
00343
00344 virtual void SetGLDevice(Int_t dev) {fGLDevice = dev;}
00345 virtual void SetCopyGLDevice(Bool_t copy) {fCopyGLDevice = copy;}
00346
00347 virtual void Update();
00348
00349
00350
00351
00352 Int_t UtoAbsPixel(Double_t u) const {return Int_t(fUtoAbsPixelk + u*fUtoPixel);}
00353 Int_t VtoAbsPixel(Double_t v) const {return Int_t(fVtoAbsPixelk + v*fVtoPixel);}
00354 Int_t UtoPixel(Double_t u) const;
00355 Int_t VtoPixel(Double_t v) const;
00356 virtual TObject *WaitPrimitive(const char *pname="", const char *emode="");
00357 Int_t XtoAbsPixel(Double_t x) const;
00358 Int_t YtoAbsPixel(Double_t y) const;
00359 Double_t XtoPad(Double_t x) const;
00360 Double_t YtoPad(Double_t y) const;
00361 Int_t XtoPixel(Double_t x) const;
00362 Int_t YtoPixel(Double_t y) const;
00363 virtual void XYtoAbsPixel(Double_t x, Double_t y, Int_t &xpixel, Int_t &ypixel) const;
00364 virtual void XYtoPixel(Double_t x, Double_t y, Int_t &xpixel, Int_t &ypixel) const;
00365
00366 virtual TObject *CreateToolTip(const TBox *b, const char *text, Long_t delayms);
00367 virtual void DeleteToolTip(TObject *tip);
00368 virtual void ResetToolTip(TObject *tip);
00369 virtual void CloseToolTip(TObject *tip);
00370
00371 virtual void x3d(Option_t *type="");
00372
00373 virtual TVirtualViewer3D *GetViewer3D(Option_t * type = "");
00374 virtual Bool_t HasViewer3D() const { return (fViewer3D); }
00375 virtual void ReleaseViewer3D(Option_t * type = "");
00376
00377 virtual void RecordPave(const TObject *obj);
00378 virtual void RecordLatex(const TObject *obj);
00379 virtual void EventPave() { Emit("EventPave()"); }
00380 virtual void StartEditing() { Emit("StartEditing()"); }
00381
00382 ClassDef(TPad,10)
00383 };
00384
00385
00386
00387
00388
00389 inline void TPad::Modified(Bool_t flag)
00390 {
00391 if (!fModified && flag) Emit("Modified()");
00392 fModified = flag;
00393 }
00394
00395
00396 inline void TPad::AbsPixeltoXY(Int_t xpixel, Int_t ypixel, Double_t &x, Double_t &y)
00397 {
00398 x = AbsPixeltoX(xpixel);
00399 y = AbsPixeltoY(ypixel);
00400 }
00401
00402
00403 inline Double_t TPad::PixeltoX(Int_t px)
00404 {
00405 if (fAbsCoord) return fAbsPixeltoXk + px*fPixeltoX;
00406 else return fPixeltoXk + px*fPixeltoX;
00407 }
00408
00409
00410 inline Double_t TPad::PixeltoY(Int_t py)
00411 {
00412 if (fAbsCoord) return fAbsPixeltoYk + py*fPixeltoY;
00413 else return fPixeltoYk + py*fPixeltoY;
00414 }
00415
00416
00417 inline void TPad::PixeltoXY(Int_t xpixel, Int_t ypixel, Double_t &x, Double_t &y)
00418 {
00419 x = PixeltoX(xpixel);
00420 y = PixeltoY(ypixel);
00421 }
00422
00423
00424 inline Int_t TPad::UtoPixel(Double_t u) const
00425 {
00426 Double_t val;
00427 if (fAbsCoord) val = fUtoAbsPixelk + u*fUtoPixel;
00428 else val = u*fUtoPixel;
00429 if (val < -kMaxPixel) return -kMaxPixel;
00430 if (val > kMaxPixel) return kMaxPixel;
00431 return Int_t(val);
00432 }
00433
00434
00435 inline Int_t TPad::VtoPixel(Double_t v) const
00436 {
00437 Double_t val;
00438 if (fAbsCoord) val = fVtoAbsPixelk + v*fVtoPixel;
00439 else val = fVtoPixelk + v*fVtoPixel;
00440 if (val < -kMaxPixel) return -kMaxPixel;
00441 if (val > kMaxPixel) return kMaxPixel;
00442 return Int_t(val);
00443 }
00444
00445
00446 inline Int_t TPad::XtoAbsPixel(Double_t x) const
00447 {
00448 Double_t val = fXtoAbsPixelk + x*fXtoPixel;
00449 if (val < -kMaxPixel) return -kMaxPixel;
00450 if (val > kMaxPixel) return kMaxPixel;
00451 return Int_t(val);
00452 }
00453
00454
00455 inline Int_t TPad::XtoPixel(Double_t x) const
00456 {
00457 Double_t val;
00458 if (fAbsCoord) val = fXtoAbsPixelk + x*fXtoPixel;
00459 else val = fXtoPixelk + x*fXtoPixel;
00460 if (val < -kMaxPixel) return -kMaxPixel;
00461 if (val > kMaxPixel) return kMaxPixel;
00462 return Int_t(val);
00463 }
00464
00465
00466 inline Int_t TPad::YtoAbsPixel(Double_t y) const
00467 {
00468 Double_t val = fYtoAbsPixelk + y*fYtoPixel;
00469 if (val < -kMaxPixel) return -kMaxPixel;
00470 if (val > kMaxPixel) return kMaxPixel;
00471 return Int_t(val);
00472 }
00473
00474
00475 inline Int_t TPad::YtoPixel(Double_t y) const
00476 {
00477 Double_t val;
00478 if (fAbsCoord) val = fYtoAbsPixelk + y*fYtoPixel;
00479 else val = fYtoPixelk + y*fYtoPixel;
00480 if (val < -kMaxPixel) return -kMaxPixel;
00481 if (val > kMaxPixel) return kMaxPixel;
00482 return Int_t(val);
00483 }
00484
00485
00486 inline void TPad::XYtoAbsPixel(Double_t x, Double_t y, Int_t &xpixel, Int_t &ypixel) const
00487 {
00488 xpixel = XtoAbsPixel(x);
00489 ypixel = YtoAbsPixel(y);
00490 }
00491
00492
00493 inline void TPad::XYtoPixel(Double_t x, Double_t y, Int_t &xpixel, Int_t &ypixel) const
00494 {
00495 xpixel = XtoPixel(x);
00496 ypixel = YtoPixel(y);
00497 }
00498
00499
00500 inline void TPad::SetDrawOption(Option_t *)
00501 { }
00502
00503 #endif