]>
Commit | Line | Data |
---|---|---|
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$ | |
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. */ | |
51 | wxFoldPanel(wxFoldPanelItem *item) | |
52 | : m_item(item) | |
53 | { | |
54 | } | |
55 | ||
56 | /** Returns true if this is a valid wxFoldPanelItem reference. */ | |
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 | |
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 | */ | |
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_PTR(wxFoldPanelItem *, wxFoldPanelItemArray); | |
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::AddFoldPanelSeperator() 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_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 allign | |
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 | allign 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 alligned 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: Alligns 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. Allign 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 seperator line to the current wxFoldPanel. The seperator is a simple line which is drawn and is no | |
210 | real component. It can be used to seperate groups of controls which belong to eachother. 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. */ | |
218 | size_t GetCount() const { | |
219 | return m_panels.GetCount(); | |
220 | }; | |
221 | ||
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. */ | |
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 */ | |
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. */ | |
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() */ | |
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 */ | |
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 */ | |
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__ |