]>
Commit | Line | Data |
---|---|---|
1 | \section{wxTab classes overview}\label{wxtaboverview} | |
2 | ||
3 | Classes: \helpref{wxTabView}{wxtabview}, \helpref{wxPanelTabView}{wxpaneltabview}, | |
4 | \helpref{wxTabbedPanel}{wxtabbedpanel}, \helpref{wxTabbedDialog}{wxtabbeddialog}, | |
5 | \helpref{wxTabControl}{wxtabcontrol} | |
6 | ||
7 | The tab classes provides a way to display rows of tabs (like file divider tabs), which can be | |
8 | used to switch between panels or other information. Tabs are most | |
9 | commonly used in dialog boxes where the number of options is too great | |
10 | to fit on one dialog. | |
11 | ||
12 | {\bf Please note} that the preferred class for programming tabbed windows is \helpref{wxNotebook}{wxnotebook}. | |
13 | The old tab classes are retained for backward compatibility and also to implement | |
14 | wxNotebook on platforms that don't have native tab controls. | |
15 | ||
16 | \wxheading{The appearance and behaviour of a wxTabbedDialog} | |
17 | ||
18 | The following screenshot shows the appearance of the sample tabbed dialog application. | |
19 | ||
20 | $$\image{8cm;0cm}{wxtab1.eps}$$ | |
21 | ||
22 | By clicking on the tabs, the user can display a different set of controls. In the example, | |
23 | the Close and Help buttons remain constant. These two buttons are children of the main dialog box, | |
24 | whereas the other controls are children of panels which are shown and hidden according to | |
25 | which tab is active. | |
26 | ||
27 | A tabbed dialog may have several layers (rows) of tabs, each being | |
28 | offset vertically and horizontally from the previous. Tabs work in | |
29 | columns, in that when a tab is pressed, it swaps place with the tab on | |
30 | the first row of the same column, in order to give the effect of | |
31 | displaying that tab. All tabs must be of the same width. | |
32 | This is a constraint of the implementation, but it also | |
33 | means that the user will find it easier to find tabs since there are | |
34 | distinct tab columns. On some tabbed dialog implementations, tabs jump around | |
35 | seemingly randomly because tabs have different widths. | |
36 | In this implementation, a tab can always be found on the same column. | |
37 | ||
38 | Tabs are always drawn along the top of the view area; the implementation does | |
39 | not allow for vertical tabs or any other configuration. | |
40 | ||
41 | \wxheading{Using tabs} | |
42 | ||
43 | The tab classes provide facilities for switching between contexts by | |
44 | means of `tabs', which look like file divider tabs. | |
45 | ||
46 | You must create both a {\it view} to handle the tabs, and a {\it window} to display the tabs | |
47 | and related information. The wxTabbedDialog and wxTabbedPanel classes are provided for | |
48 | convenience, but you could equally well construct your own window class and derived | |
49 | tab view. | |
50 | ||
51 | If you wish to display a tabbed dialog - the most common use - you should follow these steps. | |
52 | ||
53 | \begin{enumerate}\itemsep=0pt | |
54 | \item Create a new wxTabbedDialog class, and any buttons you wish always to be displayed | |
55 | (regardless of which tab is active). | |
56 | \item Create a new wxPanelTabView, passing the dialog as the first argument. | |
57 | \item Set the view rectangle with \helpref{wxTabView::SetViewRect}{wxtabviewsetviewrect}, | |
58 | to specify the area in which child panels will be | |
59 | shown. The tabs will sit on top of this view rectangle. | |
60 | \item Call \helpref{wxTabView::CalculateTabWidth}{wxtabviewcalculatetabwidth} to calculate | |
61 | the width of the tabs based on the view area. This is optional if, for example, you have one row | |
62 | of tabs which does not extend the full width of the view area. | |
63 | \item Call \helpref{wxTabView::AddTab}{wxtabviewaddtab} for each of the tabs you wish to create, passing | |
64 | a unique identifier and a tab label. | |
65 | \item Construct a number of windows, one for each tab, and call \helpref{wxPanelTabView::AddTabWindow}{wxpaneltabviewaddtabwindow} for | |
66 | each of these, passing a tab identifier and the window. | |
67 | \item Set the tab selection. | |
68 | \item Show the dialog. | |
69 | \end{enumerate} | |
70 | ||
71 | Under Motif, you may also need to size the dialog just before setting the tab selection, for unknown reasons. | |
72 | ||
73 | Some constraints you need to be aware of: | |
74 | ||
75 | \begin{itemize}\itemsep=0pt | |
76 | \item All tabs must be of the same width. | |
77 | \item Omit the wxTAB\_STYLE\_COLOUR\_INTERIOR flag to ensure that the dialog background | |
78 | and tab backgrounds match. | |
79 | \end{itemize} | |
80 | ||
81 | \subsection{Example} | |
82 | ||
83 | The following fragment is taken from the file test.cpp. | |
84 | ||
85 | {\small | |
86 | \begin{verbatim} | |
87 | void MyDialog::Init(void) | |
88 | { | |
89 | int dialogWidth = 365; | |
90 | int dialogHeight = 390; | |
91 | ||
92 | wxButton *okButton = new wxButton(this, wxID_OK, "Close", wxPoint(100, 330), wxSize(80, 25)); | |
93 | wxButton *cancelButton = new wxButton(this, wxID_CANCEL, "Cancel", wxPoint(185, 330), wxSize(80, 25)); | |
94 | wxButton *HelpButton = new wxButton(this, wxID_HELP, "Help", wxPoint(270, 330), wxSize(80, 25)); | |
95 | okButton->SetDefault(); | |
96 | ||
97 | // Note, omit the wxTAB_STYLE_COLOUR_INTERIOR, so we will guarantee a match | |
98 | // with the panel background, and save a bit of time. | |
99 | wxPanelTabView *view = new wxPanelTabView(this, wxTAB_STYLE_DRAW_BOX); | |
100 | ||
101 | wxRectangle rect; | |
102 | rect.x = 5; | |
103 | rect.y = 70; | |
104 | // Could calculate the view width from the tab width and spacing, | |
105 | // as below, but let's assume we have a fixed view width. | |
106 | // rect.width = view->GetTabWidth()*4 + 3*view->GetHorizontalTabSpacing(); | |
107 | rect.width = 326; | |
108 | rect.height = 250; | |
109 | ||
110 | view->SetViewRect(rect); | |
111 | ||
112 | // Calculate the tab width for 4 tabs, based on a view width of 326 and | |
113 | // the current horizontal spacing. Adjust the view width to exactly fit | |
114 | // the tabs. | |
115 | view->CalculateTabWidth(4, true); | |
116 | ||
117 | if (!view->AddTab(TEST_TAB_CAT, wxString("Cat"))) | |
118 | return; | |
119 | ||
120 | if (!view->AddTab(TEST_TAB_DOG, wxString("Dog"))) | |
121 | return; | |
122 | if (!view->AddTab(TEST_TAB_GUINEAPIG, wxString("Guinea Pig"))) | |
123 | return; | |
124 | if (!view->AddTab(TEST_TAB_GOAT, wxString("Goat"))) | |
125 | return; | |
126 | if (!view->AddTab(TEST_TAB_ANTEATER, wxString("Ant-eater"))) | |
127 | return; | |
128 | if (!view->AddTab(TEST_TAB_SHEEP, wxString("Sheep"))) | |
129 | return; | |
130 | if (!view->AddTab(TEST_TAB_COW, wxString("Cow"))) | |
131 | return; | |
132 | if (!view->AddTab(TEST_TAB_HORSE, wxString("Horse"))) | |
133 | return; | |
134 | if (!view->AddTab(TEST_TAB_PIG, wxString("Pig"))) | |
135 | return; | |
136 | if (!view->AddTab(TEST_TAB_OSTRICH, wxString("Ostrich"))) | |
137 | return; | |
138 | if (!view->AddTab(TEST_TAB_AARDVARK, wxString("Aardvark"))) | |
139 | return; | |
140 | if (!view->AddTab(TEST_TAB_HUMMINGBIRD,wxString("Hummingbird"))) | |
141 | return; | |
142 | ||
143 | // Add some panels | |
144 | wxPanel *panel1 = new wxPanel(this, -1, wxPoint(rect.x + 20, rect.y + 10), wxSize(290, 220), wxTAB_TRAVERSAL); | |
145 | (void)new wxButton(panel1, -1, "Press me", wxPoint(10, 10)); | |
146 | (void)new wxTextCtrl(panel1, -1, "1234", wxPoint(10, 40), wxSize(120, 150)); | |
147 | ||
148 | view->AddTabWindow(TEST_TAB_CAT, panel1); | |
149 | ||
150 | wxPanel *panel2 = new wxPanel(this, -1, wxPoint(rect.x + 20, rect.y + 10), wxSize(290, 220)); | |
151 | ||
152 | wxString animals[] = { "Fox", "Hare", "Rabbit", "Sabre-toothed tiger", "T Rex" }; | |
153 | (void)new wxListBox(panel2, -1, wxPoint(5, 5), wxSize(170, 80), 5, animals); | |
154 | ||
155 | (void)new wxTextCtrl(panel2, -1, "Some notes about the animals in this house", wxPoint(5, 100), wxSize(170, 100)), | |
156 | wxTE_MULTILINE; | |
157 | ||
158 | view->AddTabWindow(TEST_TAB_DOG, panel2); | |
159 | ||
160 | // Don't know why this is necessary under Motif... | |
161 | #ifdef wx_motif | |
162 | this->SetSize(dialogWidth, dialogHeight-20); | |
163 | #endif | |
164 | ||
165 | view->SetTabSelection(TEST_TAB_CAT); | |
166 | ||
167 | this->Centre(wxBOTH); | |
168 | } | |
169 | \end{verbatim} | |
170 | } | |
171 | ||
172 | \section{wxTabView overview}\label{wxtabviewoverview} | |
173 | ||
174 | Classes: \helpref{wxTabView}{wxtabview}, \helpref{wxPanelTabView}{wxpaneltabview} | |
175 | ||
176 | A wxTabView manages and draws a number of tabs. Because it is separate | |
177 | from the tabbed window implementation, it can be reused in a number of contexts. | |
178 | This library provides tabbed dialog and panel classes to use with the | |
179 | wxPanelTabView class, but an application could derive other kinds of | |
180 | view from wxTabView. | |
181 | ||
182 | For example, a help application might draw a representation of a book on | |
183 | a window, with a row of tabs along the top. The new tab view class might | |
184 | be called wxCanvasTabView, for example, with the wxBookCanvas posting | |
185 | the OnEvent function to the wxCanvasTabView before processing further, | |
186 | application-specific event processing. | |
187 | ||
188 | A window class designed to work with a view class must call the view's | |
189 | OnEvent and Draw functions at appropriate times. | |
190 |