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