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