]> git.saurik.com Git - wxWidgets.git/blame - contrib/src/foldbar/foldpanelbar.cpp
fixed line endings
[wxWidgets.git] / contrib / src / foldbar / foldpanelbar.cpp
CommitLineData
957f5ab7 1/////////////////////////////////////////////////////////////////////////////
f857e441
WS
2// Name: foldpanelbar.cpp
3// Purpose:
4// Author: Jorgen Bodde
7a8d9418
WS
5// Modified by: ABX - 19/12/2004 : possibility of horizontal orientation
6// : wxWidgets coding standards
f857e441
WS
7// Created: 22/06/2004
8// RCS-ID: $Id$
9// Copyright: (c) Jorgen Bodde
10// Licence: wxWindows licence
957f5ab7
VZ
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
7a8d9418
WS
20#ifndef WX_PRECOMP
21 #include "wx/wx.h"
22#endif
23
957f5ab7
VZ
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
e9333003 33IMPLEMENT_DYNAMIC_CLASS( wxFoldPanelBar, wxPanel )
957f5ab7
VZ
34
35BEGIN_EVENT_TABLE(wxFoldPanelBar,wxPanel)
f857e441
WS
36 EVT_SIZE(wxFoldPanelBar::OnSizePanel)
37 //EVT_PAINT(wxFoldPanelBar::OnPaint)
38 EVT_CAPTIONBAR(wxID_ANY, wxFoldPanelBar::OnPressCaption)
957f5ab7
VZ
39END_EVENT_TABLE()
40
41wxFoldPanelBar::wxFoldPanelBar()
e9333003
VZ
42 : wxPanel()
43 , m_foldPanel(NULL)
44 , m_bottomPanel(NULL)
45 , m_controlCreated(false)
957f5ab7
VZ
46{
47
48}
49
f857e441
WS
50wxFoldPanelBar::wxFoldPanelBar( wxWindow *parent, wxWindowID id, const wxPoint &position,
51 const wxSize& size, long style, long extraStyle)
e9333003
VZ
52 : wxPanel()
53 , m_foldPanel(NULL)
7a8d9418
WS
54 , m_bottomPanel(NULL)
55 , m_controlCreated(false)
957f5ab7 56{
f857e441 57 Create( parent, id, position, size, style, extraStyle);
957f5ab7
VZ
58}
59
f857e441
WS
60void wxFoldPanelBar::Create( wxWindow *parent, wxWindowID id, const wxPoint &position,
61 const wxSize& size, long style, long extraStyle )
957f5ab7 62{
f857e441 63
7a8d9418
WS
64 m_extraStyle = extraStyle;
65
66 // make sure there is any orientation
67 if ( ( style & wxFPB_HORIZONTAL ) != wxFPB_HORIZONTAL )
68 style |= wxFPB_VERTICAL;
f857e441
WS
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
60f94682 77 m_foldPanel = new wxPanel(this, wxID_ANY, position, size, wxNO_BORDER|wxTAB_TRAVERSAL);
f857e441
WS
78
79 // the extra area for some icons / context menu etc
957f5ab7
VZ
80
81#if 0
7a8d9418
WS
82 m_bottomPanel = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxSize(wxDefaultCoord,22), wxNO_BORDER|wxTAB_TRAVERSAL);
83 m_bottomPanel->SetBackgroundColour(*wxWHITE);
957f5ab7
VZ
84#endif
85
f857e441 86 // create the fold icons to be used in the captions
957f5ab7 87
7a8d9418 88 m_images = new wxImageList(16, 16);
957f5ab7 89
f857e441 90 wxBitmap *bmp = new wxBitmap(icon_expanded);
7a8d9418 91 m_images->Add(*bmp);
f857e441 92 delete bmp;
957f5ab7 93
f857e441 94 bmp = new wxBitmap(icon_collapsed);
7a8d9418 95 m_images->Add(*bmp);
f857e441 96 delete bmp;
957f5ab7 97
7a8d9418 98 m_moreBmp = new wxBitmap(icon_theresmore);
f857e441
WS
99
100 // do this as last, to check if create is already called
101
7a8d9418 102 m_controlCreated = true;
957f5ab7
VZ
103}
104
105wxFoldPanelBar::~wxFoldPanelBar()
106{
7a8d9418
WS
107 delete m_images;
108 delete m_moreBmp;
957f5ab7
VZ
109}
110
111wxFoldPanel wxFoldPanelBar::AddFoldPanel(const wxString &caption, bool collapsedInitially, const wxCaptionBarStyle &style)
112{
7a8d9418 113 wxASSERT(m_controlCreated);
f857e441
WS
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.
957f5ab7 118
7a8d9418 119 wxFoldPanelItem *item = new wxFoldPanelItem(m_foldPanel, caption, m_images, collapsedInitially, style);
957f5ab7 120
f857e441 121 // look at the last added one and reposition this one
7a8d9418
WS
122 int pos = 0;
123 if(m_panels.GetCount() > 0)
124 pos = m_panels.Last()->GetItemPos() + m_panels.Last()->GetPanelLength();
957f5ab7 125
7a8d9418
WS
126 item->Reposition(pos);
127 m_panels.Add(item);
957f5ab7 128
f857e441
WS
129 //return wxFoldPanel(item);
130 return wxFoldPanel(item);
957f5ab7
VZ
131}
132
133int wxFoldPanelBar::AddFoldPanelWindow(const wxFoldPanel &panel, wxWindow *window, int flags, int ySpacing, int leftSpacing,
f857e441 134 int rightSpacing)
957f5ab7 135{
f857e441
WS
136 wxCHECK(panel.IsOk(), -1);
137 panel.GetItem()->AddWindow(window, flags, ySpacing, leftSpacing, rightSpacing);
957f5ab7 138
f857e441
WS
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.
957f5ab7 142
f857e441 143 return 0;
957f5ab7
VZ
144}
145
146int wxFoldPanelBar::AddFoldPanelSeperator(const wxFoldPanel &panel, const wxColour &color, int ySpacing, int leftSpacing,
f857e441 147 int rightSpacing)
957f5ab7 148{
f857e441
WS
149 wxCHECK(panel.IsOk(), -1);
150 panel.GetItem()->AddSeparator(color, ySpacing, leftSpacing, rightSpacing);
957f5ab7 151
f857e441 152 return 0;
957f5ab7
VZ
153}
154
155void wxFoldPanelBar::OnSizePanel(wxSizeEvent &event)
156{
f857e441 157 // skip all stuff when we are not initialised yet
957f5ab7 158
7a8d9418 159 if(!m_controlCreated)
f857e441
WS
160 {
161 event.Skip();
162 return;
163 }
957f5ab7 164
f857e441
WS
165 // now size the fold panel area and the
166 // lower bar in such a way that the bar is always
167 // visible
957f5ab7 168
f857e441
WS
169 wxRect foldrect = GetRect();
170
171 // fold panel itself. If too little space,
172 // don't show it
957f5ab7
VZ
173
174#if 0
f857e441
WS
175 if(foldrect.GetHeight() < 23)
176 foldrect.SetHeight(0);
177 else
178 foldrect.SetHeight(foldrect.GetHeight() - 22);
957f5ab7
VZ
179#endif
180
f857e441
WS
181 foldrect.SetX(0);
182 foldrect.SetY(0);
7a8d9418 183 m_foldPanel->SetSize(foldrect);
957f5ab7 184
7a8d9418 185 if(m_extraStyle & wxFPB_COLLAPSE_TO_BOTTOM)
f857e441
WS
186 {
187 wxRect rect = RepositionCollapsedToBottom();
7a8d9418
WS
188 bool vertical = IsVertical();
189 if((vertical && rect.GetHeight() > 0) || (!vertical && rect.GetWidth() > 0))
f857e441
WS
190 RefreshRect(rect);
191 }
957f5ab7 192
f857e441
WS
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
957f5ab7 195
f857e441 196 RedisplayFoldPanelItems();
957f5ab7 197
f857e441 198 // tool panel for icons and other stuff
957f5ab7
VZ
199
200#if 0
f857e441
WS
201 wxRect bottomrect = GetRect();
202 if(bottomrect.GetHeight() < 22)
203 bottomrect.SetY(0);
204 else
205 bottomrect.SetY(bottomrect.GetHeight() - 22);
957f5ab7 206
f857e441
WS
207 bottomrect.SetHeight(22);
208 bottomrect.SetX(0);
7a8d9418 209 m_bottomPanel->SetSize(bottomrect);
957f5ab7 210
f857e441
WS
211 // TODO: redraw the bitmap properly
212 // use the captionbar algorithm for that
957f5ab7 213
7a8d9418 214 m_bottomPanel->Refresh();
957f5ab7
VZ
215#endif
216}
217
218void wxFoldPanelBar::OnPaint(wxPaintEvent &event)
219{
7a8d9418 220 if(!m_controlCreated)
f857e441 221 return;
957f5ab7 222#if 0
f857e441
WS
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
957f5ab7 226
7a8d9418 227 wxPaintDC dc(m_bottomPanel);
957f5ab7 228
7a8d9418
WS
229 wxSize size = m_bottomPanel->GetSize();
230 int offset = (size.GetHeight() - m_moreBmp->GetHeight()) / 2;
957f5ab7 231
7a8d9418 232 dc.DrawBitmap(*m_moreBmp, size.GetWidth() - m_moreBmp->GetWidth() - 2, offset, true);
957f5ab7
VZ
233#endif
234
f857e441 235 event.Skip();
957f5ab7
VZ
236}
237
238void wxFoldPanelBar::OnPressCaption(wxCaptionBarEvent &event)
239{
f857e441
WS
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()));
957f5ab7
VZ
247}
248
249void wxFoldPanelBar::RefreshPanelsFrom(wxFoldPanelItem *item)
250{
f857e441 251 wxASSERT(item);
957f5ab7 252
7a8d9418 253 int i = m_panels.Index(item);
f857e441
WS
254 if(i != wxNOT_FOUND)
255 RefreshPanelsFrom(i);
957f5ab7
VZ
256}
257
258void wxFoldPanelBar::RefreshPanelsFrom(size_t i)
259{
f857e441
WS
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
7a8d9418 266 if(m_extraStyle & wxFPB_COLLAPSE_TO_BOTTOM)
f857e441
WS
267 {
268 int offset = 0;
269
7a8d9418 270 for(size_t j = 0; j < m_panels.GetCount(); j++)
f857e441 271 {
7a8d9418
WS
272 if(m_panels.Item(j)->IsExpanded())
273 offset += m_panels.Item(j)->Reposition(offset);
f857e441
WS
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 {
7a8d9418
WS
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);
f857e441
WS
286 }
287 Thaw();
957f5ab7
VZ
288}
289
290void wxFoldPanelBar::RedisplayFoldPanelItems()
291{
f857e441 292 // resize them all. No need to reposition
957f5ab7 293
f857e441 294 wxFoldPanelItem *item;
7a8d9418 295 for(size_t i = 0; i < m_panels.GetCount(); i++)
f857e441 296 {
7a8d9418 297 item = m_panels.Item(i);
f857e441 298 wxASSERT(item);
957f5ab7 299
f857e441
WS
300 item->ResizePanel();
301 }
957f5ab7
VZ
302}
303
304wxRect wxFoldPanelBar::RepositionCollapsedToBottom()
305{
f857e441 306 wxRect value(0,0,0,0);
7a8d9418 307 bool vertical = IsVertical();
f857e441
WS
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;
7a8d9418 314 GetPanelsLength(collapsed, expanded);
f857e441
WS
315
316 // if no room stick them behind the normal ones, else
317 // at the bottom
318
7a8d9418 319 if(((vertical ? GetSize().GetHeight() : GetSize().GetWidth()) - expanded - collapsed) < 0)
f857e441
WS
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
7a8d9418 327 value.SetHeight(GetSize().GetHeight());
f857e441
WS
328 value.SetWidth(GetSize().GetWidth());
329
7a8d9418
WS
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 }
f857e441 340
7a8d9418
WS
341 offset = (vertical ? GetSize().GetHeight() : GetSize().GetWidth()) - collapsed;
342 }
f857e441
WS
343
344 // go reposition
345
7a8d9418 346 for(size_t i = 0; i < m_panels.GetCount(); i++)
f857e441 347 {
7a8d9418
WS
348 if(!m_panels.Item(i)->IsExpanded())
349 offset += m_panels.Item(i)->Reposition(offset);
f857e441
WS
350 }
351
352 return value;
957f5ab7
VZ
353}
354
7a8d9418 355int wxFoldPanelBar::GetPanelsLength(int &collapsed, int &expanded)
957f5ab7 356{
f857e441
WS
357 int value = 0;
358
359 // assumed here that all the panels that are expanded
3103e8a9 360 // are positioned after each other from 0,0 to end.
f857e441 361
7a8d9418 362 for(size_t j = 0; j < m_panels.GetCount(); j++)
f857e441 363 {
7a8d9418 364 int offset = m_panels.Item(j)->GetPanelLength();
f857e441 365 value += offset;
7a8d9418 366 if(m_panels.Item(j)->IsExpanded())
f857e441
WS
367 expanded += offset;
368 else
369 collapsed += offset;
370 }
371
372 return value;
9cf662c4 373}