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