00001 // @(#)root/gui:$Id: TGXYLayout.cxx 31685 2009-12-08 16:33:13Z bellenot $ 00002 // Author: Reiner Rohlfs 24/03/2002 00003 00004 /************************************************************************* 00005 * Copyright (C) 1995-2001, Rene Brun, Fons Rademakers and Reiner Rohlfs * 00006 * All rights reserved. * 00007 * * 00008 * For the licensing terms see $ROOTSYS/LICENSE. * 00009 * For the list of contributors see $ROOTSYS/README/CREDITS. * 00010 *************************************************************************/ 00011 00012 ////////////////////////////////////////////////////////////////////////// 00013 // // 00014 // TGXYLayout // 00015 // // 00016 // Is a layout manager where the position and the size of each widget // 00017 // in the frame are defined by X / Y - coordinates. The coordinates // 00018 // for each widget are defined by the TGXYLayoutHints. Therefore it // 00019 // is not possible to share a layout hint for several widgets. // 00020 // // 00021 // The coordinates (X, Y) and the size (W, H) are defined in units // 00022 // of the size of a typical character. Also the size of the // 00023 // TGCompositeFrame for which a TGXYLayout manager is used has to be // 00024 // defined in its constructor in units of the size of a character! // 00025 // // 00026 // It is not possible to use any other layout hint than the // 00027 // TGXYLayoutHints for this layout manager! // 00028 // // 00029 // The rubberFlag in the constructor of the TGLXYLayoutHins defines // 00030 // how the position and the size of a widget is recalculated if the // 00031 // size of the frame is increased: // 00032 // - kLRubberX: The X - position (left edge) is increased by the same // 00033 // factor as the width of the frame increases. // 00034 // - kLRubberY: The Y - position (upper edge) is increased by the same // 00035 // factor as the height of the frame increases. // 00036 // - kLRubberW: The width of the widget is increased by the same // 00037 // factor as the width of the frame increases. // 00038 // - kLRubberH: The height of the widget is increased by the same // 00039 // factor as the height of the frame increases. // 00040 // But the size never becomes smaller than defined by the // 00041 // TGXYLayoutHints and the X and Y coordinates becomes never smaller // 00042 // than defined by the layout hints. // 00043 // // 00044 // TGXYLayoutHints // 00045 // // 00046 // This layout hint must be used for the TGXYLouyout manager! // 00047 // // 00048 // // 00049 // Example how to use this layout manager: // 00050 // // 00051 // TGMyFrame::TGMyFrame() // 00052 // : TGMainFrame(gClient->GetRoot(), 30, 12) // 00053 // // frame is 30 character long and 12 character heigh // 00054 // { // 00055 // SetLayoutManager(new TGXYLayout(this)); // 00056 // // 00057 // // create a button of size 8 X 1.8 at position 20 / 1 // 00058 // TGTextButton * button; // 00059 // button = new TGTextButton(this, "&Apply", 1); // 00060 // AddFrame(button, new TGXYLayoutHints(20, 1, 8, 1.8)); // 00061 // // 00062 // // create a listbox of size 18 X 10 at position 1 / 1. // 00063 // // The height will increase if the frame height increases // 00064 // TGListBox * listBox; // 00065 // listBox = new TGListBox(this, 2); // 00066 // AddFrame(listBox, new TGXYLayoutHints(1, 1, 18, 10, // 00067 // TGXYLayoutHints::kLRubberX | // 00068 // TGXYLayoutHints::kLRubberY | // 00069 // TGXYLayoutHints::kLRubberH )); // 00070 // . // 00071 // . // 00072 // . // 00073 // } // 00074 // // 00075 // Normaly there is one layout hint per widget. Therefore these // 00076 // can be deleted like in the following example in the desctuctor // 00077 // of the frame: // 00078 // // 00079 // TGMyFrame::~TGMyFrame() // 00080 // { // 00081 // // Destructor, deletes all frames and their layout hints. // 00082 // // 00083 // TGFrameElement *ptr; // 00084 // // 00085 // // delete all frames and layout hints // 00086 // if (fList) { // 00087 // TIter next(fList); // 00088 // while ((ptr = (TGFrameElement *) next())) { // 00089 // if (ptr->fLayout) // 00090 // delete ptr->fLayout; // 00091 // if (ptr->fFrame) // 00092 // delete ptr->fFrame; // 00093 // } // 00094 // } // 00095 // } // 00096 // // 00097 ////////////////////////////////////////////////////////////////////////// 00098 00099 #include "TGXYLayout.h" 00100 #include "TGFrame.h" 00101 #include "TGLabel.h" 00102 #include "Riostream.h" 00103 00104 00105 ClassImp(TGXYLayout) 00106 ClassImp(TGXYLayoutHints) 00107 00108 //______________________________________________________________________________ 00109 TGXYLayoutHints::TGXYLayoutHints(Double_t x, Double_t y, Double_t w, Double_t h, 00110 UInt_t rubberFlag) 00111 : TGLayoutHints(kLHintsNormal, 0,0,0,0) 00112 { 00113 // Constructor. The x, y, w and h define the position of the widget in 00114 // its frame and the size of the widget. The unit is the size of a 00115 // character. The rubberFlag defines how to move and to resize the 00116 // widget when the frame is resized. Default is moving the X and Y 00117 // position but keep the size of the widget. 00118 00119 fX = x; 00120 fY = y; 00121 fW = w; 00122 fH = h; 00123 fFlag = rubberFlag; 00124 } 00125 00126 //______________________________________________________________________________ 00127 void TGXYLayoutHints::SavePrimitive(ostream &out, Option_t * /*option = ""*/) 00128 { 00129 // Save XY layout hints as a C++ statement(s) on output stream. 00130 00131 TString flag = ""; 00132 if (fFlag & kLRubberX) { 00133 if (flag.Length() == 0) flag = "TGXYLayoutHints::kLRubberX"; 00134 else flag += " | TGXYLayoutHints::kLRubberX"; 00135 } 00136 if (fFlag & kLRubberY) { 00137 if (flag.Length() == 0) flag = "TGXYLayoutHints::kLRubberY"; 00138 else flag += " | TGXYLayoutHints::kLRubberY"; 00139 } 00140 if (fFlag & kLRubberW) { 00141 if (flag.Length() == 0) flag = "TGXYLayoutHints::kLRubberW"; 00142 else flag += " | TGXYLayoutHints::kLRubberW"; 00143 } 00144 if (fFlag & kLRubberH) { 00145 if (flag.Length() == 0) flag = "TGXYLayoutHints::kLRubberH"; 00146 else flag += " | TGXYLayoutHints::kLRubberH"; 00147 } 00148 00149 out << ", new TGXYLayoutHints(" << GetX() << ", " << GetY() << ", " 00150 << GetW() << ", " << GetH(); 00151 00152 if (!flag.Length()) 00153 out << ")"; 00154 else 00155 out << ", " << flag << ")"; 00156 00157 } 00158 00159 //______________________________________________________________________________ 00160 TGXYLayout::TGXYLayout(TGCompositeFrame *main) 00161 { 00162 // Constructor. The main is the frame for which this layout manager works. 00163 00164 UInt_t width, height; 00165 Int_t dummy; 00166 00167 fMain = main; 00168 fList = main->GetList(); 00169 fFirst = kTRUE; 00170 fFirstWidth = fFirstHeight = 0; 00171 00172 FontStruct_t fs = TGLabel::GetDefaultFontStruct(); 00173 00174 // get standard width an height of a character 00175 fTWidth = gVirtualX->TextWidth(fs, "1234567890", 10) / 10; 00176 gVirtualX->GetFontProperties(fs, fTHeight, dummy); 00177 00178 // the size of the main window are defined in units of a character 00179 // but the system does not understand this. We have to recalculate 00180 // the size into pixels. 00181 width = main->GetWidth() * fTWidth; 00182 height = main->GetHeight() * fTHeight; 00183 00184 main->Resize(width, height); 00185 } 00186 00187 //______________________________________________________________________________ 00188 TGXYLayout::TGXYLayout(const TGXYLayout& xyl) : 00189 TGLayoutManager(xyl), 00190 fList(xyl.fList), 00191 fMain(xyl.fMain), 00192 fFirst(xyl.fFirst), 00193 fFirstWidth(xyl.fFirstWidth), 00194 fFirstHeight(xyl.fFirstHeight), 00195 fTWidth(xyl.fTWidth), 00196 fTHeight(xyl.fTHeight) 00197 { 00198 //copy constructor 00199 } 00200 00201 //______________________________________________________________________________ 00202 TGXYLayout& TGXYLayout::operator=(const TGXYLayout& xyl) 00203 { 00204 //assignment operator 00205 if(this!=&xyl) { 00206 TGLayoutManager::operator=(xyl); 00207 fList=xyl.fList; 00208 fMain=xyl.fMain; 00209 fFirst=xyl.fFirst; 00210 fFirstWidth=xyl.fFirstWidth; 00211 fFirstHeight=xyl.fFirstHeight; 00212 fTWidth=xyl.fTWidth; 00213 fTHeight=xyl.fTHeight; 00214 } 00215 return *this; 00216 } 00217 00218 //______________________________________________________________________________ 00219 void TGXYLayout::Layout() 00220 { 00221 // Recalculates the postion and the size of all widgets. 00222 00223 TGFrameElement *ptr; 00224 TGXYLayoutHints *layout; 00225 Double_t xFactor; 00226 Double_t yFactor; 00227 Int_t newX, newY; 00228 UInt_t newW, newH; 00229 Double_t temp; 00230 00231 if (!fList) return; 00232 00233 if (fFirst) { 00234 // save the original size of the frame. It is used to determin 00235 // if the user has changed the window 00236 fFirstWidth = fMain->GetWidth(); 00237 fFirstHeight = fMain->GetHeight(); 00238 fFirst = kFALSE; 00239 } 00240 00241 // get the factor of the increacement of the window 00242 xFactor = (Double_t)fMain->GetWidth() / (Double_t)fFirstWidth; 00243 if (xFactor < 1.0) xFactor = 1.0; 00244 yFactor = (Double_t)fMain->GetHeight() / (Double_t)fFirstHeight; 00245 if (yFactor < 1.0) yFactor = 1.0; 00246 00247 // set the position an size for each widget and call the layout 00248 // function for each widget 00249 TIter next(fList); 00250 while ((ptr = (TGFrameElement *) next())) { 00251 if (ptr->fState & kIsVisible) { 00252 layout = (TGXYLayoutHints*)ptr->fLayout; 00253 if (layout == 0) 00254 continue; 00255 00256 temp = layout->GetX() * fTWidth ; 00257 if (layout->GetFlag() & TGXYLayoutHints::kLRubberX) 00258 temp *= xFactor; 00259 newX = (Int_t)(temp + 0.5); 00260 00261 temp = layout->GetY() * fTHeight; 00262 if (layout->GetFlag() & TGXYLayoutHints::kLRubberY) 00263 temp *= yFactor; 00264 newY = (Int_t)(temp + 0.5); 00265 00266 temp = layout->GetW() * fTWidth; 00267 if (layout->GetFlag() & TGXYLayoutHints::kLRubberW) 00268 temp *= xFactor; 00269 newW = (UInt_t)(temp + 0.5); 00270 00271 temp = layout->GetH() * fTHeight; 00272 if (layout->GetFlag() & TGXYLayoutHints::kLRubberH) 00273 temp *= yFactor; 00274 newH = (UInt_t)(temp + 0.5); 00275 ptr->fFrame->MoveResize(newX, newY, newW, newH); 00276 ptr->fFrame->Layout(); 00277 } 00278 } 00279 } 00280 00281 //______________________________________________________________________________ 00282 TGDimension TGXYLayout::GetDefaultSize() const 00283 { 00284 // Returns the original size of the frame. 00285 00286 TGDimension size(fFirstWidth, fFirstHeight); 00287 00288 return size; 00289 } 00290 00291 //______________________________________________________________________________ 00292 void TGXYLayout::SavePrimitive(ostream &out, Option_t * /*option = ""*/) 00293 { 00294 // Save XY layout manager as a C++ statement(s) on output stream. 00295 00296 out << "new TGXYLayout(" << fMain->GetName() << ")"; 00297 00298 }