]>
git.saurik.com Git - wxWidgets.git/blob - contrib/src/foldbar/foldpanelbar.cpp
b3d9b30e696c2331a2a7cb36c0ee9ed71d53bef2
   1 ///////////////////////////////////////////////////////////////////////////// 
   2 // Name:        foldpanelbar.cpp 
   4 // Author:      Jorgen Bodde 
   8 // Copyright:   (c) Jorgen Bodde 
   9 // Licence:     wxWindows licence 
  10 ///////////////////////////////////////////////////////////////////////////// 
  12 // For compilers that support precompilation, includes "wx/wx.h". 
  13 #include "wx/wxprec.h" 
  19 #include "wx/foldbar/foldpanelbar.h" 
  20 #include "icon_collapsed.xpm" 
  21 #include "icon_expanded.xpm" 
  22 #include "icon_theresmore.xpm" 
  24 //---------------------------------------------------------------------------- 
  26 //---------------------------------------------------------------------------- 
  28 IMPLEMENT_CLASS( wxFoldPanelBar
, wxPanel 
) 
  30 BEGIN_EVENT_TABLE(wxFoldPanelBar
,wxPanel
) 
  31     EVT_SIZE(wxFoldPanelBar::OnSizePanel
) 
  32     //EVT_PAINT(wxFoldPanelBar::OnPaint) 
  33     EVT_CAPTIONBAR(wxID_ANY
, wxFoldPanelBar::OnPressCaption
) 
  36 wxFoldPanelBar::wxFoldPanelBar() 
  41 wxFoldPanelBar::wxFoldPanelBar( wxWindow 
*parent
, wxWindowID id
, const wxPoint 
&position
, 
  42                                 const wxSize
& size
, long style
, long extraStyle
) 
  45     , _controlCreated(false) 
  47     Create( parent
, id
, position
, size
, style
, extraStyle
); 
  50 void wxFoldPanelBar::Create( wxWindow 
*parent
, wxWindowID id
, const wxPoint 
&position
, 
  51                              const wxSize
& size
, long style
, long extraStyle 
) 
  54     _extraStyle 
= extraStyle
; 
  56     // create the panel (duh!). This causes a size event, which we are going 
  57     // to skip when we are not initialised 
  59     wxPanel::Create(parent
, id
, position
, size
, style
); 
  61     // the fold panel area 
  63     _foldPanel 
= new wxPanel(this, wxID_ANY
, wxDefaultPosition
, wxDefaultSize
, wxNO_BORDER
|wxTAB_TRAVERSAL
); 
  65     // the extra area for some icons / context menu etc 
  68     _bottomPanel 
= new wxPanel(this, wxID_ANY
, wxDefaultPosition
, wxSize(wxDefaultCoord
,22), wxNO_BORDER
|wxTAB_TRAVERSAL
); 
  69     _bottomPanel
->SetBackgroundColour(*wxWHITE
); 
  72     // create the fold icons to be used in the captions 
  74     _images 
= new wxImageList(16, 16); 
  76     wxBitmap 
*bmp 
= new wxBitmap(icon_expanded
); 
  80     bmp 
= new wxBitmap(icon_collapsed
); 
  84     _moreBmp 
= new wxBitmap(icon_theresmore
); 
  86     // do this as last, to check if create is already called 
  88     _controlCreated 
= true; 
  91 wxFoldPanelBar::~wxFoldPanelBar() 
  97 wxFoldPanel 
wxFoldPanelBar::AddFoldPanel(const wxString 
&caption
, bool collapsedInitially
, const wxCaptionBarStyle 
&style
) 
  99     wxASSERT(_controlCreated
); 
 101     // create a fold panel item, which is first only the caption. 
 102     // the user can now add a panel area which will be folded in 
 105     wxFoldPanelItem 
*item 
= new wxFoldPanelItem(_foldPanel
, caption
, _images
, collapsedInitially
, style
); 
 107     // look at the last added one and reposition this one 
 109     if(_panels
.GetCount() > 0) 
 110         y 
