LightWrap++
AC++wrapperfortheLightWave3DSDK
panel_sizer.h
Go to the documentation of this file.
1 #ifndef LWPP_PANEL_SIZER_H
2 #define LWPP_PANEL_SIZER_H
3 
4 #include <lwpp/panel.h>
5 #include <vector>
6 
7 namespace lwpp
8 {
9 
11  {
13  STRETCH_VERTICAL = 1 << 1,
14  };
15 
17  class Sizer
18  {
19  public:
20  Sizer() {;}
21 
23  virtual Sizer *Add(Sizer *) = 0;
25  virtual void getMinSize(int &w, int &h) = 0;
27  virtual void getMaxSize(int &w, int &h) = 0;
29  virtual void getCurrentSize(int &w, int &h) = 0;
31  virtual int getLabelWidth() = 0;
33  virtual void Layout(int x, int y, int w, int h, int lw) = 0;
34 
35  virtual int getFlags() = 0;
36  };
37 
38  class DynamicSizer : public Sizer
39  {
40  protected:
41  std::vector<Sizer *> childList;
42  typedef std::vector<Sizer *>::iterator childIter;
43  int Flags;
44  DynamicSizer(int flags) : Flags(flags)
45  {
46  ;
47  }
49  {
50  for (childIter i = childList.begin(); i != childList.end(); ++i)
51  {
52  delete *i;
53  }
54  }
55  public:
56  virtual Sizer *Add(Sizer *sizer)
57  {
58  childList.push_back(sizer);
59  return sizer;
60  }
61  virtual int getLabelWidth()
62  {
63  int w = 0;
64  for (childIter i = childList.begin(); i != childList.end(); ++i)
65  {
66  w = lwpp::Max(w, (*i)->getLabelWidth());
67  }
68  return w;
69  }
70  virtual int getFlags() {return Flags;}
71  };
72 
75  {
76  public:
77  HorizontalSizer(int flags) : DynamicSizer(flags)
78  {
79  ;
80  }
81  virtual void getMaxSize(int &w, int &h)
82  {
83  for (childIter i = childList.begin(); i != childList.end(); ++i)
84  {
85  int tw, th;
86  (*i)->getMaxSize(tw, th);
87  w += tw;
88  h = lwpp::Max(h, th);
89  }
90  }
91  virtual void getMinSize(int &w, int &h)
92  {
93  for (childIter i = childList.begin(); i != childList.end(); ++i)
94  {
95  int tw, th;
96  (*i)->getMinSize(tw, th);
97  w += tw;
98  h = lwpp::Max(h, th);
99  }
100  }
101  virtual void getCurrentSize(int &w, int &h)
102  {
103  for (childIter i = childList.begin(); i != childList.end(); ++i)
104  {
105  int tw, th;
106  (*i)->getCurrentSize(tw, th);
107  w += tw;
108  h = lwpp::Max(h, th);
109  }
110  }
111  virtual void Layout(int x, int y, int w, int h, int lw)
112  {
113  int currentW = 0;
114  int currentH = 0;
115  getCurrentSize(currentW, currentH);
116  int remW = w - currentW;
117  int remH = h - currentH;
118  int numChilds = 0; // the number of childs that can be stretched
119  for (childIter i = childList.begin(); i != childList.end(); ++i)
120  {
121  if ( (*i)->getFlags() & STRETCH_HORIZONTAL ) numChilds++;
122  }
123  remW /= numChilds;
124  int top = x;
125  int left = y;
126  for (childIter i = childList.begin(); i != childList.end(); ++i)
127  {
128  int tw, th;
129  (*i)->getCurrentSize(tw, th);
130  if ( (*i)->getFlags() & STRETCH_HORIZONTAL)
131  {
132  tw += remW;
133  }
134  (*i)->Layout(left, top, tw, th, lw);
135  top += th;
136  left += tw;
137  }
138  }
139  };
140 
143  {
144  public:
145  VerticalSizer(int flags) : DynamicSizer(flags)
146  {
147  ;
148  }
149  virtual void getMinSize(int &w, int &h)
150  {
151  for (childIter i = childList.begin(); i != childList.end(); ++i)
152  {
153  int tw, th;
154  (*i)->getMinSize(tw, th);
155  h += th;
156  w = lwpp::Max(w, tw);
157  }
158  }
159  virtual void getMaxSize(int &w, int &h)
160  {
161  for (childIter i = childList.begin(); i != childList.end(); ++i)
162  {
163  int tw, th;
164  (*i)->getMaxSize(tw, th);
165  h += th;
166  w = lwpp::Max(w, tw);
167  }
168  }
169  virtual void getCurrentSize(int &w, int &h)
170  {
171  for (childIter i = childList.begin(); i != childList.end(); ++i)
172  {
173  int tw, th;
174  (*i)->getCurrentSize(tw, th);
175  h += th;
176  w = lwpp::Max(w, tw);
177  }
178  }
179  virtual void Layout(int x, int y, int w, int h, int lw)
180  {
181  int currentW = 0;
182  int currentH = 0;
183  getCurrentSize(currentW, currentH);
184  int remW = w - currentW;
185  int remH = h - currentH;
186  int numChilds = 0; // the number of childs that can be stretched
187  for (childIter i = childList.begin(); i != childList.end(); ++i)
188  {
189  if ( (*i)->getFlags() & STRETCH_VERTICAL) numChilds++;
190  }
191  remH /= numChilds;
192  int top = x;
193  int left = y;
194  for (childIter i = childList.begin(); i != childList.end(); ++i)
195  {
196  int tw, th;
197  (*i)->getCurrentSize(tw, th);
198  if ( (*i)->getFlags() & STRETCH_VERTICAL)
199  {
200  th += remH;
201  }
202  (*i)->Layout(left, top, tw, th, lw);
203  top += th;
204  left += tw;
205  }
206  }
207  };
208 
210  /* A ControlSizer contains a single LWPanel control
211  *
212  */
213  class ControlSizer : public Sizer
214  {
215  PanelControl control;
216  int minWidth, minHeight;
217  int Flags;
218  public:
219  ControlSizer(PanelControl _control, int flags = 0) : control(_control), Flags(flags)
220  {
221  getCurrentSize(minWidth, minHeight);
222  }
223  virtual Sizer *Add(Sizer *sizer, SizerFlags) {return sizer;}
224  virtual void getMinSize(int &w, int &h)
225  {
226  w = minWidth;
227  h = minHeight;
228  }
229  virtual void getMaxSize(int &w, int &h)
230  {
231  w = minWidth * 2;
232  h = minHeight * 2;
233  }
234  virtual void getCurrentSize(int &w, int &h)
235  {
236  w = control.W();
237  h = control.H();
238  }
239  virtual int getLabelWidth()
240  {
241  return control.LW();
242  }
243  virtual void Layout(int x, int y, int w, int h, int lw)
244  {
245  control.Move(x + lw - getLabelWidth() ,y);
246 
247  if (!(Flags & STRETCH_HORIZONTAL)) w = minWidth;
248  if (!(Flags & STRETCH_VERTICAL)) h = minHeight;
249  control.setSize(w,h);
250  }
251  virtual int getFlags() {return Flags;}
252  virtual Sizer *Add(Sizer *s) {return s;}
253  };
254 
256  {
257  Sizer *root; // root sizer for the panel
258  int minWidth, minHeight;
259  int labelWidth;
260  void init()
261  {
262  if (root)
263  {
264  root->getMinSize(minWidth, minHeight);
265  root->getLabelWidth();
266  }
267  }
268  public:
269  ManagedPanel() : root(0), minWidth(0), minHeight(0), labelWidth(0)
270  {
271  ;
272  }
274  {
275  if (root) delete root;
276  }
277  void setRoot(Sizer *_root)
278  {
279  root = _root;
280  init();
281  }
282  void Layout (LWPanel &panel)
283  {
284  int w = panel.GetWidth() + 8;
285  int h = panel.GetHeight() + 8;
286  int x = 4;
287  int y = 4;
288  if (root)
289  {
290  root->Layout(x, y, w, h, labelWidth);
291  }
292  panel.Draw(DR_REFRESH);
293  }
294  };
295 
296 }
297 
298 #endif // LWPP_PANEL_SIZER_H