]>
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_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()
46 wxFoldPanelBar::wxFoldPanelBar( wxWindow
*parent
, wxWindowID id
, const wxPoint
&position
,
47 const wxSize
& size
, long style
, long extraStyle
)
50 , m_controlCreated(false)
52 Create( parent
, id
, position
, size
, style
, extraStyle
);
55 void wxFoldPanelBar::Create( wxWindow
*parent
, wxWindowID id
, const wxPoint
&position
,
56 const wxSize
& size
, long style
, long extraStyle
)
59 m_extraStyle
= extraStyle
;
61 // make sure there is any orientation
62 if ( ( style
& wxFPB_HORIZONTAL
) != wxFPB_HORIZONTAL
)
63 style
|= wxFPB_VERTICAL
;
65 // create the panel (duh!). This causes a size event, which we are going
66 // to skip when we are not initialised
68 wxPanel::Create(parent
, id
, position
, size
, style
);
70 // the fold panel area
72 m_foldPanel
= new wxPanel(this, wxID_ANY
, position
, size
, wxNO_BORDER
|wxTAB_TRAVERSAL
);
74 // the extra area for some icons / context menu etc
77 m_bottomPanel
= new wxPanel(this, wxID_ANY
, wxDefaultPosition
, wxSize(wxDefaultCoord
,22), wxNO_BORDER
|wxTAB_TRAVERSAL
);
78 m_bottomPanel
->SetBackgroundColour(*wxWHITE
);
81 // create the fold icons to be used in the captions
83 m_images
= new wxImageList(16, 16);
85 wxBitmap
*bmp
= new wxBitmap(icon_expanded
);
89 bmp
= new wxBitmap(icon_collapsed
);
93 m_moreBmp
= new wxBitmap(icon_theresmore
);
95 // do this as last, to check if create is already called
97 m_controlCreated
= true;
100 wxFoldPanelBar::~wxFoldPanelBar()
106 wxFoldPanel
wxFoldPanelBar::AddFoldPanel(const wxString
&caption
, bool collapsedInitially
, const wxCaptionBarStyle
&style
)
108 wxASSERT(m_controlCreated
);
110 // create a fold panel item, which is first only the caption.
111 // the user can now add a panel area which will be folded in
114 wxFoldPanelItem
*item
= new wxFoldPanelItem(m_foldPanel
, caption
, m_images
, collapsedInitially
, style
);
116 // look at the last added one and reposition this one
118 if(m_panels
.GetCount() > 0)
119 pos
= m_panels
.Last()->GetItemPos() + m_panels
.Last()->GetPanelLength();
121 item
->Reposition(pos
);
124 //return wxFoldPanel(item);
125 return wxFoldPanel(item
);
128 int wxFoldPanelBar::AddFoldPanelWindow(const wxFoldPanel
&panel
, wxWindow
*window
, int flags
, int ySpacing
, int leftSpacing
,
131 wxCHECK(panel
.IsOk(), -1);
132 panel
.GetItem()->AddWindow(window
, flags
, ySpacing
, leftSpacing
, rightSpacing
);
134 // TODO: Take old and new height, and if difference, reposition all the lower panels
135 // this is because the user can add new wxWindow controls somewhere in between
136 // when other panels are already present.
141 int wxFoldPanelBar::AddFoldPanelSeperator(const wxFoldPanel
&panel
, const wxColour
&color
, int ySpacing
, int leftSpacing
,
144 wxCHECK(panel
.IsOk(), -1);
145 panel
.GetItem()->AddSeparator(color
, ySpacing
, leftSpacing
, rightSpacing
);
150 void wxFoldPanelBar::OnSizePanel(wxSizeEvent
&event
)
152 // skip all stuff when we are not initialised yet
154 if(!m_controlCreated
)
160 // now size the fold panel area and the
161 // lower bar in such a way that the bar is always
164 wxRect foldrect
= GetRect();
166 // fold panel itself. If too little space,
170 if(foldrect
.GetHeight() < 23)
171 foldrect
.SetHeight(0);
173 foldrect
.SetHeight(foldrect
.GetHeight() - 22);
178 m_foldPanel
->SetSize(foldrect
);
180 if(m_extraStyle
& wxFPB_COLLAPSE_TO_BOTTOM
)
182 wxRect rect
= RepositionCollapsedToBottom();
183 bool vertical
= IsVertical();
184 if((vertical
&& rect
.GetHeight() > 0) || (!vertical
&& rect
.GetWidth() > 0))
188 // TODO: A smart way to check wether the old - new width of the
189 // panel changed, if so no need to resize the fold panel items
191 RedisplayFoldPanelItems();
193 // tool panel for icons and other stuff
196 wxRect bottomrect
= GetRect();
197 if(bottomrect
.GetHeight() < 22)
200 bottomrect
.SetY(bottomrect
.GetHeight() - 22);
202 bottomrect
.SetHeight(22);
204 m_bottomPanel
->SetSize(bottomrect
);
206 // TODO: redraw the bitmap properly
207 // use the captionbar algorithm for that
209 m_bottomPanel
->Refresh();
213 void wxFoldPanelBar::OnPaint(wxPaintEvent
&event
)
215 if(!m_controlCreated
)
218 // paint the bottom panel only, where the
219 // arrow is shown when there is more to show the user
220 // just as informative icon
222 wxPaintDC
dc(m_bottomPanel
);
224 wxSize size
= m_bottomPanel
->GetSize();
225 int offset
= (size
.GetHeight() - m_moreBmp
->GetHeight()) / 2;
227 dc
.DrawBitmap(*m_moreBmp
, size
.GetWidth() - m_moreBmp
->GetWidth() - 2, offset
, true);
233 void wxFoldPanelBar::OnPressCaption(wxCaptionBarEvent
&event
)
235 // act upon the folding or expanding status of the bar
236 // to expand or collapse the panel(s)
238 if(event
.GetFoldStatus())
239 Collapse(wxFoldPanel((wxFoldPanelItem
*)event
.GetTag()));
241 Expand(wxFoldPanel((wxFoldPanelItem
*)event
.GetTag()));
244 void wxFoldPanelBar::RefreshPanelsFrom(wxFoldPanelItem
*item
)
248 int i
= m_panels
.Index(item
);
250 RefreshPanelsFrom(i
);
253 void wxFoldPanelBar::RefreshPanelsFrom(size_t i
)
257 // if collapse to bottom is on, the panels that are not expanded
258 // should be drawn at the bottom. All panels that are expanded
259 // are drawn on top. The last expanded panel gets all the extra space
261 if(m_extraStyle
& wxFPB_COLLAPSE_TO_BOTTOM
)
265 for(size_t j
= 0; j
< m_panels
.GetCount(); j
++)
267 if(m_panels
.Item(j
)->IsExpanded())
268 offset
+= m_panels
.Item(j
)->Reposition(offset
);
271 // put all non collapsed panels at the bottom where there is space, else
272 // put them right behind the expanded ones
274 RepositionCollapsedToBottom();
278 int pos
= m_panels
.Item(i
)->GetItemPos() + m_panels
.Item(i
)->GetPanelLength();
279 for(i
++; i
< m_panels
.GetCount(); i
++)
280 pos
+= m_panels
.Item(i
)->Reposition(pos
);
285 void wxFoldPanelBar::RedisplayFoldPanelItems()
287 // resize them all. No need to reposition
289 wxFoldPanelItem
*item
;
290 for(size_t i
= 0; i
< m_panels
.GetCount(); i
++)
292 item
= m_panels
.Item(i
);
299 wxRect
wxFoldPanelBar::RepositionCollapsedToBottom()
301 wxRect
value(0,0,0,0);
302 bool vertical
= IsVertical();
304 // determine wether the number of panels left
305 // times the size of their captions is enough
306 // to be placed in the left over space
308 int expanded
= 0, collapsed
= 0, offset
;
309 GetPanelsLength(collapsed
, expanded
);
311 // if no room stick them behind the normal ones, else
314 if(((vertical
? GetSize().GetHeight() : GetSize().GetWidth()) - expanded
- collapsed
) < 0)
318 // value is the region which is left unpainted
319 // I will send it back as 'slack' so it does not need to
322 value
.SetHeight(GetSize().GetHeight());
323 value
.SetWidth(GetSize().GetWidth());
327 value
.SetY(expanded
);
328 value
.SetHeight(value
.GetHeight() - expanded
);
332 value
.SetX(expanded
);
333 value
.SetWidth(value
.GetWidth() - expanded
);
336 offset
= (vertical
? GetSize().GetHeight() : GetSize().GetWidth()) - collapsed
;
341 for(size_t i
= 0; i
< m_panels
.GetCount(); i
++)
343 if(!m_panels
.Item(i
)->IsExpanded())
344 offset
+= m_panels
.Item(i
)->Reposition(offset
);
350 int wxFoldPanelBar::GetPanelsLength(int &collapsed
, int &expanded
)
354 // assumed here that all the panels that are expanded
355 // are positioned after each other from 0,0 to end.
357 for(size_t j
= 0; j
< m_panels
.GetCount(); j
++)
359 int offset
= m_panels
.Item(j
)->GetPanelLength();
361 if(m_panels
.Item(j
)->IsExpanded())