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