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