1 ///////////////////////////////////////////////////////////////////////////// 2 // Name: foldpanelbar.h 3 // Purpose: wxFoldPanel 4 // Author: Jorgen Bodde 5 // Modified by: ABX - 19/12/2004 : possibility of horizontal orientation 6 // : wxWidgets coding standards 7 // Created: 22/06/2004 8 // RCS-ID: $Id: foldpanelbar.h 34972 2005-07-28 23:23:27Z VZ $ 9 // Copyright: (c) Jorgen Bodde 10 // Licence: wxWindows licence 11 ///////////////////////////////////////////////////////////////////////////// 12 13 #ifndef __WXFOLDPANELBAR_H__ 14 #define __WXFOLDPANELBAR_H__ 15 16 /** Not yet supported but added for future reference. Single fold forces other panels to close when 17 they are open, and only opens the current panel. This will allow the open panel to gain the full 18 size left in the client area */ 19 #define wxFPB_SINGLE_FOLD 0x0001 20 21 /** All panels are stacked to the bottom. When they are expanded again they show up at the top */ 22 #define wxFPB_COLLAPSE_TO_BOTTOM 0x0002 23 24 /** Orientation flag **/ 25 #define wxFPB_HORIZONTAL wxHORIZONTAL /* 0x0004 */ 26 #define wxFPB_VERTICAL wxVERTICAL /* 0x0008 */ 27 28 /** Not yet supported, but added for future reference. Single fold plus panels will be stacked at the bottom */ 29 #define wxFPB_EXCLUSIVE_FOLD wxFPB_SINGLE_FOLD | wxFPB_COLLAPSE_TO_BOTTOM 30 31 /** Default style of the wxFoldPanelBar */ 32 #define wxFPB_DEFAULT_EXTRASTYLE 0 33 34 #define wxFPB_DEFAULT_STYLE wxTAB_TRAVERSAL | wxNO_BORDER 35 36 #include "wx/foldbar/foldpanelitem.h" 37 38 /** \class wxFoldPanel 39 This class is used to return a reference to the fold panel that is added by wxFoldPanelBar::AddFoldPanel(). Use 40 wxFoldPanel::IsOk() to check wether the result is ok to be used in further operations. Use wxFoldPanel::GetItem() 41 to obtain a parent window reference to create the controls on you want to add with wxFoldPanelBar::AddFoldPanelWindow().<br><br> 42 */ 43 44 class wxFoldPanel 45 { 46 private: 47 wxFoldPanelItem *m_item; 48 49 public: 50 /** Constructor, usually not directly used by the developer. */ wxFoldPanel(wxFoldPanelItem * item)51 wxFoldPanel(wxFoldPanelItem *item) 52 : m_item(item) 53 { 54 } 55 56 /** Returns true if this is a valid wxFoldPanelItem reference. */ IsOk()57 bool IsOk() const { 58 return (m_item != 0); 59 }; 60 61 /** Copy operator to assign one instance to the other, this is needed because these classes are passed 62 as instance not by reference. */ 63 virtual void operator=(const wxFoldPanel &item) { 64 m_item = item.m_item; 65 }; 66 67 #ifndef _NO_DOXYGEN_ 68 // not allowed to be seen by doxygen GetItem()69 wxFoldPanelItem *GetItem() const { 70 return m_item; 71 }; 72 #endif 73 74 /** Use this method to obtain the wxPanel derived class to which you need to add your components. For example;<br> 75 76 \code 77 wxFoldPanel item = m_pnl->AddFoldPanel(wxT("Test me"), false); 78 m_pnl->AddFoldPanelWindow(item, new wxButton(item.GetParent(), wxID_ANY, wxT("Press Me"))); 79 \endcode 80 */ GetParent()81 wxFoldPanelItem *GetParent() const { 82 wxASSERT(m_item); 83 return m_item; 84 }; 85 86 87 }; 88 89 #include <wx/dynarray.h> 90 WX_DEFINE_ARRAY_WITH_DECL_PTR(wxFoldPanelItem *, wxFoldPanelItemArray, class WXDLLIMPEXP_FOLDBAR); 91 92 /** \class wxFoldPanelBar 93 The wxFoldPanelBar is a class which can maintain a list of collapsable panels. Once a panel is collapsed, only 94 it's panel bar is visible to the user. This will provide more space for the other panels, or allow the user to 95 close panels which are not used often to get the most out of the work area. 96 97 This control is easy to use. Simply create it as a child for a panel or sash window, and populate panels with 98 wxFoldPanelBar::AddFoldPanel(). Then use the wxFoldPanelBar::AddFoldPanelWindow() to add wxWindow derived controls 99 to the current fold panel. Use wxFoldPanelBar::AddFoldPanelSeparator() to put separators between the groups of 100 controls that need a visual separator to group them together. After all is constructed, the user can fold 101 the panels by doubleclicking on the bar or single click on the arrow, which will indicate the collapsed or 102 expanded state. 103 */ 104 105 class WXDLLIMPEXP_FOLDBAR wxFoldPanelBar: public wxPanel 106 { 107 private: 108 DECLARE_DYNAMIC_CLASS( wxFoldPanelBar ) 109 DECLARE_EVENT_TABLE() 110 111 wxImageList *m_images; 112 wxFoldPanelItemArray m_panels; 113 wxBoxSizer* m_panelSizer; 114 wxPanel *m_foldPanel, *m_bottomPanel; 115 wxFlexGridSizer* m_mainSizer; 116 bool m_controlCreated; 117 wxBitmap *m_moreBmp; 118 int m_extraStyle; 119 120 private: 121 /** Refreshes all the panels from given index down to last one */ 122 void RefreshPanelsFrom(size_t i); 123 124 /** Refreshes all the panels from given pointer down to last one in the list */ 125 void RefreshPanelsFrom(wxFoldPanelItem *item); 126 127 /** Returns the length of the panels that are expanded and collapsed. This is useful to determine 128 quickly what size is used to display, and what is left at the bottom (right) to align 129 the collapsed panels. */ 130 int GetPanelsLength(int &collapsed, int &expanded); 131 132 /** Reposition all the collapsed panels to the bottom. When it is not possible to 133 align them to the bottom, stick them behind the visible panels. The Rect holds the 134 slack area left between last repositioned panel and the bottom panels. This needs to 135 get a refresh */ 136 wxRect RepositionCollapsedToBottom(); 137 138 public: 139 /** Two step constructor used for XRC. Use wxFoldPanelBar::Create() to create the panel. Do not call 140 any other methods before the control is fully created! */ 141 wxFoldPanelBar(); 142 /** One step creation. Look at wxPanel for the argument and style flags. The extraStyle flags are 143 - wxFPB_DEFAULT_EXTRASTYLE : Takes default styles. 144 - wxFPB_COLLAPSE_TO_BOTTOM : When panels are collapsed, they are put at the bottom of the area. */ 145 wxFoldPanelBar( wxWindow *parent, wxWindowID id = wxID_ANY, const wxPoint& pos = wxDefaultPosition, 146 const wxSize& size = wxDefaultSize, long style = wxFPB_DEFAULT_STYLE, 147 long extraStyle = wxFPB_DEFAULT_EXTRASTYLE); 148 149 /** wxFoldPanelBar destructor */ 150 virtual ~wxFoldPanelBar(); 151 152 /** Two step create call. Use this when the control is not created using the wxPanel derived constructor. 153 WARNING: Do not create this component more then once! */ 154 virtual void Create( wxWindow *parent, wxWindowID id = wxID_ANY, const wxPoint& pos = wxDefaultPosition, 155 const wxSize& size = wxDefaultSize, long style = wxFPB_DEFAULT_STYLE, 156 long extraStyle = wxFPB_DEFAULT_EXTRASTYLE); 157 158 /** Adds a fold panel to the list of panels. If the flag collapsedInitially is set to true, the panel 159 is collapsed initially. The wxFoldPanel item which is returned, can be used as a reference to 160 perform actions upon the fold panel like collapsing it, expanding it, or deleting it from the list. 161 162 Use this foldpanel to add windows to it. Please consult wxFoldPanelBar::AddFoldPanelWindow() and 163 wxFoldPanelBar::AddFoldPanelSeparator() how to add wxWindow items to the panels. */ 164 wxFoldPanel AddFoldPanel(const wxString &caption, bool collapsedInitially = false, 165 const wxCaptionBarStyle &style = wxEmptyCaptionBarStyle); 166 167 168 /** Adds a wxWindow derived class to the referenced wxFoldPanel. IMPORTANT: Make the to be created window, 169 child of the wxFoldPanel. See example that follows. The flags to be used are: 170 - wxFPB_ALIGN_WIDTH: Which means the wxWindow to be added will be aligned to fit the width of the 171 wxFoldPanel when it is resized. Very handy for sizer items, buttons and text boxes. 172 - wxFPB_ALIGN_LEFT: Aligns left instead of fitting the width of the child window to be added. Use either 173 this one or wxFPB_ALIGN_WIDTH. 174 175 The wxWindow to be added can be slightly indented from left and right so it is more visibly placed 176 in the wxFoldPanel. Use ySpacing > 0 to give the control an y offset from the previous wxWindow added, 177 use leftSpacing to give it a slight indent from the left, and rightSpacing also reserves a little space 178 on the right so the wxWindow can be properly placed in the wxFoldPanel. 179 180 The following example adds a wxFoldPanel to the wxFoldPanelBar and adds two wxWindow derived controls 181 to the wxFoldPanel: 182 183 \code 184 185 // create the wxFoldPanelBar 186 m_pnl = new wxFoldPanelBar(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxFPB_DEFAULT_STYLE, wxFPB_COLLAPSE_TO_BOTTOM); 187 188 // add a foldpanel to the control. "Test me" is the caption and it is initially not collapsed. 189 wxFoldPanel item = m_pnl->AddFoldPanel(wxT("Test me"), false); 190 191 // now add a button to the fold panel. Mind that the button should be made child of the 192 // wxFoldPanel and not of the main form. 193 m_pnl->AddFoldPanelWindow(item, new wxButton(item.GetParent(), ID_COLLAPSEME, wxT("Collapse Me"))); 194 195 // add a separator between the two controls. This is purely a visual line that can have a certain 196 // color and also the indents and width alligning like a control. 197 m_pnl->AddFoldPanelSeperator(item); 198 199 // now add a text ctrl. Also very easy. Align this on width so that when the control gets wider 200 // the text control also sizes along. 201 m_pnl->AddFoldPanelWindow(item, new wxTextCtrl(item.GetParent(), wxID_ANY, wxT("Comment")), wxFPB_ALIGN_WIDTH, wxFPB_DEFAULT_SPACING, 20); 202 203 \endcode 204 */ 205 int AddFoldPanelWindow(const wxFoldPanel &panel, wxWindow *window, int flags = wxFPB_ALIGN_WIDTH, 206 int Spacing = wxFPB_DEFAULT_SPACING, int leftSpacing = wxFPB_DEFAULT_LEFTSPACING, 207 int rightSpacing = wxFPB_DEFAULT_RIGHTSPACING); 208 209 /** Adds a separator line to the current wxFoldPanel. The separator is a simple line which is drawn and is no 210 real component. It can be used to separate groups of controls which belong to each other. The colour is 211 adjustable, and it takes the same ySpacing, leftSpacing and rightSpacing as AddFoldPanelWindow(). */ 212 int AddFoldPanelSeperator(const wxFoldPanel &panel, const wxColour &color = wxColour(167,167,167), 213 int Spacing = wxFPB_DEFAULT_SPACING, int leftSpacing = wxFPB_DEFAULT_LEFTLINESPACING, 214 int rightSpacing = wxFPB_DEFAULT_RIGHTLINESPACING); 215 216 /** Returns the number of panels currently present in the wxFoldPanelBar. This is independent if they are 217 visible or hidden. */ GetCount()218 size_t GetCount() const { 219 return m_panels.GetCount(); 220 }; 221 IsVertical()222 inline bool IsVertical() const 223 { 224 return HasFlag(wxFPB_VERTICAL); 225 } 226 227 /** Returns the wxFoldPanel reference belonging to the current index. An empty panel is returned when the 228 index is out of bounds. Use GetCount() to get the amount of panels present. Collapsing and folding the 229 panel does not change the order in which they are indexed. So it is safe enough to keep a reference 230 to the panel by number. */ Item(size_t i)231 wxFoldPanel Item(size_t i) { 232 wxCHECK((int)i >= 0 && i < GetCount(), wxFoldPanel(0)); 233 return wxFoldPanel(m_panels.Item(i)); 234 }; 235 236 /** Collapses the given wxFoldPanel reference, and updates the foldpanel bar. In the wxFPB_COLLAPSE_TO_BOTTOM 237 style, all collapsed captions are put at the bottom of the control. In the normal mode, they stay where 238 they are */ Collapse(const wxFoldPanel & item)239 void Collapse(const wxFoldPanel &item) { 240 wxCHECK2(item.IsOk(), return); 241 item.GetItem()->Collapse(); 242 243 RefreshPanelsFrom(item.GetItem()); 244 }; 245 246 /** Expands the given wxFoldPanel reference, and updates the foldpanel bar. In the wxFPB_COLLAPSE_TO_BOTTOM 247 they will be removed from the bottom and the order where the panel originally was placed is restored. */ Expand(const wxFoldPanel & item)248 void Expand(const wxFoldPanel &item) { 249 wxCHECK2(item.IsOk(), return); 250 item.GetItem()->Expand(); 251 252 RefreshPanelsFrom(item.GetItem()); 253 }; 254 255 /** Sets the style of the caption bar (called wxCaptionBar) of the wxFoldPanel. The changes are applied immediately. 256 All styles not set in the wxCaptionBarStyle class are not applied. Use the wxCaptionBar reference to indicate 257 what captionbar you want to apply the style to. To apply one style to all wxCaptionBar items, use 258 ApplyCaptionStyleAll() */ ApplyCaptionStyle(wxFoldPanel & fp,const wxCaptionBarStyle & style)259 void ApplyCaptionStyle(wxFoldPanel &fp, const wxCaptionBarStyle &style) { 260 wxCHECK2(fp.IsOk(), return); 261 fp.GetItem()->ApplyCaptionStyle(style); 262 }; 263 264 /** Sets the style of all the caption bars of the wxFoldPanel. The changes are applied immediately */ ApplyCaptionStyleAll(const wxCaptionBarStyle & style)265 void ApplyCaptionStyleAll(const wxCaptionBarStyle &style) { 266 for(size_t i = 0; i < GetCount(); i++) 267 { 268 wxFoldPanel item = Item(i); 269 ApplyCaptionStyle(item, style); 270 } 271 }; 272 273 /** Returns the currently used caption style for the wxFoldPanel. It is returned as a wxCaptionBarStyle class. 274 after modifying it, it can be set again */ GetCaptionStyle(wxFoldPanel & fp)275 wxCaptionBarStyle GetCaptionStyle(wxFoldPanel &fp) const { 276 wxCHECK2(fp.IsOk(), return wxEmptyCaptionBarStyle); 277 return fp.GetItem()->GetCaptionStyle(); 278 }; 279 280 private: 281 void OnPressCaption(wxCaptionBarEvent &event); 282 void OnSizePanel(wxSizeEvent &event); 283 284 /** Resize the fold panels so they match the width */ 285 void RedisplayFoldPanelItems(); 286 287 void OnPaint(wxPaintEvent &event); 288 }; 289 290 #endif // __WXFOLDPANELBAR_H__ 291