2    Copyright (C) 1996 Scott W. Sadler
 
  10       03-Mar-96 1.0; Scott W. Sadler (ssadler@cisco.com)
 
  17 #include <Xm/ScrolledW.h>
 
  18 #include <Xm/DrawingA.h>
 
  19 #include "XsMDICanvas.h"
 
  20 #include "XsMDIWindow.h"
 
  24 String XsMDICanvas::_resources[] = {
 
  25    "*canvas.resizePolicy:     XmRESIZE_GROW",
 
  31 XsMDICanvas::XsMDICanvas (const char *name, Widget parent) : XsComponent (name)
 
  44    _setResources (parent, _resources);
 
  46 // Create the scrolled window
 
  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++;
 
  60    _base = XmCreateScrolledWindow (parent, _name, args, n);
 
  62 // Install the destroy handler
 
  64    _installDestroyHandler ( );
 
  66 // Create the drawing area (canvas)
 
  68    _drawArea = XtVaCreateWidget ("canvas", xmDrawingAreaWidgetClass,
 
  69       _base, XmNmarginHeight, (Dimension)0, XmNmarginWidth, (Dimension)0,
 
  72 // Set resize callback on drawing area
 
  74    XtAddCallback (_drawArea, XmNresizeCallback, _canvasResizeCallback, (XtPointer)this);
 
  76 // Set resize callback on clip window
 
  78    XtVaGetValues (_base, XmNclipWindow, &_clipWin, NULL);
 
  79    XtAddCallback (_clipWin, XmNresizeCallback, _clipResizeCallback, (XtPointer)this);
 
  84 XsMDICanvas::~XsMDICanvas ( )
 
  88    Remove callbacks to prevent calls to destroyed class-part of XsMDICanvas
 
  89    while children are being destroyed.
 
  93       XtRemoveCallback (_drawArea, XmNresizeCallback, _canvasResizeCallback, (XtPointer)this);
 
  96       XtRemoveCallback (_clipWin, XmNresizeCallback, _clipResizeCallback, (XtPointer)this);
 
 105 void XsMDICanvas::add (XsMDIWindow *win)
 
 109    const int increment = 10;
 
 111 // Check if we need to allocate more space
 
 115       XsMDIWindow **newList = new XsMDIWindow*[_max + increment];
 
 117       for (int loop = 0; loop < _num; loop++)
 
 118          newList[loop] = _list[loop];
 
 125 // Add the new window
 
 129 // Install the parent canvas 
 
 131    win->_setWindowParent (_drawArea);
 
 133 // If the canvas is shown, place the window
 
 135    if (XtIsManaged (_base))
 
 141 void XsMDICanvas::remove (XsMDIWindow *win)
 
 149    for (i = 0; i < _num; i++)
 
 154          win->_setWindowParent (0);
 
 156          for (j = i; j < _num - 1; j++)
 
 157             _list[j] = _list[j + 1];
 
 164    assert (0);    // Couldn't find window
 
 169 void XsMDICanvas::removeAll ( )
 
 172 // Delete and reset the list
 
 183 void XsMDICanvas::show ( )
 
 185    assert (_drawArea != 0);
 
 187 // Place all of the child windows
 
 189    for (int loop = 0; loop < _num; loop++)
 
 190       _placeWindow (_list[loop]);
 
 192 // Manage the drawing area and canvas
 
 194    XtManageChild (_drawArea);
 
 198    XsComponent::show ( );
 
 203 const char* XsMDICanvas::className ( ) const
 
 205    return ("XsMDICanvas");
 
 208 // _componentDestroyed
 
 210 void XsMDICanvas::_componentDestroyed ( )
 
 213 // Remove the callbacks
 
 215    XtRemoveCallback (_drawArea, XmNresizeCallback, _canvasResizeCallback, (XtPointer)this);
 
 216    XtRemoveCallback (_clipWin, XmNresizeCallback, _clipResizeCallback, (XtPointer)this);
 
 224 void XsMDICanvas::_placeWindow (XsMDIWindow *win)
 
 228 // Compute window placement
 
 232    const int maxWin = 10;
 
 233    const Position offset = 20;
 
 234    const Position minOffset = 10;
 
 236    x = (_place * offset) + minOffset;
 
 237    y = (_place * offset) + minOffset;
 
 239    if (++_place == maxWin)
 
 242 // Set the window placement
 
 244    win->setPosition (x, y);
 
 253 void XsMDICanvas::_resize (XtPointer)
 
 255    Dimension   clipHeight;
 
 257    Dimension   canvasHeight;
 
 258    Dimension   canvasWidth;
 
 260 // Check if clip window and canvas are managed
 
 262    if (!XtIsManaged (_clipWin) || !XtIsManaged (_drawArea))
 
 265 // Get the clip window size
 
 267    XtVaGetValues (_clipWin, XmNwidth, &clipWidth, XmNheight, &clipHeight, NULL);
 
 269 // Get the canvas size
 
 271    XtVaGetValues (_drawArea, XmNwidth, &canvasWidth, XmNheight, &canvasHeight, NULL);
 
 273 // Force the canvas to be at least as big as the clip window
 
 275    if (canvasWidth < clipWidth)
 
 276       canvasWidth = clipWidth;
 
 277    if (canvasHeight < clipHeight)
 
 278       canvasHeight = clipHeight;
 
 280    XtVaSetValues (_drawArea, XmNwidth, canvasWidth, XmNheight, canvasHeight, NULL);
 
 283 // _clipResizeCallback
 
 285 void XsMDICanvas::_clipResizeCallback (Widget, XtPointer clientData, XtPointer callData)
 
 287    XsMDICanvas *obj = (XsMDICanvas*)clientData;
 
 288    obj->_resize (callData);
 
 291 // _canvasResizeCallback
 
 293 void XsMDICanvas::_canvasResizeCallback (Widget, XtPointer clientData, XtPointer callData)
 
 295    XsMDICanvas *obj = (XsMDICanvas*)clientData;
 
 296    obj->_resize (callData);