1
/////////////////////////////////////////////////////////////////////////////
2
// Name: foldpanelbar.cpp
4
// Author: Jorgen Bodde
5
// Modified by: ABX - 19/12/2004 : possibility of horizontal orientation
6
// : wxWidgets coding standards
8
// RCS-ID: $Id: foldpanelbar.cpp,v 1.7 2005/07/28 23:23:27 VZ Exp $
9
// Copyright: (c) Jorgen Bodde
10
// Licence: wxWindows licence
11
/////////////////////////////////////////////////////////////////////////////
13
// For compilers that support precompilation, includes "wx/wx.h".
14
#include "wx/wxprec.h"
24
#include "wx/foldbar/foldpanelbar.h"
25
#include "icon_collapsed.xpm"
26
#include "icon_expanded.xpm"
27
#include "icon_theresmore.xpm"
29
//----------------------------------------------------------------------------
31
//----------------------------------------------------------------------------
33
IMPLEMENT_DYNAMIC_CLASS( wxFoldPanelBar, wxPanel )
35
BEGIN_EVENT_TABLE(wxFoldPanelBar,wxPanel)
36
EVT_SIZE(wxFoldPanelBar::OnSizePanel)
37
//EVT_PAINT(wxFoldPanelBar::OnPaint)
38
EVT_CAPTIONBAR(wxID_ANY, wxFoldPanelBar::OnPressCaption)
41
wxFoldPanelBar::wxFoldPanelBar()
45
, m_controlCreated(false)
50
wxFoldPanelBar::wxFoldPanelBar( wxWindow *parent, wxWindowID id, const wxPoint &position,
51
const wxSize& size, long style, long extraStyle)
55
, m_controlCreated(false)
57
Create( parent, id, position, size, style, extraStyle);
60
void wxFoldPanelBar::Create( wxWindow *parent, wxWindowID id, const wxPoint &position,
61
const wxSize& size, long style, long extraStyle )
64
m_extraStyle = extraStyle;
66
// make sure there is any orientation
67
if ( ( style & wxFPB_HORIZONTAL ) != wxFPB_HORIZONTAL )
68
style |= wxFPB_VERTICAL;
70
// create the panel (duh!). This causes a size event, which we are going
71
// to skip when we are not initialised
73
wxPanel::Create(parent, id, position, size, style);
75
// the fold panel area
77
m_foldPanel = new wxPanel(this, wxID_ANY, position, size, wxNO_BORDER|wxTAB_TRAVERSAL);
79
// the extra area for some icons / context menu etc
82
m_bottomPanel = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxSize(wxDefaultCoord,22), wxNO_BORDER|wxTAB_TRAVERSAL);
83
m_bottomPanel->SetBackgroundColour(*wxWHITE);
86
// create the fold icons to be used in the captions
88
m_images = new wxImageList(16, 16);
90
wxBitmap *bmp = new wxBitmap(icon_expanded);
94
bmp = new wxBitmap(icon_collapsed);
98
m_moreBmp = new wxBitmap(icon_theresmore);
100
// do this as last, to check if create is already called
102
m_controlCreated = true;
105
wxFoldPanelBar::~wxFoldPanelBar()
111
wxFoldPanel wxFoldPanelBar::AddFoldPanel(const wxString &caption, bool collapsedInitially, const wxCaptionBarStyle &style)
113
wxASSERT(m_controlCreated);
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
119
wxFoldPanelItem *item = new wxFoldPanelItem(m_foldPanel, caption, m_images, collapsedInitially, style);
121
// look at the last added one and reposition this one
123
if(m_panels.GetCount() > 0)
124
pos = m_panels.Last()->GetItemPos() + m_panels.Last()->GetPanelLength();
126
item->Reposition(pos);
129
//return wxFoldPanel(item);
130
return wxFoldPanel(item);
133
int wxFoldPanelBar::AddFoldPanelWindow(const wxFoldPanel &panel, wxWindow *window, int flags, int ySpacing, int leftSpacing,
136
wxCHECK(panel.IsOk(), -1);
137
panel.GetItem()->AddWindow(window, flags, ySpacing, leftSpacing, rightSpacing);
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.
146
int wxFoldPanelBar::AddFoldPanelSeperator(const wxFoldPanel &panel, const wxColour &color, int ySpacing, int leftSpacing,
149
wxCHECK(panel.IsOk(), -1);
150
panel.GetItem()->AddSeparator(color, ySpacing, leftSpacing, rightSpacing);
155
void wxFoldPanelBar::OnSizePanel(wxSizeEvent &event)
157
// skip all stuff when we are not initialised yet
159
if(!m_controlCreated)
165
// now size the fold panel area and the
166
// lower bar in such a way that the bar is always
169
wxRect foldrect = GetRect();
171
// fold panel itself. If too little space,
175
if(foldrect.GetHeight() < 23)
176
foldrect.SetHeight(0);
178
foldrect.SetHeight(foldrect.GetHeight() - 22);
183
m_foldPanel->SetSize(foldrect);
185
if(m_extraStyle & wxFPB_COLLAPSE_TO_BOTTOM)
187
wxRect rect = RepositionCollapsedToBottom();
188
bool vertical = IsVertical();
189
if((vertical && rect.GetHeight() > 0) || (!vertical && rect.GetWidth() > 0))
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
196
RedisplayFoldPanelItems();
198
// tool panel for icons and other stuff
201
wxRect bottomrect = GetRect();
202
if(bottomrect.GetHeight() < 22)
205
bottomrect.SetY(bottomrect.GetHeight() - 22);
207
bottomrect.SetHeight(22);
209
m_bottomPanel->SetSize(bottomrect);
211
// TODO: redraw the bitmap properly
212
// use the captionbar algorithm for that
214
m_bottomPanel->Refresh();
218
void wxFoldPanelBar::OnPaint(wxPaintEvent &event)
220
if(!m_controlCreated)
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
227
wxPaintDC dc(m_bottomPanel);
229
wxSize size = m_bottomPanel->GetSize();
230
int offset = (size.GetHeight() - m_moreBmp->GetHeight()) / 2;
232
dc.DrawBitmap(*m_moreBmp, size.GetWidth() - m_moreBmp->GetWidth() - 2, offset, true);
238
void wxFoldPanelBar::OnPressCaption(wxCaptionBarEvent &event)
240
// act upon the folding or expanding status of the bar
241
// to expand or collapse the panel(s)
243
if(event.GetFoldStatus())
244
Collapse(wxFoldPanel((wxFoldPanelItem *)event.GetTag()));
246
Expand(wxFoldPanel((wxFoldPanelItem *)event.GetTag()));
249
void wxFoldPanelBar::RefreshPanelsFrom(wxFoldPanelItem *item)
253
int i = m_panels.Index(item);
255
RefreshPanelsFrom(i);
258
void wxFoldPanelBar::RefreshPanelsFrom(size_t i)
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
266
if(m_extraStyle & wxFPB_COLLAPSE_TO_BOTTOM)
270
for(size_t j = 0; j < m_panels.GetCount(); j++)
272
if(m_panels.Item(j)->IsExpanded())
273
offset += m_panels.Item(j)->Reposition(offset);
276
// put all non collapsed panels at the bottom where there is space, else
277
// put them right behind the expanded ones
279
RepositionCollapsedToBottom();
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);
290
void wxFoldPanelBar::RedisplayFoldPanelItems()
292
// resize them all. No need to reposition
294
wxFoldPanelItem *item;
295
for(size_t i = 0; i < m_panels.GetCount(); i++)
297
item = m_panels.Item(i);
304
wxRect wxFoldPanelBar::RepositionCollapsedToBottom()
306
wxRect value(0,0,0,0);
307
bool vertical = IsVertical();
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
313
int expanded = 0, collapsed = 0, offset;
314
GetPanelsLength(collapsed, expanded);
316
// if no room stick them behind the normal ones, else
319
if(((vertical ? GetSize().GetHeight() : GetSize().GetWidth()) - expanded - collapsed) < 0)
323
// value is the region which is left unpainted
324
// I will send it back as 'slack' so it does not need to
327
value.SetHeight(GetSize().GetHeight());
328
value.SetWidth(GetSize().GetWidth());
332
value.SetY(expanded);
333
value.SetHeight(value.GetHeight() - expanded);
337
value.SetX(expanded);
338
value.SetWidth(value.GetWidth() - expanded);
341
offset = (vertical ? GetSize().GetHeight() : GetSize().GetWidth()) - collapsed;
346
for(size_t i = 0; i < m_panels.GetCount(); i++)
348
if(!m_panels.Item(i)->IsExpanded())
349
offset += m_panels.Item(i)->Reposition(offset);
355
int wxFoldPanelBar::GetPanelsLength(int &collapsed, int &expanded)
359
// assumed here that all the panels that are expanded
360
// are positioned after each other from 0,0 to end.
362
for(size_t j = 0; j < m_panels.GetCount(); j++)
364
int offset = m_panels.Item(j)->GetPanelLength();
366
if(m_panels.Item(j)->IsExpanded())