/* author: Sascha Zelzer * date: 11.04.2002 * descr: testing the behaviour of a TGCanvas, when one just wants a * vertical scrolling an normal layout management in the * x direction (e.g. expand/shrink horizontally). * Derived class MyTGCanvas just rewrites the TGCanvas::Layout() * function, by adding lines marked with // **** */ #include #include #include #include #include #include #include class MyTGCanvas : public TGCanvas { public: MyTGCanvas(const TGWindow* p, UInt_t w, UInt_t h, UInt_t options = kSunkenFrame|kDoubleBorder, ULong_t back = fgDefaultFrameBackground) : TGCanvas(p, w, h, options, back) {} virtual ~MyTGCanvas() {} virtual void Layout(); }; class MainFrame { public: MainFrame(Bool_t mycanv = kFALSE); virtual ~MainFrame(); private: TGMainFrame *pMainFr; TGCanvas *pCanv; MyTGCanvas *pMyCanv; TGCompositeFrame *pMainCont, *pCont; TGTextEntry *pTE; TGTextButton *pBt; TGLayoutHints *pL; }; void MyTGCanvas::Layout() { // Create layout for canvas. Depending on the size of the container // we need to add the scrollbars. Bool_t need_vsb, need_hsb; UInt_t cw, ch, tcw, tch; need_vsb = need_hsb = kFALSE; TGFrame *container = fVport->GetContainer(); if (!container) { Error("Layout", "no canvas container set yet"); return; } Bool_t fixedw = (container->GetOptions() & kFixedWidth) ? kTRUE : kFALSE; Bool_t fixedh = (container->GetOptions() & kFixedHeight) ? kTRUE : kFALSE; // **** ------- additional booleans ------------------------ Bool_t fitw = (container->GetOptions() & kFitWidth) ? kTRUE : kFALSE; Bool_t fith = (container->GetOptions() & kFitHeight) ? kTRUE : kFALSE; // **** ---------------------------------------------------- // test whether we need scrollbars cw = fWidth - (fBorderWidth << 1); ch = fHeight - (fBorderWidth << 1); if (!fixedw) container->SetWidth(cw); if (!fixedh) container->SetHeight(ch); if (container->GetDefaultWidth() > cw) { if (fScrolling & kCanvasScrollHorizontal) { need_hsb = kTRUE; ch -= fHScrollbar->GetDefaultHeight(); if ((Int_t) ch < 0) { //Warning("Layout", "height would become too small, setting to 10"); ch = 10; } if (!fixedh) container->SetHeight(ch); } } if (container->GetDefaultHeight() > ch) { if (fScrolling & kCanvasScrollVertical) { need_vsb = kTRUE; cw -= fVScrollbar->GetDefaultWidth(); if ((Int_t) cw < 0) { //Warning("Layout", "width would become too small, setting to 10"); cw = 10; } if (!fixedw) container->SetWidth(cw); } } // re-check again (putting the vertical scrollbar could have changed things) if (container->GetDefaultWidth() > cw) { if (!need_hsb) { if (fScrolling & kCanvasScrollHorizontal) { need_hsb = kTRUE; ch -= fHScrollbar->GetDefaultHeight(); if ((Int_t) ch < 0) { //Warning("Layout", "height would become too small, setting to 10"); ch = 10; } if (!fixedh) container->SetHeight(ch); } } } if (need_hsb) { fHScrollbar->MoveResize(fBorderWidth, ch+fBorderWidth, cw, fHScrollbar->GetDefaultHeight()); fHScrollbar->MapWindow(); } else { fHScrollbar->UnmapWindow(); fHScrollbar->SetPosition(0); } if (need_vsb) { fVScrollbar->MoveResize(cw+fBorderWidth, fBorderWidth, fVScrollbar->GetDefaultWidth(), ch); fVScrollbar->MapWindow(); } else { fVScrollbar->UnmapWindow(); fVScrollbar->SetPosition(0); } fVport->MoveResize(fBorderWidth, fBorderWidth, cw, ch); tcw = TMath::Max(container->GetDefaultWidth(), cw); tch = TMath::Max(container->GetDefaultHeight(), ch); UInt_t curw = container->GetDefaultWidth(); container->SetWidth(0); // force a resize in TGFrame::Resize if (fixedw && fixedh) container->Resize(curw, container->GetDefaultHeight()); else if (fixedw) container->Resize(curw, tch); else if (fixedh) container->Resize(tcw, container->GetDefaultHeight()); // **** ----- Additional tests -------------------- else if (fitw && fith) container->Resize(cw, ch); else if (fitw) container->Resize(cw, tch); else if (fith) container->Resize(tch, ch); // **** ----- Maybe other possible combinations ---------- else container->Resize(tcw, tch); if (need_hsb) fHScrollbar->SetRange(container->GetWidth(), fVport->GetWidth()); if (need_vsb) fVScrollbar->SetRange(container->GetHeight(), fVport->GetHeight()); } MainFrame::MainFrame(Bool_t mycanv) { pMainFr = new TGMainFrame(gClient->GetRoot(), 300, 200); if (mycanv) { pCanv = new MyTGCanvas(pMainFr, 300, 200, kFitWidth | kFitHeight); pMainFr->SetWindowName("MyTGCanvas"); } else { pCanv = new TGCanvas(pMainFr, 300, 200, kFitWidth | kFitHeight); pMainFr->SetWindowName("TGCanvas"); } // container for the TGCanvas, which should expand horiz. pCont = new TGCompositeFrame(pCanv, 300, 200, kVerticalFrame | kFitWidth); pCanv->SetContainer(pCont); pCanv->SetScrolling(TGCanvas::kCanvasScrollVertical); pTE = new TGTextEntry(pCont, ""); pBt = new TGTextButton(pCont, "Button"); pCanv->AddFrame(pTE, pL = new TGLayoutHints(kLHintsLeft | kLHintsTop | kLHintsExpandX, 2, 2, 2, 2)); pCanv->AddFrame(pBt, pL); pMainFr->AddFrame(pCanv, pL = new TGLayoutHints(kLHintsLeft | kLHintsTop | kLHintsExpandX | kLHintsExpandY)); pMainFr->MapSubwindows(); pMainFr->MapWindow(); pMainFr->Layout(); } MainFrame::~MainFrame() { delete pTE; delete pBt; delete pCont; delete pCanv; delete pMainFr; } void tgcanvastest() { new MainFrame(kTRUE); new MainFrame(kFALSE); } //----- standalone program ------------------ #ifdef STANDALONE TROOT root("TGCanvas", "TGCanvas testing"); int main(int argc, char **argv) { TApplication theApp("App", &argc, argv); if (gROOT->IsBatch()) { fprintf(stderr, "%s: cannot run in batch mode\n", argv[0]); return 1; } tgcanvastest(); theApp.Run(); return 0; } #endif