]>
Commit | Line | Data |
---|---|---|
a660d684 KB |
1 | \section{Constraints overview}\label{constraintsoverview} |
2 | ||
3 | Classes: \helpref{wxLayoutConstraints}{wxlayoutconstraints}, \helpref{wxIndividualLayoutConstraint}{wxindividuallayoutconstraint}. | |
4 | ||
5 | Objects of class wxLayoutConstraint can be associated with a window to define the | |
6 | way its subwindows are laid out, with respect to their siblings or parent. | |
7 | ||
8 | The class consists of the following eight constraints of class wxIndividualLayoutConstraint, | |
9 | some or all of which should be accessed directly to set the appropriate | |
10 | constraints. | |
11 | ||
12 | \begin{itemize}\itemsep=0pt | |
13 | \item {\bf left:} represents the left hand edge of the window | |
14 | \item {\bf right:} represents the right hand edge of the window | |
15 | \item {\bf top:} represents the top edge of the window | |
16 | \item {\bf bottom:} represents the bottom edge of the window | |
17 | \item {\bf width:} represents the width of the window | |
18 | \item {\bf height:} represents the height of the window | |
19 | \item {\bf centreX:} represents the horizontal centre point of the window | |
20 | \item {\bf centreY:} represents the vertical centre point of the window | |
21 | \end{itemize} | |
22 | ||
23 | Most constraints are initially set to have the relationship wxUnconstrained, | |
24 | which means that their values should be calculated by looking at known constraints. | |
25 | The exceptions are {\it width} and {\it height}, which are set to wxAsIs to | |
26 | ensure that if the user does not specify a constraint, the existing | |
27 | width and height will be used, to be compatible with panel items which often | |
28 | have take a default size. If the constraint is wxAsIs, the dimension will | |
29 | not be changed. | |
30 | ||
31 | To call the \helpref{wxWindow::Layout}{wxwindowlayout} function which evaluates | |
32 | constraints, you can either call wxWindow::SetAutoLayout to tell | |
33 | default OnSize handlers to call Layout, or override OnSize and call Layout yourself. | |
34 | ||
35 | \subsection{Constraint layout: more detail} | |
36 | ||
37 | By default, windows do not have a wxLayoutConstraints object. In this case, much layout | |
38 | must be done explicitly, by performing calculations in OnSize members, except | |
39 | for the case of frames that have one subwindow, where wxFrame::OnSize takes care | |
40 | of resizing the child. | |
41 | ||
42 | To avoid the need for these rather awkward calculations, the user can create | |
43 | a wxLayoutConstraints object and associate it with a window with wxWindow::SetConstraints. | |
44 | This object contains a constraint for each of the window edges, two for the centre point, | |
45 | and two for the window size. By setting some or all of these constraints appropriately, | |
46 | the user can achieve quite complex layout by defining relationships between windows. | |
47 | ||
48 | In wxWindows, each window can be constrained relative to either its {\it | |
49 | siblings} on the same window, or the {\it parent}. The layout algorithm | |
50 | therefore operates in a top-down manner, finding the correct layout for | |
51 | the children of a window, then the layout for the grandchildren, and so | |
52 | on. Note that this differs markedly from native Motif layout, where | |
53 | constraints can ripple upwards and can eventually change the frame | |
54 | window or dialog box size. We assume in wxWindows that the {\it user} is | |
55 | always `boss' and specifies the size of the outer window, to which | |
56 | subwindows must conform. Obviously, this might be a limitation in some | |
57 | circumstances, but it suffices for most situations, and the | |
58 | simplification avoids some of the nightmarish problems associated with | |
59 | programming Motif. | |
60 | ||
61 | When the user sets constraints, many of the constraints for windows | |
62 | edges and dimensions remain unconstrained. For a given window, | |
63 | the wxWindow::Layout algorithm first resets all constraints | |
64 | in all children to have unknown edge or dimension values, and then iterates through the constraints, | |
65 | evaulating them. For unconstrained edges and dimensions, it | |
66 | tries to find the value using known relationships that always hold. For example, | |
67 | an unconstrained {\it width} may be calculated from the {\it left} and {\it right edges}, if | |
68 | both are currently known. For edges and dimensions with user-supplied constraints, these | |
69 | constraints are evaulated if the inputs of the constraint are known. | |
70 | ||
71 | The algorithm stops when all child edges and dimension are known (success), or there | |
72 | there are unknown edges or dimensions but there has been no change in this cycle (failure). | |
73 | ||
74 | It then sets all the window positions and sizes according to the values it has found. | |
75 | ||
76 | Because the algorithm is iterative, the order in which constraints are considered is | |
77 | irrelevant. | |
78 | ||
79 | \subsection{Window layout examples}\label{layoutexamples} | |
80 | ||
81 | \subsubsection{Example 1: subwindow layout} | |
82 | ||
fe604ccd | 83 | This example specifies a panel and a window side by side, |
a660d684 KB |
84 | with a text subwindow below it. |
85 | ||
86 | \begin{verbatim} | |
fe604ccd JS |
87 | frame->panel = new wxPanel(frame, -1, wxPoint(0, 0), wxSize(1000, 500), 0); |
88 | frame->scrollWindow = new MyScrolledWindow(frame, -1, wxPoint(0, 0), wxSize(400, 400), wxRETAINED); | |
89 | frame->text_window = new MyTextWindow(frame, -1, wxPoint(0, 250), wxSize(400, 250)); | |
a660d684 KB |
90 | |
91 | // Set constraints for panel subwindow | |
92 | wxLayoutConstraints *c1 = new wxLayoutConstraints; | |
93 | ||
94 | c1->left.SameAs (frame, wxLeft); | |
95 | c1->top.SameAs (frame, wxTop); | |
96 | c1->right.PercentOf (frame, wxWidth, 50); | |
97 | c1->height.PercentOf (frame, wxHeight, 50); | |
98 | ||
99 | frame->panel->SetConstraints(c1); | |
100 | ||
fe604ccd | 101 | // Set constraints for scrollWindow subwindow |
a660d684 KB |
102 | wxLayoutConstraints *c2 = new wxLayoutConstraints; |
103 | ||
104 | c2->left.SameAs (frame->panel, wxRight); | |
105 | c2->top.SameAs (frame, wxTop); | |
106 | c2->right.SameAs (frame, wxRight); | |
107 | c2->height.PercentOf (frame, wxHeight, 50); | |
108 | ||
fe604ccd | 109 | frame->scrollWindow->SetConstraints(c2); |
a660d684 KB |
110 | |
111 | // Set constraints for text subwindow | |
112 | wxLayoutConstraints *c3 = new wxLayoutConstraints; | |
113 | c3->left.SameAs (frame, wxLeft); | |
114 | c3->top.Below (frame->panel); | |
115 | c3->right.SameAs (frame, wxRight); | |
116 | c3->bottom.SameAs (frame, wxBottom); | |
117 | ||
118 | frame->text_window->SetConstraints(c3); | |
119 | \end{verbatim} | |
120 | ||
121 | \subsubsection{Example 2: panel item layout} | |
122 | ||
123 | This example sizes a button width to 80 percent of the panel width, and centres | |
124 | it horizontally. A listbox and multitext item are placed below it. The listbox | |
125 | takes up 40 percent of the panel width, and the multitext item takes up | |
126 | the remainder of the width. Margins of 5 pixels are used. | |
127 | ||
128 | \begin{verbatim} | |
129 | // Create some panel items | |
fe604ccd | 130 | wxButton *btn1 = new wxButton(frame->panel, -1, "A button") ; |
a660d684 KB |
131 | |
132 | wxLayoutConstraints *b1 = new wxLayoutConstraints; | |
133 | b1->centreX.SameAs (frame->panel, wxCentreX); | |
134 | b1->top.SameAs (frame->panel, wxTop, 5); | |
135 | b1->width.PercentOf (frame->panel, wxWidth, 80); | |
136 | b1->height.PercentOf (frame->panel, wxHeight, 10); | |
137 | btn1->SetConstraints(b1); | |
138 | ||
fe604ccd JS |
139 | wxListBox *list = new wxListBox(frame->panel, -1, "A list", |
140 | wxPoint(-1, -1), wxSize(200, 100)); | |
a660d684 KB |
141 | |
142 | wxLayoutConstraints *b2 = new wxLayoutConstraints; | |
143 | b2->top.Below (btn1, 5); | |
144 | b2->left.SameAs (frame->panel, wxLeft, 5); | |
145 | b2->width.PercentOf (frame->panel, wxWidth, 40); | |
146 | b2->bottom.SameAs (frame->panel, wxBottom, 5); | |
147 | list->SetConstraints(b2); | |
148 | ||
fe604ccd JS |
149 | wxTextCtrl *mtext = new wxTextCtrl(frame->panel, -1, "Multiline text", "Some text", |
150 | wxPoint(-1, -1), wxSize(150, 100), wxTE_MULTILINE); | |
a660d684 KB |
151 | |
152 | wxLayoutConstraints *b3 = new wxLayoutConstraints; | |
153 | b3->top.Below (btn1, 5); | |
154 | b3->left.RightOf (list, 5); | |
155 | b3->right.SameAs (frame->panel, wxRight, 5); | |
156 | b3->bottom.SameAs (frame->panel, wxBottom, 5); | |
157 | mtext->SetConstraints(b3); | |
158 | \end{verbatim} | |
159 | ||
160 |