Logo ROOT   6.30.04
Reference Guide
 All Namespaces Files Pages
TGXYLayout.cxx
Go to the documentation of this file.
1 // @(#)root/gui:$Id$
2 // Author: Reiner Rohlfs 24/03/2002
3 
4 /*************************************************************************
5  * Copyright (C) 1995-2001, Rene Brun, Fons Rademakers and Reiner Rohlfs *
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 //////////////////////////////////////////////////////////////////////////
13 // //
14 // TGXYLayout //
15 // //
16 // Is a layout manager where the position and the size of each widget //
17 // in the frame are defined by X / Y - coordinates. The coordinates //
18 // for each widget are defined by the TGXYLayoutHints. Therefore it //
19 // is not possible to share a layout hint for several widgets. //
20 // //
21 // The coordinates (X, Y) and the size (W, H) are defined in units //
22 // of the size of a typical character. Also the size of the //
23 // TGCompositeFrame for which a TGXYLayout manager is used has to be //
24 // defined in its constructor in units of the size of a character! //
25 // //
26 // It is not possible to use any other layout hint than the //
27 // TGXYLayoutHints for this layout manager! //
28 // //
29 // The rubberFlag in the constructor of the TGLXYLayoutHins defines //
30 // how the position and the size of a widget is recalculated if the //
31 // size of the frame is increased: //
32 // - kLRubberX: The X - position (left edge) is increased by the same //
33 // factor as the width of the frame increases. //
34 // - kLRubberY: The Y - position (upper edge) is increased by the same //
35 // factor as the height of the frame increases. //
36 // - kLRubberW: The width of the widget is increased by the same //
37 // factor as the width of the frame increases. //
38 // - kLRubberH: The height of the widget is increased by the same //
39 // factor as the height of the frame increases. //
40 // But the size never becomes smaller than defined by the //
41 // TGXYLayoutHints and the X and Y coordinates becomes never smaller //
42 // than defined by the layout hints. //
43 // //
44 // TGXYLayoutHints //
45 // //
46 // This layout hint must be used for the TGXYLouyout manager! //
47 // //
48 // //
49 // Example how to use this layout manager: //
50 // //
51 // TGMyFrame::TGMyFrame() //
52 // : TGMainFrame(gClient->GetRoot(), 30, 12) //
53 // // frame is 30 character long and 12 character heigh //
54 // { //
55 // SetLayoutManager(new TGXYLayout(this)); //
56 // //
57 // // create a button of size 8 X 1.8 at position 20 / 1 //
58 // TGTextButton * button; //
59 // button = new TGTextButton(this, "&Apply", 1); //
60 // AddFrame(button, new TGXYLayoutHints(20, 1, 8, 1.8)); //
61 // //
62 // // create a listbox of size 18 X 10 at position 1 / 1. //
63 // // The height will increase if the frame height increases //
64 // TGListBox * listBox; //
65 // listBox = new TGListBox(this, 2); //
66 // AddFrame(listBox, new TGXYLayoutHints(1, 1, 18, 10, //
67 // TGXYLayoutHints::kLRubberX | //
68 // TGXYLayoutHints::kLRubberY | //
69 // TGXYLayoutHints::kLRubberH )); //
70 // . //
71 // . //
72 // . //
73 // } //
74 // //
75 // Normally there is one layout hint per widget. Therefore these //
76 // can be deleted like in the following example in the desctuctor //
77 // of the frame: //
78 // //
79 // TGMyFrame::~TGMyFrame() //
80 // { //
81 // // Destructor, deletes all frames and their layout hints. //
82 // //
83 // TGFrameElement *ptr; //
84 // //
85 // // delete all frames and layout hints //
86 // if (fList) { //
87 // TIter next(fList); //
88 // while ((ptr = (TGFrameElement *) next())) { //
89 // if (ptr->fLayout) //
90 // delete ptr->fLayout; //
91 // if (ptr->fFrame) //
92 // delete ptr->fFrame; //
93 // } //
94 // } //
95 // } //
96 // //
97 //////////////////////////////////////////////////////////////////////////
98 
99 #include "TGXYLayout.h"
100 #include "TGFrame.h"
101 #include "TGLabel.h"
102 #include "Riostream.h"
103 
104 
105 ClassImp(TGXYLayout);
106 ClassImp(TGXYLayoutHints);
107 
108 ////////////////////////////////////////////////////////////////////////////////
109 /// Constructor. The x, y, w and h define the position of the widget in
110 /// its frame and the size of the widget. The unit is the size of a
111 /// character. The rubberFlag defines how to move and to resize the
112 /// widget when the frame is resized. Default is moving the X and Y
113 /// position but keep the size of the widget.
114 
115 TGXYLayoutHints::TGXYLayoutHints(Double_t x, Double_t y, Double_t w, Double_t h,
116  UInt_t rubberFlag)
117  : TGLayoutHints(kLHintsNormal, 0,0,0,0)
118 {
119  fX = x;
120  fY = y;
121  fW = w;
122  fH = h;
123  fFlag = rubberFlag;
124 }
125 
126 ////////////////////////////////////////////////////////////////////////////////
127 /// Save XY layout hints as a C++ statement(s) on output stream.
128 
129 void TGXYLayoutHints::SavePrimitive(std::ostream &out, Option_t * /*option = ""*/)
130 {
131  TString flag = "";
132  if (fFlag & kLRubberX) {
133  if (flag.Length() == 0) flag = "TGXYLayoutHints::kLRubberX";
134  else flag += " | TGXYLayoutHints::kLRubberX";
135  }
136  if (fFlag & kLRubberY) {
137  if (flag.Length() == 0) flag = "TGXYLayoutHints::kLRubberY";
138  else flag += " | TGXYLayoutHints::kLRubberY";
139  }
140  if (fFlag & kLRubberW) {
141  if (flag.Length() == 0) flag = "TGXYLayoutHints::kLRubberW";
142  else flag += " | TGXYLayoutHints::kLRubberW";
143  }
144  if (fFlag & kLRubberH) {
145  if (flag.Length() == 0) flag = "TGXYLayoutHints::kLRubberH";
146  else flag += " | TGXYLayoutHints::kLRubberH";
147  }
148 
149  out << ", new TGXYLayoutHints(" << GetX() << ", " << GetY() << ", "
150  << GetW() << ", " << GetH();
151 
152  if (!flag.Length())
153  out << ")";
154  else
155  out << ", " << flag << ")";
156 
157 }
158 
159 ////////////////////////////////////////////////////////////////////////////////
160 /// Constructor. The main is the frame for which this layout manager works.
161 
162 TGXYLayout::TGXYLayout(TGCompositeFrame *main)
163 {
164  UInt_t width, height;
165  Int_t dummy;
166 
167  fMain = main;
168  fList = main->GetList();
169  fFirst = kTRUE;
170  fFirstWidth = fFirstHeight = 0;
171 
172  FontStruct_t fs = TGLabel::GetDefaultFontStruct();
173 
174  // get standard width an height of a character
175  fTWidth = gVirtualX->TextWidth(fs, "1234567890", 10) / 10;
176  gVirtualX->GetFontProperties(fs, fTHeight, dummy);
177 
178  // the size of the main window are defined in units of a character
179  // but the system does not understand this. We have to recalculate
180  // the size into pixels.
181  width = main->GetWidth() * fTWidth;
182  height = main->GetHeight() * fTHeight;
183 
184  main->Resize(width, height);
185 }
186 
187 ////////////////////////////////////////////////////////////////////////////////
188 ///copy constructor
189 
190 TGXYLayout::TGXYLayout(const TGXYLayout& xyl) :
191  TGLayoutManager(xyl),
192  fList(xyl.fList),
193  fMain(xyl.fMain),
194  fFirst(xyl.fFirst),
195  fFirstWidth(xyl.fFirstWidth),
196  fFirstHeight(xyl.fFirstHeight),
197  fTWidth(xyl.fTWidth),
198  fTHeight(xyl.fTHeight)
199 {
200 }
201 
202 ////////////////////////////////////////////////////////////////////////////////
203 ///assignment operator
204 
205 TGXYLayout& TGXYLayout::operator=(const TGXYLayout& xyl)
206 {
207  if(this!=&xyl) {
208  TGLayoutManager::operator=(xyl);
209  fList=xyl.fList;
210  fMain=xyl.fMain;
211  fFirst=xyl.fFirst;
212  fFirstWidth=xyl.fFirstWidth;
213  fFirstHeight=xyl.fFirstHeight;
214  fTWidth=xyl.fTWidth;
215  fTHeight=xyl.fTHeight;
216  }
217  return *this;
218 }
219 
220 ////////////////////////////////////////////////////////////////////////////////
221 /// Recalculates the postion and the size of all widgets.
222 
223 void TGXYLayout::Layout()
224 {
225  TGFrameElement *ptr;
226  TGXYLayoutHints *layout;
227  Double_t xFactor;
228  Double_t yFactor;
229  Int_t newX, newY;
230  UInt_t newW, newH;
231  Double_t temp;
232 
233  if (!fList) return;
234 
235  if (fFirst) {
236  // save the original size of the frame. It is used to determin
237  // if the user has changed the window
238  fFirstWidth = fMain->GetWidth();
239  fFirstHeight = fMain->GetHeight();
240  fFirst = kFALSE;
241  }
242 
243  // get the factor of the increacement of the window
244  xFactor = (Double_t)fMain->GetWidth() / (Double_t)fFirstWidth;
245  if (xFactor < 1.0) xFactor = 1.0;
246  yFactor = (Double_t)fMain->GetHeight() / (Double_t)fFirstHeight;
247  if (yFactor < 1.0) yFactor = 1.0;
248 
249  // set the position an size for each widget and call the layout
250  // function for each widget
251  TIter next(fList);
252  while ((ptr = (TGFrameElement *) next())) {
253  if (ptr->fState & kIsVisible) {
254  layout = (TGXYLayoutHints*)ptr->fLayout;
255  if (layout == 0)
256  continue;
257 
258  temp = layout->GetX() * fTWidth ;
259  if (layout->GetFlag() & TGXYLayoutHints::kLRubberX)
260  temp *= xFactor;
261  newX = (Int_t)(temp + 0.5);
262 
263  temp = layout->GetY() * fTHeight;
264  if (layout->GetFlag() & TGXYLayoutHints::kLRubberY)
265  temp *= yFactor;
266  newY = (Int_t)(temp + 0.5);
267 
268  temp = layout->GetW() * fTWidth;
269  if (layout->GetFlag() & TGXYLayoutHints::kLRubberW)
270  temp *= xFactor;
271  newW = (UInt_t)(temp + 0.5);
272 
273  temp = layout->GetH() * fTHeight;
274  if (layout->GetFlag() & TGXYLayoutHints::kLRubberH)
275  temp *= yFactor;
276  newH = (UInt_t)(temp + 0.5);
277  ptr->fFrame->MoveResize(newX, newY, newW, newH);
278  ptr->fFrame->Layout();
279  }
280  }
281 }
282 
283 ////////////////////////////////////////////////////////////////////////////////
284 /// Returns the original size of the frame.
285 
286 TGDimension TGXYLayout::GetDefaultSize() const
287 {
288  TGDimension size(fFirstWidth, fFirstHeight);
289 
290  return size;
291 }
292 
293 ////////////////////////////////////////////////////////////////////////////////
294 /// Save XY layout manager as a C++ statement(s) on output stream.
295 
296 void TGXYLayout::SavePrimitive(std::ostream &out, Option_t * /*option = ""*/)
297 {
298  out << "new TGXYLayout(" << fMain->GetName() << ")";
299 
300 }