]> git.saurik.com Git - wxWidgets.git/blob - contrib/src/foldbar/foldpanelbar.cpp
added foldbar contrib
[wxWidgets.git] / contrib / src / foldbar / foldpanelbar.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: wxFoldPanelBar.cpp
3 // Author: XX
4 // Created: Tuesday, June 22, 2004 20:40:00
5 // Copyright: XX
6 /////////////////////////////////////////////////////////////////////////////
7
8 // For compilers that support precompilation, includes "wx/wx.h".
9 #include "wx/wxprec.h"
10
11 #ifdef __BORLANDC__
12 #pragma hdrstop
13 #endif
14
15 #include "wx/foldbar/foldpanelbar.h"
16 #include "icon_collapsed.xpm"
17 #include "icon_expanded.xpm"
18 #include "icon_theresmore.xpm"
19
20 //----------------------------------------------------------------------------
21 // wxFoldPanelBar
22 //----------------------------------------------------------------------------
23
24 IMPLEMENT_CLASS( wxFoldPanelBar, wxPanel )
25
26 BEGIN_EVENT_TABLE(wxFoldPanelBar,wxPanel)
27 EVT_SIZE(wxFoldPanelBar::OnSizePanel)
28 //EVT_PAINT(wxFoldPanelBar::OnPaint)
29 EVT_CAPTIONBAR(-1, wxFoldPanelBar::OnPressCaption)
30 END_EVENT_TABLE()
31
32 wxFoldPanelBar::wxFoldPanelBar()
33 {
34
35 }
36
37 wxFoldPanelBar::wxFoldPanelBar( wxWindow *parent, wxWindowID id, const wxPoint &position,
38 const wxSize& size, long style, long extraStyle)
39 : _foldPanel(0)
40 , _bottomPanel(0)
41 , _controlCreated(false)
42 {
43 Create( parent, id, position, size, style, extraStyle);
44 }
45
46 void wxFoldPanelBar::Create( wxWindow *parent, wxWindowID id, const wxPoint &position,
47 const wxSize& size, long style, long extraStyle )
48 {
49
50 _extraStyle = extraStyle;
51
52 // create the panel (duh!). This causes a size event, which we are going
53 // to skip when we are not initialised
54
55 wxPanel::Create(parent, id, position, size, style);
56
57 // the fold panel area
58
59 _foldPanel = new wxPanel(this, -1, wxDefaultPosition, wxDefaultSize, wxNO_BORDER|wxTAB_TRAVERSAL);
60
61 // the extra area for some icons / context menu etc
62
63 #if 0
64 _bottomPanel = new wxPanel(this, -1, wxDefaultPosition, wxSize(-1,22), wxNO_BORDER|wxTAB_TRAVERSAL);
65 _bottomPanel->SetBackgroundColour(*wxWHITE);
66 #endif
67
68 // create the fold icons to be used in the captions
69
70 _images = new wxImageList(16, 16);
71
72 wxBitmap *bmp = new wxBitmap(icon_expanded);
73 _images->Add(*bmp);
74 delete bmp;
75
76 bmp = new wxBitmap(icon_collapsed);
77 _images->Add(*bmp);
78 delete bmp;
79
80 _moreBmp = new wxBitmap(icon_theresmore);
81
82 // do this as last, to check if create is already called
83
84 _controlCreated = true;
85 }
86
87 wxFoldPanelBar::~wxFoldPanelBar()
88 {
89 delete _images;
90 delete _moreBmp;
91 }
92
93 wxFoldPanel wxFoldPanelBar::AddFoldPanel(const wxString &caption, bool collapsedInitially, const wxCaptionBarStyle &style)
94 {
95 wxASSERT(_controlCreated);
96
97 // create a fold panel item, which is first only the caption.
98 // the user can now add a panel area which will be folded in
99 // when pressed.
100
101 wxFoldPanelItem *item = new wxFoldPanelItem(_foldPanel, caption, _images, collapsedInitially, style);
102
103 // look at the last added one and reposition this one
104 int y = 0;
105 if(_panels.GetCount() > 0)
106 y = _panels.Last()->GetY() + _panels.Last()->GetPanelHeight();
107
108 item->Reposition(y);
109 _panels.Add(item);
110
111 //return wxFoldPanel(item);
112 return wxFoldPanel(item);
113 }
114
115 int wxFoldPanelBar::AddFoldPanelWindow(const wxFoldPanel &panel, wxWindow *window, int flags, int ySpacing, int leftSpacing,
116 int rightSpacing)
117 {
118 wxCHECK(panel.IsOk(), -1);
119 panel.GetItem()->AddWindow(window, flags, ySpacing, leftSpacing, rightSpacing);
120
121 // TODO: Take old and new height, and if difference, reposition all the lower panels
122 // this is because the user can add new wxWindow controls somewhere in between
123 // when other panels are already present.
124
125 return 0;
126 }
127
128 int wxFoldPanelBar::AddFoldPanelSeperator(const wxFoldPanel &panel, const wxColour &color, int ySpacing, int leftSpacing,
129 int rightSpacing)
130 {
131 wxCHECK(panel.IsOk(), -1);
132 panel.GetItem()->AddSeparator(color, ySpacing, leftSpacing, rightSpacing);
133
134 return 0;
135 }
136
137 void wxFoldPanelBar::OnSizePanel(wxSizeEvent &event)
138 {
139 // skip all stuff when we are not initialised yet
140
141 if(!_controlCreated)
142 {
143 event.Skip();
144 return;
145 }
146
147 // now size the fold panel area and the
148 // lower bar in such a way that the bar is always
149 // visible
150
151 wxRect foldrect = GetRect();
152
153 // fold panel itself. If too little space,
154 // don't show it
155
156 #if 0
157 if(foldrect.GetHeight() < 23)
158 foldrect.SetHeight(0);
159 else
160 foldrect.SetHeight(foldrect.GetHeight() - 22);
161 #endif
162
163 foldrect.SetX(0);
164 foldrect.SetY(0);
165 _foldPanel->SetSize(foldrect);
166
167 if(_extraStyle & wxFPB_COLLAPSE_TO_BOTTOM)
168 {
169 wxRect rect = RepositionCollapsedToBottom();
170 if(rect.GetHeight() > 0)
171 RefreshRect(rect);
172 }
173
174 // TODO: A smart way to check wether the old - new width of the
175 // panel changed, if so no need to resize the fold panel items
176
177 RedisplayFoldPanelItems();
178
179 // tool panel for icons and other stuff
180
181 #if 0
182 wxRect bottomrect = GetRect();
183 if(bottomrect.GetHeight() < 22)
184 bottomrect.SetY(0);
185 else
186 bottomrect.SetY(bottomrect.GetHeight() - 22);
187
188 bottomrect.SetHeight(22);
189 bottomrect.SetX(0);
190 _bottomPanel->SetSize(bottomrect);
191
192 // TODO: redraw the bitmap properly
193 // use the captionbar algorithm for that
194
195 _bottomPanel->Refresh();
196 #endif
197 }
198
199 void wxFoldPanelBar::OnPaint(wxPaintEvent &event)
200 {
201 if(!_controlCreated)
202 return;
203 #if 0
204 // paint the bottom panel only, where the
205 // arrow is shown when there is more to show the user
206 // just as informative icon
207
208 wxPaintDC dc(_bottomPanel);
209
210 wxSize size = _bottomPanel->GetSize();
211 int offset = (size.GetHeight() - _moreBmp->GetHeight()) / 2;
212
213 dc.DrawBitmap(*_moreBmp, size.GetWidth() - _moreBmp->GetWidth() - 2, offset, true);
214 #endif
215
216 event.Skip();
217 }
218
219 void wxFoldPanelBar::OnPressCaption(wxCaptionBarEvent &event)
220 {
221 // act upon the folding or expanding status of the bar
222 // to expand or collapse the panel(s)
223
224 if(event.GetFoldStatus())
225 Collapse(wxFoldPanel((wxFoldPanelItem *)event.GetTag()));
226 else
227 Expand(wxFoldPanel((wxFoldPanelItem *)event.GetTag()));
228 }
229
230 void wxFoldPanelBar::RefreshPanelsFrom(wxFoldPanelItem *item)
231 {
232 wxASSERT(item);
233
234 size_t i = _panels.Index(item);
235 if(i != wxNOT_FOUND)
236 RefreshPanelsFrom(i);
237 }
238
239 void wxFoldPanelBar::RefreshPanelsFrom(size_t i)
240 {
241 Freeze();
242
243 // if collapse to bottom is on, the panels that are not expanded
244 // should be drawn at the bottom. All panels that are expanded
245 // are drawn on top. The last expanded panel gets all the extra space
246
247 if(_extraStyle & wxFPB_COLLAPSE_TO_BOTTOM)
248 {
249 int offset = 0;
250
251 for(size_t j = 0; j < _panels.GetCount(); j++)
252 {
253 if(_panels.Item(j)->IsExpanded())
254 offset += _panels.Item(j)->Reposition(offset);
255 }
256
257 // put all non collapsed panels at the bottom where there is space, else
258 // put them right behind the expanded ones
259
260 RepositionCollapsedToBottom();
261 }
262 else
263 {
264 int y = _panels.Item(i)->GetY() + _panels.Item(i)->GetPanelHeight();
265 for(i++; i < _panels.GetCount(); i++)
266 y += _panels.Item(i)->Reposition(y);
267 }
268 Thaw();
269 }
270
271 void wxFoldPanelBar::RedisplayFoldPanelItems()
272 {
273 // resize them all. No need to reposition
274
275 wxFoldPanelItem *item;
276 for(size_t i = 0; i < _panels.GetCount(); i++)
277 {
278 item = _panels.Item(i);
279 wxASSERT(item);
280
281 item->ResizePanel();
282 }
283 }
284
285 wxRect wxFoldPanelBar::RepositionCollapsedToBottom()
286 {
287 wxRect value(0,0,0,0);
288
289 // determine wether the number of panels left
290 // times the size of their captions is enough
291 // to be placed in the left over space
292
293 int expanded = 0, collapsed = 0, offset;
294 GetPanelsHeight(collapsed, expanded);
295
296 // if no room stick them behind the normal ones, else
297 // at the bottom
298
299 if((GetSize().GetHeight() - expanded - collapsed) < 0)
300 offset = expanded;
301 else
302 {
303 // value is the region which is left unpainted
304 // I will send it back as 'slack' so it does not need to
305 // be recalulated.
306
307 value.SetX(0);
308 value.SetY(expanded);
309 value.SetHeight(GetSize().GetHeight() - expanded);
310 value.SetWidth(GetSize().GetWidth());
311
312 offset = GetSize().GetHeight() - collapsed;
313 }
314
315
316 // go reposition
317
318 for(size_t i = 0; i < _panels.GetCount(); i++)
319 {
320 if(!_panels.Item(i)->IsExpanded())
321 offset += _panels.Item(i)->Reposition(offset);
322 }
323
324 return value;
325 }
326
327 int wxFoldPanelBar::GetPanelsHeight(int &collapsed, int &expanded)
328 {
329 int value = 0, offset = 0;
330
331 // assumed here that all the panels that are expanded
332 // are positioned after eachother from 0,0 to end.
333
334 for(size_t j = 0; j < _panels.GetCount(); j++)
335 {
336 offset = _panels.Item(j)->GetPanelHeight();
337 value += offset;
338 if(_panels.Item(j)->IsExpanded())
339 expanded += offset;
340 else
341 collapsed += offset;
342 }
343
344 return value;
345
346 }