/***********************************************************************/ /* Open Visualization Data Explorer */ /* (C) Copyright IBM Corp. 1989,1999 */ /* ALL RIGHTS RESERVED */ /* This code licensed under the */ /* "IBM PUBLIC LICENSE - Open Visualization Data Explorer" */ /***********************************************************************/ #include #include #include #include #ifdef DXD_WIN #include "../widgets/XmDX.h" #else #include "XmDX.h" #endif #include "defines.h" #include "WorkSpace.h" #include "WorkSpaceInfo.h" #include "Application.h" #include "List.h" #include "ListIterator.h" #include <../widgets/WorkspaceW.h> String WorkSpace::DefaultResources[] = { ".traversalOn: True", ".marginWidth: 0", ".marginHeight: 0", ".allowResize: True", ".sensitive: True", ".allowMovement: True", ".allowOverlap: False", ".button1PressMode: False", ".resizePolicy: RESIZE_GROW", ".accentPolicy: ACCENT_BACKGROUND", ".horizontalDrawGrid: DRAW_HASH", ".verticalDrawGrid: DRAW_HASH", ".horizontalAlignment: ALIGNMENT_CENTER", ".verticalAlignment: ALIGNMENT_CENTER", ".inclusionPolicy: INCLUDE_ALL", ".outlineType: OUTLINE_EACH", ".selectionPolicy: EXTENDED_SELECT", ".sortPolicy: ALIGNMENT_BEGINNING", NUL(char*) }; WorkSpace::WorkSpace( const char* name, Widget parent, WorkSpaceInfo *wsinfo) : UIComponent(name) { this->info = wsinfo; this->parent = parent; this->info->associateWorkSpace(this); this->activeManyPlacements = 0; } WorkSpace::~WorkSpace() { if (this->isRoot()) XtRemoveEventHandler(this->parent, StructureNotifyMask, False, (XtEventHandler)WorkSpace_ResizeHandlerEH, (XtPointer)this); if (this->info) this->info->associateWorkSpace(NULL); } void WorkSpace::manage() { if (!this->getRootWidget()) this->initializeRootWidget(FALSE); this->UIComponent::manage(); } void WorkSpace::initializeRootWidget(boolean fromFirstIntanceOfADerivedClass) { int w, h, n; Arg warg[20]; boolean prevent_overlap; if (fromFirstIntanceOfADerivedClass) { ASSERT(theApplication); this->setDefaultResources(theApplication->getRootWidget(), WorkSpace::DefaultResources); } n = 0; XtSetArg(warg[n],XmNwidth, this->info->getWidth()); n++; XtSetArg(warg[n],XmNheight, this->info->getHeight()); n++; // // Info from grid spec // WorkSpaceInfo *info = this->info; info->getGridSpacing(w,h); prevent_overlap = info->getPreventOverlap(); XtSetArg(warg[n],XmNgridWidth, w); n++; XtSetArg(warg[n],XmNgridHeight, h); n++; XtSetArg(warg[n],XmNsnapToGrid, (info->isGridActive() ? True : False)); n++; XtSetArg(warg[n],XmNverticalAlignment, info->getGridYAlignment()); n++; XtSetArg(warg[n],XmNhorizontalAlignment, info->getGridXAlignment()); n++; XtSetArg(warg[n],XmNhorizontalDrawGrid, (info->getGridXAlignment() == XmALIGNMENT_NONE) && (info->getGridYAlignment() == XmALIGNMENT_CENTER) ? XmDRAW_NONE : XmDRAW_HASH); n++; XtSetArg(warg[n],XmNverticalDrawGrid, (info->getGridYAlignment() == XmALIGNMENT_NONE) && (info->getGridXAlignment() == XmALIGNMENT_CENTER) ? XmDRAW_NONE : XmDRAW_HASH); n++; XtSetArg(warg[n], XmNpreventOverlap, prevent_overlap); n++; this->setRootWidget( XtCreateWidget (name, xmWorkspaceWidgetClass, this->parent, warg, n)); this->display = XtDisplay(this->getRootWidget()); XtAddCallback(this->getRootWidget(), XmNdefaultActionCallback, (XtCallbackProc)WorkSpace_DefaultActionCB, (XtPointer)this); XtAddCallback(this->getRootWidget(), XmNbackgroundCallback, (XtCallbackProc)WorkSpace_BackgroundCB, (XtPointer)this); XtAddCallback(this->getRootWidget(), XmNselectionCallback, (XtCallbackProc)WorkSpace_SelectionCB, (XtPointer)this); XtAddCallback(this->getRootWidget(), XmNpositionChangeCallback, (XtCallbackProc)WorkSpace_PosChangeCB, (XtPointer)this); // // Record initial lineDrawing, overlap, and manhattan values so that // they can be toggle later, on behalf of pages. // this->saveWorkSpaceParams(NUL(WorkSpace*)); if (this->isRoot()) XtAddEventHandler(this->parent, StructureNotifyMask, False, (XtEventHandler)WorkSpace_ResizeHandlerEH, (XtPointer)this); } extern "C" void WorkSpace_PosChangeCB(Widget widget, XtPointer clientData, XtPointer callData) { WorkSpace *ws = (WorkSpace*) clientData; ws->doPosChangeAction(widget, callData); } extern "C" void WorkSpace_DefaultActionCB(Widget widget, XtPointer clientData, XtPointer callData) { WorkSpace *ws = (WorkSpace*) clientData; ws->doDefaultAction(widget, callData); } extern "C" void WorkSpace_BackgroundCB(Widget widget, XtPointer clientData, XtPointer calldata) { WorkSpace *ws = (WorkSpace*) clientData; Arg arg[2]; ws->doBackgroundAction(widget,calldata); } extern "C" void WorkSpace_SelectionCB(Widget widget, XtPointer clientData, XtPointer calldata) { WorkSpace *ws = (WorkSpace*) clientData; Arg arg[2]; ws->doSelectionAction(widget,calldata); } void WorkSpace::setCursor(int cursorType) { Widget widget; int n; Arg arg[5]; static int _type[] = { XC_ul_angle, XC_fleur, XC_watch, XC_left_ptr }; static Cursor _cursor[4] = { NUL(Cursor), NUL(Cursor), NUL(Cursor), NUL(Cursor) }; widget = this->getRootWidget(); ASSERT(widget); n = 0; XtSetArg(arg[n], XmNbutton1PressMode, True); n++; XtSetValues(widget, arg, n); if (!XtIsRealized(widget)) return; ASSERT(cursorType >= 0 AND cursorType < 4); if (_cursor[cursorType] == NUL(Cursor)) { _cursor[cursorType] = XCreateFontCursor(XtDisplay(widget), _type[cursorType]); } XDefineCursor(XtDisplay(widget), XtWindow(widget), _cursor[cursorType]); XFlush(XtDisplay(widget)); } // // reset the WorkSpace cursor to the default. // void WorkSpace::resetCursor() { Widget widget; int n; Arg arg[2]; widget = this->getRootWidget(); ASSERT(widget); n = 0; XtSetArg(arg[n], XmNbutton1PressMode, False); n++; XtSetValues(widget, arg, n); if (!XtIsRealized(widget)) return; XUndefineCursor(XtDisplay(widget), XtWindow(widget)); XFlush(XtDisplay(widget)); } // // Set the Height and Width of the work space. // void WorkSpace::setWidth(int val) { this->info->setWidth(val); if (!this->getRootWidget()) return; XtVaSetValues(this->getRootWidget(),XmNwidth, val, NULL); } void WorkSpace::setHeight(int val ) { this->info->setHeight(val); if (!this->getRootWidget()) return; XtVaSetValues(this->getRootWidget(),XmNheight, val, NULL); } void WorkSpace::setWidthHeight(int width, int height ) { this->info->setWidth(width); this->info->setHeight(height); if (!this->getRootWidget()) return; XtVaSetValues(this->getRootWidget(), XmNwidth, width, XmNheight, height, NULL); } void WorkSpace::getMaxWidthHeight(int *w, int *h) { XmWorkspaceGetMaxWidthHeight(this->getRootWidget(), w, h); } extern "C" void WorkSpace_ResizeHandlerEH(Widget widget, XtPointer clientdata, XEvent*, Boolean*) { WorkSpace * ws = (WorkSpace*) clientdata; ws->resize(); } // // Install the new grid in the WorkSpace // void WorkSpace::installInfo(WorkSpaceInfo *new_info) { int n, w,h; Arg warg[20]; boolean prevent_overlap; if (new_info) { this->info->disassociateWorkSpace(); this->info = new_info; this->info->associateWorkSpace(this); } prevent_overlap = this->info->getPreventOverlap(); // // Install the grid info in the work space. // n = 0; this->info->getGridSpacing(w,h); XtSetArg(warg[n],XmNgridWidth, w); n++; XtSetArg(warg[n],XmNgridHeight, h); n++; XtSetArg(warg[n],XmNsnapToGrid, (this->info->isGridActive() ? True : False)); n++; XtSetArg(warg[n],XmNverticalAlignment, this->info->getGridYAlignment()); n++; XtSetArg(warg[n],XmNhorizontalAlignment, this->info->getGridXAlignment()); n++; XtSetArg(warg[n],XmNhorizontalDrawGrid, (this->info->getGridXAlignment() == XmALIGNMENT_NONE) && (this->info->getGridYAlignment() == XmALIGNMENT_CENTER) ? XmDRAW_NONE : XmDRAW_HASH); n++; XtSetArg(warg[n],XmNverticalDrawGrid, (this->info->getGridYAlignment() == XmALIGNMENT_NONE) && (this->info->getGridXAlignment() == XmALIGNMENT_CENTER) ? XmDRAW_NONE : XmDRAW_HASH); n++; this->info->getXYSize(&w,&h); XtSetArg(warg[n],XmNwidth, w); n++; XtSetArg(warg[n],XmNheight, h); n++; XtSetArg(warg[n],XmNpreventOverlap, prevent_overlap); n++; XtSetValues(this->getRootWidget(), warg, n); } // // Optimized the work space for a bunch of placements // void WorkSpace::beginManyPlacements() { ASSERT(this->getRootWidget()); ASSERT(this->activeManyPlacements >= 0); this->activeManyPlacements++; if (this->activeManyPlacements == 1) { XtVaSetValues(this->getRootWidget(), XmNlineDrawingEnabled, False, XmNallowOverlap, True, NULL); } } void WorkSpace::endManyPlacements() { ASSERT(this->getRootWidget()); this->activeManyPlacements--; if (this->activeManyPlacements == 0) { Boolean overlap = this->wasAllowOverlap; Boolean drawing = this->wasLineDrawingEnabled; if (this->getRootWidget()) XtVaSetValues(this->getRootWidget(), XmNlineDrawingEnabled, drawing, XmNallowOverlap, overlap, NULL); } ASSERT(this->activeManyPlacements >= 0); } void WorkSpace::setPlacementCount(int count) { boolean active = (count==0); boolean was_active = (this->activeManyPlacements==0); if (active != was_active) { Boolean overlap = (active?this->wasAllowOverlap:True); Boolean drawing = (active?this->wasLineDrawingEnabled:False); if (this->getRootWidget()) XtVaSetValues(this->getRootWidget(), XmNlineDrawingEnabled, drawing, XmNallowOverlap, overlap, NULL); } this->activeManyPlacements = count; } // // This logic is supplied by WorkSpaceRoot with the addition of workspace pages. // This version of resize() is in use only for ControlPanelWorkSpace which isn't // paged as of 12/96. As soon as ControlPanelWorkSpace is converted to use // WorkSpaceRoot and WorkSpacePage, WorkSpace::resize should become pure virtual. // void WorkSpace::resize() { Dimension width, height; Dimension sw_width, sw_height; Dimension vsb_width, hsb_height; int max_w, max_h; Widget wid, vsb, hsb; Widget widget = XtParent(XtParent(this->getRootWidget())); XmWorkspaceGetMaxWidthHeight(this->getRootWidget(), &max_w, &max_h); vsb_width = 0; hsb_height = 0; if(XmIsScrolledWindow(widget)) { Position x, y; XtVaGetValues(widget, XmNhorizontalScrollBar, &hsb, XmNverticalScrollBar, &vsb, NULL); XtVaGetValues(widget, XmNwidth, &sw_width, XmNheight, &sw_height, NULL); // // Vertical ScrollBar // XtVaGetValues(vsb, XmNx, &x, XmNy, &y, NULL); if((x < sw_width) && (y < sw_height)) XtVaGetValues(vsb, XmNwidth, &vsb_width, NULL); // // Horizontal ScrollBar // XtVaGetValues(hsb, XmNx, &x, XmNy, &y, NULL); if((x < sw_width) && (y < sw_height)) XtVaGetValues(hsb, XmNheight, &hsb_height, NULL); } if(XmIsScrolledWindow(widget)) XtVaGetValues(widget, XmNclipWindow, &wid, NULL); else wid = widget; XtVaGetValues(wid, XmNwidth, &width, XmNheight,&height, NULL); width += vsb_width; height += hsb_height; this->setWidthHeight(MAX(width, max_w), MAX(height, max_h)); } // // This will probably be supplied in a virtual version in a subclass unless // there is some reason to have pages with different values. The reason this // routine is required is to make it convenient to have all WorkSpaces use the // same values even though we can't make all WorkSpaces recognize the same // Xdefault setting. So we want to be able to install a parent's values into // a page if that's what the subclass wants. // void WorkSpace::saveWorkSpaceParams(WorkSpace *ws) { Boolean overlap, drawing, manhattan; if (ws) { this->wasAllowOverlap = ws->wasAllowOverlap; this->wasLineDrawingEnabled = ws->wasLineDrawingEnabled; this->wasManhattanEnabled = ws->wasManhattanEnabled; // // Deal with manhattanRoute in a special way. We never toggle its value. // We normally turn on/off lineDrawing. So if manhattanRoute wants to be // off, unset it now and don't ever touch it again. // if (!this->wasManhattanEnabled) XtVaSetValues (this->getRootWidget(), XmNmanhattanRoute, False, NULL); } else { XtVaGetValues(this->getRootWidget(), XmNlineDrawingEnabled, &drawing, XmNallowOverlap, &overlap, XmNmanhattanRoute, &manhattan, NULL); this->wasAllowOverlap = overlap; this->wasLineDrawingEnabled = drawing; this->wasManhattanEnabled = manhattan; } }