]>
git.saurik.com Git - wxWidgets.git/blob - contrib/src/foldbar/foldpanelbar.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: foldpanelbar.cpp
4 // Author: Jorgen Bodde
5 // Modified by: ABX - 19/12/2004 : possibility of horizontal orientation
6 // : wxWidgets coding standards
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())