1 /***********************************************************************/
2 /* Open Visualization Data Explorer */
3 /* (C) Copyright IBM Corp. 1989,1999 */
4 /* ALL RIGHTS RESERVED */
5 /* This code licensed under the */
6 /* "IBM PUBLIC LICENSE - Open Visualization Data Explorer" */
7 /***********************************************************************/
8
9 #include <dxconfig.h>
10 #include "../base/defines.h"
11
12
13 #include "WorkSpace.h"
14 #include "WorkSpaceRoot.h"
15 #include "WorkSpaceInfo.h"
16 #include "ListIterator.h"
17 #include "SymbolManager.h"
18
19
20 #include <Xm/Xm.h>
21 #include "WorkspaceW.h"
22 #include <Xm/ScrolledW.h>
23
24
25 //
26 // This routine is called when the scrolled window is resized. It tries
27 // to keep the Workspace the same size as the scrolled window. If the
28 // ScrolledWindow is displaying ScrollBars (we can detect this by looking
29 // at the position of the ScrollBars), then we take the ScrollBar
30 // dimensions into account when resizing the Workspace widget. This routine
31 // is also called from WorkSpaceInfo::setDefaultConfiguration (so we can
32 // get rid of the ScrollBars when the user does a "New").
33 //
resizeWorkSpace()34 void WorkSpaceRoot::resizeWorkSpace()
35 {
36 Dimension width, height;
37 Dimension sw_width, sw_height;
38 Dimension vsb_width, hsb_height;
39 Widget wid, vsb, hsb;
40 int max_w, max_h;
41
42 Widget widget = XtParent(XtParent(this->getWorkSpaceWidget()));
43
44 int page = this->getCurrentPage();
45 if (page) {
46 WorkSpace* ws = this->getElement(page);
47 XmWorkspaceGetMaxWidthHeight(ws->getRootWidget(), &max_w, &max_h);
48 } else {
49 XmWorkspaceGetMaxWidthHeight(this->getWorkSpaceWidget(), &max_w, &max_h);
50 }
51
52
53 vsb_width = 0;
54 hsb_height = 0;
55 if(XmIsScrolledWindow(widget)) {
56 Position x, y;
57
58 XtVaGetValues(widget,
59 XmNhorizontalScrollBar, &hsb,
60 XmNverticalScrollBar, &vsb,
61 NULL);
62 XtVaGetValues(widget, XmNwidth, &sw_width, XmNheight, &sw_height, NULL);
63
64 //
65 // Vertical ScrollBar
66 //
67 if (XtIsManaged(vsb)) {
68 XtVaGetValues(vsb, XmNx, &x, XmNy, &y, NULL);
69 if ((x < sw_width) && (y < sw_height))
70 XtVaGetValues(vsb, XmNwidth, &vsb_width, NULL);
71 }
72
73 //
74 // Horizontal ScrollBar
75 //
76 if (XtIsManaged(hsb)) {
77 XtVaGetValues(hsb, XmNx, &x, XmNy, &y, NULL);
78 if ((x < sw_width) && (y < sw_height))
79 XtVaGetValues(hsb, XmNheight, &hsb_height, NULL);
80 }
81
82 XtVaGetValues(widget, XmNclipWindow, &wid, NULL);
83
84 XtVaGetValues(wid, XmNwidth, &width, XmNheight,&height, NULL);
85
86 width += vsb_width;
87 height += hsb_height;
88 int mw = MAX(width, max_w);
89 int mh = MAX(height, max_h);
90 this->setDimensions(mw,mh);
91
92 if ((this->current_page) && (this->current_page != UNDETERMINED_PAGE)) {
93 WorkSpace *ws = this->getElement(this->current_page);
94 ws->setWidthHeight(mw,mh);
95 }
96 }
97 }
98
99
100 WorkSpace*
addPage()101 WorkSpaceRoot::addPage()
102 {
103 int max_w, max_h;
104 this->getObjectXYSize (&max_w, &max_h);
105 WorkSpace *ws = this->newPage(max_w,max_h);
106 this->page_list.appendElement ((const void*)ws);
107 ws->setPlacementCount(this->getPlacementCount());
108
109 WorkSpaceInfo *wsinfo = this->getWorkSpaceInfo();
110 unsigned int x_align = wsinfo->getGridXAlignment();
111 unsigned int y_align = wsinfo->getGridYAlignment();
112 int w,h;
113 wsinfo->getGridSpacing(w, h);
114
115 WorkSpaceInfo *newinfo = ws->getInfo();
116 newinfo->setGridAlignment (x_align, y_align);
117 newinfo->setGridSpacing(w, h);
118 newinfo->setGridActive(wsinfo->isGridActive());
119 newinfo->setPreventOverlap(wsinfo->getPreventOverlap());
120 ws->installInfo(NUL(WorkSpaceInfo*));
121
122 return ws;
123 }
124
125 //
126 // Maintain the current_page index by getting the old position, then checking
127 // for existing after removal from the list. If we're deleting other than the
128 // current_page, then the index should decrement by 1 or remain unchanged.
129 //
removePage(const void * ws)130 void WorkSpaceRoot::removePage (const void* ws)
131 {
132 const void* curws = NUL(void*);
133 if ((this->current_page) && (this->current_page != UNDETERMINED_PAGE)) {
134 curws = this->page_list.getElement(this->current_page);
135 ASSERT(curws);
136 }
137
138 ASSERT(this->page_list.removeElement(ws));
139
140 //
141 // If the WorkSpace which used to be current is still in the list,
142 // then its index in the list is the new current_page.
143 //
144 if (curws) {
145 int new_cur_pos = this->page_list.getPosition(curws);
146 if (new_cur_pos) {
147 this->current_page = new_cur_pos;
148 ASSERT (curws != ws);
149 } else {
150 this->current_page = UNDETERMINED_PAGE;
151 ASSERT (curws == ws);
152 }
153 }
154 }
155
156 //
157 //
showWorkSpace(int page)158 void WorkSpaceRoot::showWorkSpace(int page)
159 {
160 if (page == 0) {
161 this->showRoot();
162 this->current_page = 0;
163 return ;
164 }
165
166 WorkSpace *manage_this = NUL(WorkSpace*);
167 WorkSpace *unmanage_this = NUL(WorkSpace*);
168
169 ASSERT(page);
170
171 //
172 // By turning off mappedWhenManaged for children of the root workspace widget,
173 // we make sure that nothing can ever peek around the edge of a page in the
174 // event that our size calculations are off by a couple of pixels.
175 //
176 if (this->current_page == 0) {
177 Widget *kids;
178 int nkids,i;
179 Widget wsw = this->getWorkSpaceWidget();
180 XtVaGetValues (wsw, XmNchildren, &kids, XmNnumChildren, &nkids, NULL);
181 for (i=0; i<nkids; i++) {
182 Widget w = kids[i];
183 if (XtClass(w) == xmWorkspaceWidgetClass) continue;
184 XtVaSetValues (w, XmNmappedWhenManaged, False, NULL);
185 }
186 }
187
188 if (page == this->current_page) return ;
189 if ((this->current_page) && (this->current_page != UNDETERMINED_PAGE))
190 unmanage_this = this->getElement(this->current_page);
191 manage_this = this->getElement(page);
192
193 if (manage_this) {
194 Dimension w,h;
195 if (this->getWorkSpaceWidget()) {
196 XtVaSetValues(this->getWorkSpaceWidget(),
197 XmNlineDrawingEnabled, False,
198 XmNallowOverlap, True,
199 NULL);
200 XtVaGetValues (this->getWorkSpaceWidget(),
201 XmNwidth, &w, XmNheight, &h, NULL);
202 }
203 manage_this->manage();
204 Widget wsr = manage_this->getRootWidget();
205 if (wsr) {
206 Dimension old_w, old_h;
207 /*
208 XtVaSetValues(wsr,
209 XmNlineDrawingEnabled, manage_this->getLineDrawing(),
210 XmNallowOverlap, manage_this->getOverlap(),
211 NULL);
212 */
213 XtVaGetValues (wsr, XmNwidth, &old_w, XmNheight, &old_h, NULL);
214
215 if ((old_w < w) && (old_h < h))
216 XtVaSetValues (wsr, XmNwidth, old_w, XmNheight, old_h, NULL);
217 else if (old_w < w)
218 XtVaSetValues (wsr, XmNwidth, old_w, NULL);
219 else if (old_h < h)
220 XtVaSetValues (wsr, XmNheight, old_h, NULL);
221
222 XMapRaised (XtDisplay(wsr), XtWindow(wsr));
223 }
224 XSync(XtDisplay(this->getWorkSpaceWidget()), False);
225 }
226
227 //
228 // Found one to take down from the screen.
229 //
230 if (unmanage_this) {
231 unmanage_this->unmanage();
232 }
233
234 this->current_page = page;
235 }
236
showWorkSpace(WorkSpace * page)237 void WorkSpaceRoot::showWorkSpace(WorkSpace* page)
238 {
239 int pos = this->page_list.getPosition((void*)page);
240 this->showWorkSpace(pos);
241 }
242
showRoot()243 void WorkSpaceRoot::showRoot()
244 {
245 if ((this->current_page) && (this->current_page != UNDETERMINED_PAGE)) {
246 WorkSpace* ws = this->getElement(this->current_page);
247 ASSERT(ws);
248 ws->unmanage();
249 }
250 Widget wsw = this->getWorkSpaceWidget();
251 ASSERT(wsw);
252 if (this->getPlacementCount() == 0) {
253 XtVaSetValues(wsw,
254 XmNlineDrawingEnabled, this->getLineDrawingEnabled(),
255 XmNallowOverlap, this->getOverlapEnabled(),
256 NULL);
257 }
258
259 this->current_page = 0;
260
261 //
262 // By turning off mappedWhenManaged for children of the root workspace widget,
263 // we make sure that nothing can ever peek around the edge of a page in the
264 // event that our size calculations are off by a couple of pixels.
265 //
266 Widget *kids;
267 int nkids,i;
268 XtVaGetValues (wsw, XmNchildren, &kids, XmNnumChildren, &nkids, NULL);
269 for (i=0; i<nkids; i++) {
270 Widget w = kids[i];
271 if (XtClass(w) == xmWorkspaceWidgetClass) continue;
272 XtVaSetValues (w, XmNmappedWhenManaged, True, NULL);
273 }
274 }
275
276 //
277 // Determine if this WorkSpace is a WorkSpace of the given class
278 //
isA(const char * classname)279 boolean WorkSpaceRoot::isA(const char *classname)
280 {
281 Symbol s = theSymbolManager->registerSymbol(classname);
282 return this->isA(s);
283 }
284 //
285 // Determine if this WorkSpace is of the given class.
286 //
isA(Symbol classname)287 boolean WorkSpaceRoot::isA(Symbol classname)
288 {
289 Symbol s = theSymbolManager->registerSymbol(ClassWorkSpaceRoot);
290 return (s == classname);
291 }
292
293
294 //
295 // P E R F O R M T H E S A M E O P E R A T I O N O N P A G E S
296 // P E R F O R M T H E S A M E O P E R A T I O N O N P A G E S
297 // P E R F O R M T H E S A M E O P E R A T I O N O N P A G E S
298 // P E R F O R M T H E S A M E O P E R A T I O N O N P A G E S
299 // P E R F O R M T H E S A M E O P E R A T I O N O N P A G E S
300 // P E R F O R M T H E S A M E O P E R A T I O N O N P A G E S
301 //
~WorkSpaceRoot()302 WorkSpaceRoot::~WorkSpaceRoot()
303 {
304 WorkSpace *ws;
305 ListIterator it(this->page_list);
306 while ( (ws = (WorkSpace*)it.getNext()) )
307 delete ws;
308 }
setPageCursor(int cursorType)309 void WorkSpaceRoot::setPageCursor (int cursorType)
310 {
311 WorkSpace *ws;
312 ListIterator it(this->page_list);
313 while ( (ws = (WorkSpace*)it.getNext()) )
314 ws->setCursor(cursorType);
315 }
resetPageCursor()316 void WorkSpaceRoot::resetPageCursor()
317 {
318 WorkSpace *ws;
319 ListIterator it(this->page_list);
320 while ( (ws = (WorkSpace*)it.getNext()) )
321 ws->resetCursor();
322 }
installPageInfo(WorkSpaceInfo * new_info)323 void WorkSpaceRoot::installPageInfo (WorkSpaceInfo* new_info)
324 {
325 int w,h;
326
327 WorkSpaceInfo* info = (new_info?new_info: this->getWorkSpaceInfo());
328
329 unsigned int x_align = info->getGridXAlignment();
330 unsigned int y_align = info->getGridYAlignment();
331 boolean is_active = info->isGridActive();
332 boolean prevent_overlap = info->getPreventOverlap();
333 info->getGridSpacing(w,h);
334
335 ListIterator it(this->page_list);
336 WorkSpace *ws = NULL;
337 while ( (ws = (WorkSpace*)it.getNext()) ) {
338 WorkSpaceInfo *page_info = ws->getInfo();
339 page_info->setGridAlignment (x_align, y_align);
340 page_info->setGridActive (is_active);
341 page_info->setGridSpacing (w,h);
342 page_info->setPreventOverlap(prevent_overlap);
343 ws->installInfo(NULL);
344 }
345 }
beginManyPagePlacements()346 void WorkSpaceRoot::beginManyPagePlacements()
347 {
348 ListIterator it(this->page_list);
349 WorkSpace *ws = NULL;
350 while ( (ws = (WorkSpace*)it.getNext()) )
351 ws->beginManyPlacements();
352 }
endManyPagePlacements()353 void WorkSpaceRoot::endManyPagePlacements()
354 {
355 ListIterator it(this->page_list);
356 WorkSpace *ws = NULL;
357 while ( (ws = (WorkSpace*)it.getNext()) )
358 ws->endManyPlacements();
359 }
360
361
362