= _panels
.Last()->GetY() + _panels
.Last()->GetPanelHeight(); 
 115     //return wxFoldPanel(item); 
 116     return wxFoldPanel(item
); 
 119 int wxFoldPanelBar::AddFoldPanelWindow(const wxFoldPanel 
&panel
, wxWindow 
*window
, int flags
, int ySpacing
, int leftSpacing
, 
 122     wxCHECK(panel
.IsOk(), -1); 
 123     panel
.GetItem()->AddWindow(window
, flags
, ySpacing
, leftSpacing
, rightSpacing
); 
 125     // TODO: Take old and new height, and if difference, reposition all the lower panels 
 126     // this is because the user can add new wxWindow controls somewhere in between 
 127     // when other panels are already present. 
 132 int wxFoldPanelBar::AddFoldPanelSeperator(const wxFoldPanel 
&panel
, const wxColour 
&color
, int ySpacing
, int leftSpacing
, 
 135     wxCHECK(panel
.IsOk(), -1); 
 136     panel
.GetItem()->AddSeparator(color
, ySpacing
, leftSpacing
, rightSpacing
); 
 141 void wxFoldPanelBar::OnSizePanel(wxSizeEvent 
&event
) 
 143     // skip all stuff when we are not initialised yet 
 151     // now size the fold panel area and the 
 152     // lower bar in such a way that the bar is always 
 155     wxRect foldrect 
= GetRect(); 
 157     // fold panel itself. If too little space, 
 161     if(foldrect
.GetHeight() < 23) 
 162         foldrect
.SetHeight(0); 
 164         foldrect
.SetHeight(foldrect
.GetHeight() - 22); 
 169     _foldPanel
->SetSize(foldrect
); 
 171     if(_extraStyle 
& wxFPB_COLLAPSE_TO_BOTTOM
) 
 173         wxRect rect 
= RepositionCollapsedToBottom(); 
 174         if(rect
.GetHeight() > 0) 
 178     // TODO: A smart way to check wether the old - new width of the 
 179     // panel changed, if so no need to resize the fold panel items 
 181     RedisplayFoldPanelItems(); 
 183     // tool panel for icons and other stuff 
 186     wxRect bottomrect 
= GetRect(); 
 187     if(bottomrect
.GetHeight() < 22) 
 190         bottomrect
.SetY(bottomrect
.GetHeight() - 22); 
 192     bottomrect
.SetHeight(22); 
 194     _bottomPanel
->SetSize(bottomrect
); 
 196     // TODO: redraw the bitmap properly 
 197     // use the captionbar algorithm for that 
 199     _bottomPanel
->Refresh(); 
 203 void wxFoldPanelBar::OnPaint(wxPaintEvent 
&event
) 
 208     // paint the bottom panel only, where the 
 209     // arrow is shown when there is more to show the user 
 210     // just as informative icon 
 212     wxPaintDC 
dc(_bottomPanel
); 
 214     wxSize size 
= _bottomPanel
->GetSize(); 
 215     int offset 
= (size
.GetHeight() - _moreBmp
->GetHeight()) / 2; 
 217     dc
.DrawBitmap(*_moreBmp
, size
.GetWidth() - _moreBmp
->GetWidth() - 2, offset
, true); 
 223 void wxFoldPanelBar::OnPressCaption(wxCaptionBarEvent 
&event
) 
 225     // act upon the folding or expanding status of the bar 
 226     // to expand or collapse the panel(s) 
 228     if(event
.GetFoldStatus()) 
 229         Collapse(wxFoldPanel((wxFoldPanelItem 
*)event
.GetTag())); 
 231         Expand(wxFoldPanel((wxFoldPanelItem 
*)event
.GetTag())); 
 234 void wxFoldPanelBar::RefreshPanelsFrom(wxFoldPanelItem 
*item
) 
 238     int i 
= _panels
.Index(item
); 
 240         RefreshPanelsFrom(i
); 
 243 void wxFoldPanelBar::RefreshPanelsFrom(size_t i
) 
 247     // if collapse to bottom is on, the panels that are not expanded 
 248     // should be drawn at the bottom. All panels that are expanded 
 249     // are drawn on top. The last expanded panel gets all the extra space 
 251     if(_extraStyle 
& wxFPB_COLLAPSE_TO_BOTTOM
) 
 255         for(size_t j 
= 0; j 
< _panels
.GetCount(); j
++) 
 257             if(_panels
.Item(j
)->IsExpanded()) 
 258                 offset 
+= _panels
.Item(j
)->Reposition(offset
); 
 261         // put all non collapsed panels at the bottom where there is space, else 
 262         // put them right behind the expanded ones 
 264         RepositionCollapsedToBottom(); 
 268         int y 
= _panels
.Item(i
)->GetY() + _panels
.Item(i
)->GetPanelHeight(); 
 269         for(i
++; i 
< _panels
.GetCount(); i
++) 
 270             y 
+= _panels
.Item(i
)->Reposition(y
); 
 275 void wxFoldPanelBar::RedisplayFoldPanelItems() 
 277     // resize them all. No need to reposition 
 279     wxFoldPanelItem 
*item
; 
 280     for(size_t i 
= 0; i 
< _panels
.GetCount(); i
++) 
 282         item 
= _panels
.Item(i
); 
 289 wxRect 
wxFoldPanelBar::RepositionCollapsedToBottom() 
 291     wxRect 
value(0,0,0,0); 
 293     // determine wether the number of panels left 
 294     // times the size of their captions is enough 
 295     // to be placed in the left over space 
 297     int expanded 
= 0, collapsed 
= 0, offset
; 
 298     GetPanelsHeight(collapsed
, expanded
); 
 300     // if no room stick them behind the normal ones, else 
 303     if((GetSize().GetHeight() - expanded 
- collapsed
) < 0) 
 307         // value is the region which is left unpainted 
 308         // I will send it back as 'slack' so it does not need to 
 312         value
.SetY(expanded
); 
 313         value
.SetHeight(GetSize().GetHeight() - expanded
); 
 314         value
.SetWidth(GetSize().GetWidth()); 
 316         offset 
= GetSize().GetHeight() - collapsed
; 
 322     for(size_t i 
= 0; i 
< _panels
.GetCount(); i
++) 
 324         if(!_panels
.Item(i
)->IsExpanded()) 
 325             offset 
+= _panels
.Item(i
)->Reposition(offset
); 
 331 int wxFoldPanelBar::GetPanelsHeight(int &collapsed
, int &expanded
) 
 335     // assumed here that all the panels that are expanded 
 336     // are positioned after eachother from 0,0 to end. 
 338     for(size_t j 
= 0; j 
< _panels
.GetCount(); j
++) 
 340         int offset 
= _panels
.Item(j
)->GetPanelHeight(); 
 342         if(_panels
.Item(j
)->IsExpanded())