1998-05-20 10:25:30 -04:00
|
|
|
\section{Tab classes overview}\label{wxtaboverview}
|
|
|
|
|
|
|
|
Classes: \helpref{wxTabView}{wxtabview}, \helpref{wxPanelTabView}{wxpaneltabview},
|
1998-06-14 16:48:39 -04:00
|
|
|
\helpref{wxTabbedPanel}{wxtabbedpanel}, \helpref{wxTabbedDialog}{wxtabbeddialog},
|
1998-05-20 10:25:30 -04:00
|
|
|
\helpref{wxTabControl}{wxtabcontrol}
|
|
|
|
|
|
|
|
The tab classes provides a way to display rows of tabs (like file divider tabs), which can be
|
|
|
|
used to switch between panels or other information. Tabs are most
|
|
|
|
commonly used in dialog boxes where the number of options is too great
|
|
|
|
to fit on one dialog.
|
|
|
|
|
1998-06-14 16:48:39 -04:00
|
|
|
\wxheading{The appearance and behaviour of a wxTabbedDialog}
|
1998-05-20 10:25:30 -04:00
|
|
|
|
|
|
|
The following screenshot shows the appearance of the sample tabbed dialog application.
|
|
|
|
|
|
|
|
$$\image{8cm;0cm}{wxtab1.eps}$$
|
|
|
|
|
|
|
|
By clicking on the tabs, the user can display a different set of controls. In the example,
|
|
|
|
the Close and Help buttons remain constant. These two buttons are children of the main dialog box,
|
|
|
|
whereas the other controls are children of panels which are shown and hidden according to
|
|
|
|
which tab is active.
|
|
|
|
|
|
|
|
A tabbed dialog may have several layers (rows) of tabs, each being
|
|
|
|
offset vertically and horizontally from the previous. Tabs work in
|
|
|
|
columns, in that when a tab is pressed, it swaps place with the tab on
|
|
|
|
the first row of the same column, in order to give the effect of
|
|
|
|
displaying that tab. All tabs must be of the same width.
|
|
|
|
This is a constraint of the implementation, but it also
|
|
|
|
means that the user will find it easier to find tabs since there are
|
|
|
|
distinct tab columns. On some tabbed dialog implementations, tabs jump around
|
|
|
|
seemingly randomly because tabs have different widths.
|
|
|
|
In this implementation, a tab can always be found on the same column.
|
|
|
|
|
|
|
|
Tabs are always drawn along the top of the view area; the implementation does
|
|
|
|
not allow for vertical tabs or any other configuration.
|
|
|
|
|
|
|
|
\wxheading{Using tabs}
|
|
|
|
|
|
|
|
The tab classes provide facilities for switching between contexts by
|
|
|
|
means of `tabs', which look like file divider tabs.
|
|
|
|
|
|
|
|
You must create both a {\it view} to handle the tabs, and a {\it window} to display the tabs
|
|
|
|
and related information. The wxTabbedDialog and wxTabbedPanel classes are provided for
|
|
|
|
convenience, but you could equally well construct your own window class and derived
|
|
|
|
tab view.
|
|
|
|
|
|
|
|
If you wish to display a tabbed dialog - the most common use - you should follow these steps.
|
|
|
|
|
|
|
|
\begin{enumerate}\itemsep=0pt
|
|
|
|
\item Create a new wxTabbedDialog class, and any buttons you wish always to be displayed
|
|
|
|
(regardless of which tab is active).
|
|
|
|
\item Create a new wxPanelTabView, passing the dialog as the first argument.
|
|
|
|
\item Set the view rectangle with \helpref{wxTabView::SetViewRect}{wxtabviewsetviewrect},
|
|
|
|
to specify the area in which child panels will be
|
|
|
|
shown. The tabs will sit on top of this view rectangle.
|
|
|
|
\item Call \helpref{wxTabView::CalculateTabWidth}{wxtabviewcalculatetabwidth} to calculate
|
|
|
|
the width of the tabs based on the view area. This is optional if, for example, you have one row
|
|
|
|
of tabs which does not extend the full width of the view area.
|
|
|
|
\item Call \helpref{wxTabView::AddTab}{wxtabviewaddtab} for each of the tabs you wish to create, passing
|
|
|
|
a unique identifier and a tab label.
|
|
|
|
\item Construct a number of windows, one for each tab, and call \helpref{wxPanelTabView::AddTabWindow}{wxpaneltabviewaddtabwindow} for
|
|
|
|
each of these, passing a tab identifier and the window.
|
|
|
|
\item Set the tab selection.
|
|
|
|
\item Show the dialog.
|
|
|
|
\end{enumerate}
|
|
|
|
|
|
|
|
Under Motif, you may also need to size the dialog just before setting the tab selection, for unknown reasons.
|
|
|
|
|
|
|
|
Some constraints you need to be aware of:
|
|
|
|
|
|
|
|
\begin{itemize}\itemsep=0pt
|
|
|
|
\item All tabs must be of the same width.
|
|
|
|
\item Omit the wxTAB\_STYLE\_COLOUR\_INTERIOR flag to ensure that the dialog background
|
|
|
|
and tab backgrounds match.
|
|
|
|
\end{itemize}
|
|
|
|
|
|
|
|
\subsection{Example}
|
|
|
|
|
|
|
|
The following fragment is taken from the file test.cpp.
|
|
|
|
|
|
|
|
{\small
|
|
|
|
\begin{verbatim}
|
|
|
|
void MyDialog::Init(void)
|
|
|
|
{
|
|
|
|
int dialogWidth = 365;
|
|
|
|
int dialogHeight = 390;
|
|
|
|
|
|
|
|
wxButton *okButton = new wxButton(this, wxID_OK, "Close", wxPoint(100, 330), wxSize(80, 25));
|
|
|
|
wxButton *cancelButton = new wxButton(this, wxID_CANCEL, "Cancel", wxPoint(185, 330), wxSize(80, 25));
|
|
|
|
wxButton *HelpButton = new wxButton(this, wxID_HELP, "Help", wxPoint(270, 330), wxSize(80, 25));
|
|
|
|
okButton->SetDefault();
|
|
|
|
|
|
|
|
// Note, omit the wxTAB_STYLE_COLOUR_INTERIOR, so we will guarantee a match
|
|
|
|
// with the panel background, and save a bit of time.
|
|
|
|
wxPanelTabView *view = new wxPanelTabView(this, wxTAB_STYLE_DRAW_BOX);
|
|
|
|
|
|
|
|
wxRectangle rect;
|
|
|
|
rect.x = 5;
|
|
|
|
rect.y = 70;
|
|
|
|
// Could calculate the view width from the tab width and spacing,
|
|
|
|
// as below, but let's assume we have a fixed view width.
|
|
|
|
// rect.width = view->GetTabWidth()*4 + 3*view->GetHorizontalTabSpacing();
|
|
|
|
rect.width = 326;
|
|
|
|
rect.height = 250;
|
|
|
|
|
|
|
|
view->SetViewRect(rect);
|
|
|
|
|
|
|
|
// Calculate the tab width for 4 tabs, based on a view width of 326 and
|
|
|
|
// the current horizontal spacing. Adjust the view width to exactly fit
|
|
|
|
// the tabs.
|
|
|
|
view->CalculateTabWidth(4, TRUE);
|
|
|
|
|
|
|
|
if (!view->AddTab(TEST_TAB_CAT, wxString("Cat")))
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (!view->AddTab(TEST_TAB_DOG, wxString("Dog")))
|
|
|
|
return;
|
|
|
|
if (!view->AddTab(TEST_TAB_GUINEAPIG, wxString("Guinea Pig")))
|
|
|
|
return;
|
|
|
|
if (!view->AddTab(TEST_TAB_GOAT, wxString("Goat")))
|
|
|
|
return;
|
|
|
|
if (!view->AddTab(TEST_TAB_ANTEATER, wxString("Ant-eater")))
|
|
|
|
return;
|
|
|
|
if (!view->AddTab(TEST_TAB_SHEEP, wxString("Sheep")))
|
|
|
|
return;
|
|
|
|
if (!view->AddTab(TEST_TAB_COW, wxString("Cow")))
|
|
|
|
return;
|
|
|
|
if (!view->AddTab(TEST_TAB_HORSE, wxString("Horse")))
|
|
|
|
return;
|
|
|
|
if (!view->AddTab(TEST_TAB_PIG, wxString("Pig")))
|
|
|
|
return;
|
|
|
|
if (!view->AddTab(TEST_TAB_OSTRICH, wxString("Ostrich")))
|
|
|
|
return;
|
|
|
|
if (!view->AddTab(TEST_TAB_AARDVARK, wxString("Aardvark")))
|
|
|
|
return;
|
|
|
|
if (!view->AddTab(TEST_TAB_HUMMINGBIRD,wxString("Hummingbird")))
|
|
|
|
return;
|
|
|
|
|
|
|
|
// Add some panels
|
|
|
|
wxPanel *panel1 = new wxPanel(this, -1, wxPoint(rect.x + 20, rect.y + 10), wxSize(290, 220), wxTAB_TRAVERSAL);
|
|
|
|
(void)new wxButton(panel1, -1, "Press me", wxPoint(10, 10));
|
|
|
|
(void)new wxTextCtrl(panel1, -1, "1234", wxPoint(10, 40), wxSize(120, 150));
|
|
|
|
|
|
|
|
view->AddTabWindow(TEST_TAB_CAT, panel1);
|
|
|
|
|
|
|
|
wxPanel *panel2 = new wxPanel(this, -1, wxPoint(rect.x + 20, rect.y + 10), wxSize(290, 220));
|
|
|
|
|
|
|
|
wxString animals[] = { "Fox", "Hare", "Rabbit", "Sabre-toothed tiger", "T Rex" };
|
|
|
|
(void)new wxListBox(panel2, -1, wxPoint(5, 5), wxSize(170, 80), 5, animals);
|
|
|
|
|
|
|
|
(void)new wxTextCtrl(panel2, -1, "Some notes about the animals in this house", wxPoint(5, 100), wxSize(170, 100)),
|
|
|
|
wxTE_MULTILINE;
|
|
|
|
|
|
|
|
view->AddTabWindow(TEST_TAB_DOG, panel2);
|
|
|
|
|
|
|
|
// Don't know why this is necessary under Motif...
|
|
|
|
#ifdef wx_motif
|
|
|
|
this->SetSize(dialogWidth, dialogHeight-20);
|
|
|
|
#endif
|
|
|
|
|
|
|
|
view->SetTabSelection(TEST_TAB_CAT);
|
|
|
|
|
|
|
|
this->Centre(wxBOTH);
|
|
|
|
}
|
|
|
|
\end{verbatim}
|
|
|
|
}
|
|
|
|
|
|
|
|
\subsection{wxTab change log}
|
|
|
|
|
|
|
|
June 3rd 1997, Version 1.2
|
|
|
|
|
|
|
|
\begin{itemize}\itemsep=0pt
|
|
|
|
\item Fixed bug which drew some tabs incorrectly.
|
|
|
|
\item Altered sample to put buttons below tabs, as per standard
|
|
|
|
Windows conventions.
|
|
|
|
\item Added improvements from Hitachi Europe Limited: draws correctly
|
|
|
|
on Motif and Windows, and tabs are now rounded - much nicer.
|
|
|
|
\end{itemize}
|
|
|
|
|
|
|
|
April 29th 1996, Version 1.1
|
|
|
|
|
|
|
|
\begin{itemize}\itemsep=0pt
|
|
|
|
\item Added SetHorizontalTabOffset, SetHorizontalTabSpacing.
|
|
|
|
\item Corrected bug in colouring tabs (1 pixel out).
|
|
|
|
\item Corrected bug in adding tabs: last tab on first row could overlap right-hand
|
|
|
|
edge.
|
|
|
|
\item Added Layout function to allow resizing of the view rectangle and subsequent redrawing
|
|
|
|
of the tabs.
|
|
|
|
\item Added WXTAB\_VERSION symbol.
|
|
|
|
\item Fixed bug in SetTabSelection which did not move the selected tab to the first row.
|
|
|
|
\item Added argument in SetTabSelection to optionally avoid calling activation code.
|
|
|
|
\item Changed wxPanelTabView API to allow use of any window, not just a panel, in a tab.
|
|
|
|
\end{itemize}
|
|
|
|
|
|
|
|
April 24th 1996, Version 1.0
|
|
|
|
|
|
|
|
\begin{itemize}\itemsep=0pt
|
|
|
|
\item First release.
|
|
|
|
\end{itemize}
|
|
|
|
|
|
|
|
\section{wxTabView overview}\label{wxtabviewoverview}
|
|
|
|
|
|
|
|
Classes: \helpref{wxTabView}{wxtabview}, \helpref{wxPanelTabView}{wxpaneltabview}
|
|
|
|
|
|
|
|
A wxTabView manages and draws a number of tabs. Because it is separate
|
|
|
|
from the tabbed window implementation, it can be reused in a number of contexts.
|
|
|
|
This library provides tabbed dialog and panel classes to use with the
|
|
|
|
wxPanelTabView class, but an application could derive other kinds of
|
|
|
|
view from wxTabView.
|
|
|
|
|
|
|
|
For example, a help application might draw a representation of a book on
|
1998-06-14 16:48:39 -04:00
|
|
|
a window, with a row of tabs along the top. The new tab view class might
|
1998-05-20 10:25:30 -04:00
|
|
|
be called wxCanvasTabView, for example, with the wxBookCanvas posting
|
|
|
|
the OnEvent function to the wxCanvasTabView before processing further,
|
|
|
|
application-specific event processing.
|
|
|
|
|
|
|
|
A window class designed to work with a view class must call the view's
|
|
|
|
OnEvent and Draw functions at appropriate times.
|
|
|
|
|