]> git.saurik.com Git - wxWidgets.git/blob - src/motif/mdi/lib/XsMDICanvas.C
correct positioning of the control and removed workarounds for old MSW bugs
[wxWidgets.git] / src / motif / mdi / lib / XsMDICanvas.C
1 /*
2 Copyright (C) 1996 Scott W. Sadler
3 All rights reserved.
4 */
5
6 /*
7 XsMDICanvas.C
8
9 History
10 03-Mar-96 1.0; Scott W. Sadler (ssadler@cisco.com)
11 Created
12 */
13
14 // Includes
15
16 #include <assert.h>
17 #include <Xm/ScrolledW.h>
18 #include <Xm/DrawingA.h>
19 #include "XsMDICanvas.h"
20 #include "XsMDIWindow.h"
21
22 // Static definitions
23
24 String XsMDICanvas::_resources[] = {
25 "*canvas.resizePolicy: XmRESIZE_GROW",
26 NULL
27 };
28
29 // Constructor
30
31 XsMDICanvas::XsMDICanvas (const char *name, Widget parent) : XsComponent (name)
32 {
33 assert (parent != 0);
34
35 // Initialize
36
37 _list = 0;
38 _num = 0;
39 _max = 0;
40 _place = 0;
41
42 // Install resources
43
44 _setResources (parent, _resources);
45
46 // Create the scrolled window
47
48 const int nargs = 10;
49 Arg args[nargs];
50 int n = 0;
51
52 XtSetArg (args[n], XmNscrollingPolicy, XmAUTOMATIC); n++;
53 XtSetArg (args[n], XmNscrolledWindowMarginHeight, (Dimension)0); n++;
54 XtSetArg (args[n], XmNscrolledWindowMarginWidth, (Dimension)0); n++;
55 XtSetArg (args[n], XmNmarginHeight, (Dimension)5); n++;
56 XtSetArg (args[n], XmNmarginWidth, (Dimension)5); n++;
57
58 assert (n <= nargs);
59
60 _base = XmCreateScrolledWindow (parent, _name, args, n);
61
62 // Install the destroy handler
63
64 _installDestroyHandler ( );
65
66 // Create the drawing area (canvas)
67
68 _drawArea = XtVaCreateWidget ("canvas", xmDrawingAreaWidgetClass,
69 _base, XmNmarginHeight, (Dimension)0, XmNmarginWidth, (Dimension)0,
70 NULL);
71
72 // Set resize callback on drawing area
73
74 XtAddCallback (_drawArea, XmNresizeCallback, _canvasResizeCallback, (XtPointer)this);
75
76 // Set resize callback on clip window
77
78 XtVaGetValues (_base, XmNclipWindow, &_clipWin, NULL);
79 XtAddCallback (_clipWin, XmNresizeCallback, _clipResizeCallback, (XtPointer)this);
80 }
81
82 // Destructor
83
84 XsMDICanvas::~XsMDICanvas ( )
85 {
86
87 /*
88 Remove callbacks to prevent calls to destroyed class-part of XsMDICanvas
89 while children are being destroyed.
90 */
91
92 if (_drawArea)
93 XtRemoveCallback (_drawArea, XmNresizeCallback, _canvasResizeCallback, (XtPointer)this);
94
95 if (_clipWin)
96 XtRemoveCallback (_clipWin, XmNresizeCallback, _clipResizeCallback, (XtPointer)this);
97
98 // Remove all windows
99
100 removeAll ( );
101 }
102
103 // add
104
105 void XsMDICanvas::add (XsMDIWindow *win)
106 {
107 assert (win != 0);
108
109 const int increment = 10;
110
111 // Check if we need to allocate more space
112
113 if (_num >= _max)
114 {
115 XsMDIWindow **newList = new XsMDIWindow*[_max + increment];
116
117 for (int loop = 0; loop < _num; loop++)
118 newList[loop] = _list[loop];
119 _max += increment;
120
121 delete [] _list;
122 _list = newList;
123 }
124
125 // Add the new window
126
127 _list[_num++] = win;
128
129 // Install the parent canvas
130
131 win->_setWindowParent (_drawArea);
132
133 // If the canvas is shown, place the window
134
135 if (XtIsManaged (_base))
136 _placeWindow (win);
137 }
138
139 // remove
140
141 void XsMDICanvas::remove (XsMDIWindow *win)
142 {
143 assert (win != 0);
144
145 // Remove the window
146
147 int i, j;
148
149 for (i = 0; i < _num; i++)
150 {
151 if (_list[i] == win)
152 {
153 win->hide ( );
154 win->_setWindowParent (0);
155
156 for (j = i; j < _num - 1; j++)
157 _list[j] = _list[j + 1];
158 _num--;
159
160 return;
161 }
162 }
163
164 assert (0); // Couldn't find window
165 }
166
167 // removeAll
168
169 void XsMDICanvas::removeAll ( )
170 {
171
172 // Delete and reset the list
173
174 delete [] _list;
175
176 _list = 0;
177 _num = 0;
178 _max = 0;
179 }
180
181 // show
182
183 void XsMDICanvas::show ( )
184 {
185 assert (_drawArea != 0);
186
187 // Place all of the child windows
188
189 for (int loop = 0; loop < _num; loop++)
190 _placeWindow (_list[loop]);
191
192 // Manage the drawing area and canvas
193
194 XtManageChild (_drawArea);
195
196 // Call base class
197
198 XsComponent::show ( );
199 }
200
201 // className
202
203 const char* XsMDICanvas::className ( ) const
204 {
205 return ("XsMDICanvas");
206 }
207
208 // _componentDestroyed
209
210 void XsMDICanvas::_componentDestroyed ( )
211 {
212
213 // Remove the callbacks
214
215 XtRemoveCallback (_drawArea, XmNresizeCallback, _canvasResizeCallback, (XtPointer)this);
216 XtRemoveCallback (_clipWin, XmNresizeCallback, _clipResizeCallback, (XtPointer)this);
217
218 _drawArea = 0;
219 _clipWin = 0;
220 }
221
222 // _placeWindow
223
224 void XsMDICanvas::_placeWindow (XsMDIWindow *win)
225 {
226 assert (win != 0);
227
228 // Compute window placement
229
230 Position x, y;
231
232 const int maxWin = 10;
233 const Position offset = 20;
234 const Position minOffset = 10;
235
236 x = (_place * offset) + minOffset;
237 y = (_place * offset) + minOffset;
238
239 if (++_place == maxWin)
240 _place = 0;
241
242 // Set the window placement
243
244 win->setPosition (x, y);
245
246 // Show the window
247
248 win->show ( );
249 }
250
251 // _resize
252
253 void XsMDICanvas::_resize (XtPointer)
254 {
255 Dimension clipHeight;
256 Dimension clipWidth;
257 Dimension canvasHeight;
258 Dimension canvasWidth;
259
260 // Check if clip window and canvas are managed
261
262 if (!XtIsManaged (_clipWin) || !XtIsManaged (_drawArea))
263 return;
264
265 // Get the clip window size
266
267 XtVaGetValues (_clipWin, XmNwidth, &clipWidth, XmNheight, &clipHeight, NULL);
268
269 // Get the canvas size
270
271 XtVaGetValues (_drawArea, XmNwidth, &canvasWidth, XmNheight, &canvasHeight, NULL);
272
273 // Force the canvas to be at least as big as the clip window
274
275 if (canvasWidth < clipWidth)
276 canvasWidth = clipWidth;
277 if (canvasHeight < clipHeight)
278 canvasHeight = clipHeight;
279
280 XtVaSetValues (_drawArea, XmNwidth, canvasWidth, XmNheight, canvasHeight, NULL);
281 }
282
283 // _clipResizeCallback
284
285 void XsMDICanvas::_clipResizeCallback (Widget, XtPointer clientData, XtPointer callData)
286 {
287 XsMDICanvas *obj = (XsMDICanvas*)clientData;
288 obj->_resize (callData);
289 }
290
291 // _canvasResizeCallback
292
293 void XsMDICanvas::_canvasResizeCallback (Widget, XtPointer clientData, XtPointer callData)
294 {
295 XsMDICanvas *obj = (XsMDICanvas*)clientData;
296 obj->_resize (callData);
297 }
298