]> git.saurik.com Git - wxWidgets.git/blame_incremental - contrib/src/foldbar/foldpanelbar.cpp
Order of initializations according to class construction.
[wxWidgets.git] / contrib / src / foldbar / foldpanelbar.cpp
... / ...
CommitLineData
1/////////////////////////////////////////////////////////////////////////////
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
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)
31 EVT_SIZE(wxFoldPanelBar::OnSizePanel)
32 //EVT_PAINT(wxFoldPanelBar::OnPaint)
33 EVT_CAPTIONBAR(wxID_ANY, wxFoldPanelBar::OnPressCaption)
34END_EVENT_TABLE()
35
36wxFoldPanelBar::wxFoldPanelBar()
37{
38
39}
40
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)
46{
47 Create( parent, id, position, size, style, extraStyle);
48}
49
50void wxFoldPanelBar::Create( wxWindow *parent, wxWindowID id, const wxPoint &position,
51 const wxSize& size, long style, long extraStyle )
52{
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
66
67#if 0
68 _bottomPanel = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxSize(wxDefaultCoord,22), wxNO_BORDER|wxTAB_TRAVERSAL);
69 _bottomPanel->SetBackgroundColour(*wxWHITE);
70#endif
71
72 // create the fold icons to be used in the captions
73
74 _images = new wxImageList(16, 16);
75
76 wxBitmap *bmp = new wxBitmap(icon_expanded);
77 _images->Add(*bmp);
78 delete bmp;
79
80 bmp = new wxBitmap(icon_collapsed);
81 _images->Add(*bmp);
82 delete bmp;
83
84 _moreBmp = new wxBitmap(icon_theresmore);
85
86 // do this as last, to check if create is already called
87
88 _controlCreated = true;
89}
90
91wxFoldPanelBar::~wxFoldPanelBar()
92{
93 delete _images;
94 delete _moreBmp;
95}
96
97wxFoldPanel wxFoldPanelBar::AddFoldPanel(const wxString &caption, bool collapsedInitially, const wxCaptionBarStyle &style)
98{
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.
104
105 wxFoldPanelItem *item = new wxFoldPanelItem(_foldPanel, caption, _images, collapsedInitially, style);
106
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();
111
112 item->Reposition(y);
113 _panels.Add(item);
114
115 //return wxFoldPanel(item);
116 return wxFoldPanel(item);
117}
118
119int wxFoldPanelBar::AddFoldPanelWindow(const wxFoldPanel &panel, wxWindow *window, int flags, int ySpacing, int leftSpacing,
120 int rightSpacing)
121{
122 wxCHECK(panel.IsOk(), -1);
123 panel.GetItem()->AddWindow(window, flags, ySpacing, leftSpacing, rightSpacing);
124
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.
128
129 return 0;
130}
131
132int wxFoldPanelBar::AddFoldPanelSeperator(const wxFoldPanel &panel, const wxColour &color, int ySpacing, int leftSpacing,
133 int rightSpacing)
134{
135 wxCHECK(panel.IsOk(), -1);
136 panel.GetItem()->AddSeparator(color, ySpacing, leftSpacing, rightSpacing);
137
138 return 0;
139}
140
141void wxFoldPanelBar::OnSizePanel(wxSizeEvent &event)
142{
143 // skip all stuff when we are not initialised yet
144
145 if(!_controlCreated)
146 {
147 event.Skip();
148 return;
149 }
150
151 // now size the fold panel area and the
152 // lower bar in such a way that the bar is always
153 // visible
154
155 wxRect foldrect = GetRect();
156
157 // fold panel itself. If too little space,
158 // don't show it
159
160#if 0
161 if(foldrect.GetHeight() < 23)
162 foldrect.SetHeight(0);
163 else
164 foldrect.SetHeight(foldrect.GetHeight() - 22);
165#endif
166
167 foldrect.SetX(0);
168 foldrect.SetY(0);
169 _foldPanel->SetSize(foldrect);
170
171 if(_extraStyle & wxFPB_COLLAPSE_TO_BOTTOM)
172 {
173 wxRect rect = RepositionCollapsedToBottom();
174 if(rect.GetHeight() > 0)
175 RefreshRect(rect);
176 }
177
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
180
181 RedisplayFoldPanelItems();
182
183 // tool panel for icons and other stuff
184
185#if 0
186 wxRect bottomrect = GetRect();
187 if(bottomrect.GetHeight() < 22)
188 bottomrect.SetY(0);
189 else
190 bottomrect.SetY(bottomrect.GetHeight() - 22);
191
192 bottomrect.SetHeight(22);
193 bottomrect.SetX(0);
194 _bottomPanel->SetSize(bottomrect);
195
196 // TODO: redraw the bitmap properly
197 // use the captionbar algorithm for that
198
199 _bottomPanel->Refresh();
200#endif
201}
202
203void wxFoldPanelBar::OnPaint(wxPaintEvent &event)
204{
205 if(!_controlCreated)
206 return;
207#if 0
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
211
212 wxPaintDC dc(_bottomPanel);
213
214 wxSize size = _bottomPanel->GetSize();
215 int offset = (size.GetHeight() - _moreBmp->GetHeight()) / 2;
216
217 dc.DrawBitmap(*_moreBmp, size.GetWidth() - _moreBmp->GetWidth() - 2, offset, true);
218#endif
219
220 event.Skip();
221}
222
223void wxFoldPanelBar::OnPressCaption(wxCaptionBarEvent &event)
224{
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()));
232}
233
234void wxFoldPanelBar::RefreshPanelsFrom(wxFoldPanelItem *item)
235{
236 wxASSERT(item);
237
238 size_t i = _panels.Index(item);
239 if(i != wxNOT_FOUND)
240 RefreshPanelsFrom(i);
241}
242
243void wxFoldPanelBar::RefreshPanelsFrom(size_t i)
244{
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();
273}
274
275void wxFoldPanelBar::RedisplayFoldPanelItems()
276{
277 // resize them all. No need to reposition
278
279 wxFoldPanelItem *item;
280 for(size_t i = 0; i < _panels.GetCount(); i++)
281 {
282 item = _panels.Item(i);
283 wxASSERT(item);
284
285 item->ResizePanel();
286 }
287}
288
289wxRect wxFoldPanelBar::RepositionCollapsedToBottom()
290{
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;
329}
330
331int wxFoldPanelBar::GetPanelsHeight(int &collapsed, int &expanded)
332{
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;
349
350}