161 lines
7.1 KiB
TeX
161 lines
7.1 KiB
TeX
|
\section{Constraints overview}\label{constraintsoverview}
|
||
|
|
||
|
Classes: \helpref{wxLayoutConstraints}{wxlayoutconstraints}, \helpref{wxIndividualLayoutConstraint}{wxindividuallayoutconstraint}.
|
||
|
|
||
|
Objects of class wxLayoutConstraint can be associated with a window to define the
|
||
|
way its subwindows are laid out, with respect to their siblings or parent.
|
||
|
|
||
|
The class consists of the following eight constraints of class wxIndividualLayoutConstraint,
|
||
|
some or all of which should be accessed directly to set the appropriate
|
||
|
constraints.
|
||
|
|
||
|
\begin{itemize}\itemsep=0pt
|
||
|
\item {\bf left:} represents the left hand edge of the window
|
||
|
\item {\bf right:} represents the right hand edge of the window
|
||
|
\item {\bf top:} represents the top edge of the window
|
||
|
\item {\bf bottom:} represents the bottom edge of the window
|
||
|
\item {\bf width:} represents the width of the window
|
||
|
\item {\bf height:} represents the height of the window
|
||
|
\item {\bf centreX:} represents the horizontal centre point of the window
|
||
|
\item {\bf centreY:} represents the vertical centre point of the window
|
||
|
\end{itemize}
|
||
|
|
||
|
Most constraints are initially set to have the relationship wxUnconstrained,
|
||
|
which means that their values should be calculated by looking at known constraints.
|
||
|
The exceptions are {\it width} and {\it height}, which are set to wxAsIs to
|
||
|
ensure that if the user does not specify a constraint, the existing
|
||
|
width and height will be used, to be compatible with panel items which often
|
||
|
have take a default size. If the constraint is wxAsIs, the dimension will
|
||
|
not be changed.
|
||
|
|
||
|
To call the \helpref{wxWindow::Layout}{wxwindowlayout} function which evaluates
|
||
|
constraints, you can either call wxWindow::SetAutoLayout to tell
|
||
|
default OnSize handlers to call Layout, or override OnSize and call Layout yourself.
|
||
|
|
||
|
\subsection{Constraint layout: more detail}
|
||
|
|
||
|
By default, windows do not have a wxLayoutConstraints object. In this case, much layout
|
||
|
must be done explicitly, by performing calculations in OnSize members, except
|
||
|
for the case of frames that have one subwindow, where wxFrame::OnSize takes care
|
||
|
of resizing the child.
|
||
|
|
||
|
To avoid the need for these rather awkward calculations, the user can create
|
||
|
a wxLayoutConstraints object and associate it with a window with wxWindow::SetConstraints.
|
||
|
This object contains a constraint for each of the window edges, two for the centre point,
|
||
|
and two for the window size. By setting some or all of these constraints appropriately,
|
||
|
the user can achieve quite complex layout by defining relationships between windows.
|
||
|
|
||
|
In wxWindows, each window can be constrained relative to either its {\it
|
||
|
siblings} on the same window, or the {\it parent}. The layout algorithm
|
||
|
therefore operates in a top-down manner, finding the correct layout for
|
||
|
the children of a window, then the layout for the grandchildren, and so
|
||
|
on. Note that this differs markedly from native Motif layout, where
|
||
|
constraints can ripple upwards and can eventually change the frame
|
||
|
window or dialog box size. We assume in wxWindows that the {\it user} is
|
||
|
always `boss' and specifies the size of the outer window, to which
|
||
|
subwindows must conform. Obviously, this might be a limitation in some
|
||
|
circumstances, but it suffices for most situations, and the
|
||
|
simplification avoids some of the nightmarish problems associated with
|
||
|
programming Motif.
|
||
|
|
||
|
When the user sets constraints, many of the constraints for windows
|
||
|
edges and dimensions remain unconstrained. For a given window,
|
||
|
the wxWindow::Layout algorithm first resets all constraints
|
||
|
in all children to have unknown edge or dimension values, and then iterates through the constraints,
|
||
|
evaulating them. For unconstrained edges and dimensions, it
|
||
|
tries to find the value using known relationships that always hold. For example,
|
||
|
an unconstrained {\it width} may be calculated from the {\it left} and {\it right edges}, if
|
||
|
both are currently known. For edges and dimensions with user-supplied constraints, these
|
||
|
constraints are evaulated if the inputs of the constraint are known.
|
||
|
|
||
|
The algorithm stops when all child edges and dimension are known (success), or there
|
||
|
there are unknown edges or dimensions but there has been no change in this cycle (failure).
|
||
|
|
||
|
It then sets all the window positions and sizes according to the values it has found.
|
||
|
|
||
|
Because the algorithm is iterative, the order in which constraints are considered is
|
||
|
irrelevant.
|
||
|
|
||
|
\subsection{Window layout examples}\label{layoutexamples}
|
||
|
|
||
|
\subsubsection{Example 1: subwindow layout}
|
||
|
|
||
|
This example specifies a panel and a canvas side by side,
|
||
|
with a text subwindow below it.
|
||
|
|
||
|
\begin{verbatim}
|
||
|
frame->panel = new wxPanel(frame, 0, 0, 1000, 500, 0);
|
||
|
frame->canvas = new MyCanvas(frame, 0, 0, 400, 400, wxRETAINED);
|
||
|
frame->text_window = new MyTextWindow(frame, 0, 250, 400, 250, wxNATIVE_IMPL);
|
||
|
|
||
|
// Set constraints for panel subwindow
|
||
|
wxLayoutConstraints *c1 = new wxLayoutConstraints;
|
||
|
|
||
|
c1->left.SameAs (frame, wxLeft);
|
||
|
c1->top.SameAs (frame, wxTop);
|
||
|
c1->right.PercentOf (frame, wxWidth, 50);
|
||
|
c1->height.PercentOf (frame, wxHeight, 50);
|
||
|
|
||
|
frame->panel->SetConstraints(c1);
|
||
|
|
||
|
// Set constraints for canvas subwindow
|
||
|
wxLayoutConstraints *c2 = new wxLayoutConstraints;
|
||
|
|
||
|
c2->left.SameAs (frame->panel, wxRight);
|
||
|
c2->top.SameAs (frame, wxTop);
|
||
|
c2->right.SameAs (frame, wxRight);
|
||
|
c2->height.PercentOf (frame, wxHeight, 50);
|
||
|
|
||
|
frame->canvas->SetConstraints(c2);
|
||
|
|
||
|
// Set constraints for text subwindow
|
||
|
wxLayoutConstraints *c3 = new wxLayoutConstraints;
|
||
|
c3->left.SameAs (frame, wxLeft);
|
||
|
c3->top.Below (frame->panel);
|
||
|
c3->right.SameAs (frame, wxRight);
|
||
|
c3->bottom.SameAs (frame, wxBottom);
|
||
|
|
||
|
frame->text_window->SetConstraints(c3);
|
||
|
\end{verbatim}
|
||
|
|
||
|
\subsubsection{Example 2: panel item layout}
|
||
|
|
||
|
This example sizes a button width to 80 percent of the panel width, and centres
|
||
|
it horizontally. A listbox and multitext item are placed below it. The listbox
|
||
|
takes up 40 percent of the panel width, and the multitext item takes up
|
||
|
the remainder of the width. Margins of 5 pixels are used.
|
||
|
|
||
|
\begin{verbatim}
|
||
|
// Create some panel items
|
||
|
wxButton *btn1 = new wxButton(frame->panel, (wxFunction)NULL, "A button") ;
|
||
|
|
||
|
wxLayoutConstraints *b1 = new wxLayoutConstraints;
|
||
|
b1->centreX.SameAs (frame->panel, wxCentreX);
|
||
|
b1->top.SameAs (frame->panel, wxTop, 5);
|
||
|
b1->width.PercentOf (frame->panel, wxWidth, 80);
|
||
|
b1->height.PercentOf (frame->panel, wxHeight, 10);
|
||
|
btn1->SetConstraints(b1);
|
||
|
|
||
|
wxListBox *list = new wxListBox(frame->panel, (wxFunction)NULL, "A list",
|
||
|
wxSINGLE, -1, -1, 200, 100);
|
||
|
|
||
|
wxLayoutConstraints *b2 = new wxLayoutConstraints;
|
||
|
b2->top.Below (btn1, 5);
|
||
|
b2->left.SameAs (frame->panel, wxLeft, 5);
|
||
|
b2->width.PercentOf (frame->panel, wxWidth, 40);
|
||
|
b2->bottom.SameAs (frame->panel, wxBottom, 5);
|
||
|
list->SetConstraints(b2);
|
||
|
|
||
|
wxMultiText *mtext = new wxMultiText(frame->panel, (wxFunction)NULL, "Multiline text", "Some text",
|
||
|
-1, -1, 150, 100);
|
||
|
|
||
|
wxLayoutConstraints *b3 = new wxLayoutConstraints;
|
||
|
b3->top.Below (btn1, 5);
|
||
|
b3->left.RightOf (list, 5);
|
||
|
b3->right.SameAs (frame->panel, wxRight, 5);
|
||
|
b3->bottom.SameAs (frame->panel, wxBottom, 5);
|
||
|
mtext->SetConstraints(b3);
|
||
|
\end{verbatim}
|
||
|
|
||
|
|