/ExtLibs/wxWidgets/src/motif/mdi/lib/XsMotifWindow.C
C | 2415 lines | 1465 code | 624 blank | 326 comment | 272 complexity | e84605fa5b510461a0ec1e84cef7bbf3 MD5 | raw file
- /*
- Copyright (C) 1996 Scott W. Sadler
- All rights reserved.
- */
- /*
- XsMotifWindow.C
- History
- 03-Mar-96 1.0; Scott W. Sadler (ssadler@cisco.com)
- Created
- */
- // Includes
- #include <assert.h>
- #include <Xm/Form.h>
- #include <Xm/RowColumn.h>
- #include <Xm/SeparatoG.h>
- #include <Xm/PushBG.h>
- #include <X11/Shell.h>
- #include <X11/cursorfont.h>
- #include "XsMotifWindow.h"
- #include "XsResizeOutline.h"
- #include "XsMoveOutline.h"
- #include "xs_motif_icon.xbm"
- // Constants
- const int BorderSize_ = 6;
- const int ButtonSize_ = 23;
- const int IconSize_ = 70;
- /*
- ----------------------------------------------------------------------------
- _XsMotifBase
- */
-
- // Constructor
- _XsMotifBase::_XsMotifBase (const char *name, XsMotifWindow *win) :
- XsComponent (name)
- {
- assert (win != 0);
-
- // Initialize
- _win = win;
- _topShadowGC = 0;
- _bottomShadowGC = 0;
- }
-
- // Destructor
- _XsMotifBase::~_XsMotifBase ( )
- {
- if (_topShadowGC)
- XtReleaseGC (_base, _topShadowGC);
- if (_bottomShadowGC)
- XtReleaseGC (_base, _bottomShadowGC);
- }
- // show
- void _XsMotifBase::show ( )
- {
- assert (_base != 0);
-
- // Install event handler
- XtAddEventHandler (_base, StructureNotifyMask, False, _mapEventHandler, (XtPointer)this);
- // Call the base-class
- XsComponent::show ( );
- }
-
- // className
- const char* _XsMotifBase::className ( ) const
- {
- return ("_XsMotifBase");
- }
- // _componentDestroyed ( )
- void _XsMotifBase::_componentDestroyed ( )
- {
- // Clean up the GCs
- if (_topShadowGC)
- XtReleaseGC (_base, _topShadowGC);
- if (_bottomShadowGC)
- XtReleaseGC (_base, _bottomShadowGC);
- _topShadowGC = 0;
- _bottomShadowGC = 0;
-
- // Call the base-class
- XsComponent::_componentDestroyed ( );
- }
- // _drawShadows
- void _XsMotifBase::_drawShadows (Position x, Position y, Dimension width,
- Dimension height, Dimension thick, Boolean reverse)
- {
- assert (_base != 0);
- assert (thick > 0);
-
- const int nsegs = 2;
- XSegment segs[nsegs];
- GC topShadowGC;
- GC bottomShadowGC;
-
- // Work out the graphics contexts
- topShadowGC = (reverse == False) ? _topShadowGC : _bottomShadowGC;
- bottomShadowGC = (reverse == False) ? _bottomShadowGC : _topShadowGC;
-
- for (int loop = 0; loop < thick; loop++)
- {
- /*
- TOP SHADOW DRAWING
- */
- // Across the top
- segs[0].x1 = x + loop;
- segs[0].y1 = y + loop;
- segs[0].x2 = x + width - loop - 2;
- segs[0].y2 = y + loop;
-
- // Down the left side
- segs[1].x1 = x + loop;
- segs[1].y1 = y + loop + 1;
- segs[1].x2 = x + loop;
- segs[1].y2 = y + height - loop - 2;
-
- XDrawSegments (XtDisplay (_base), XtWindow (_base), topShadowGC, segs, nsegs);
- /*
- BOTTOM SHADOW DRAWING
- */
-
- // Across the bottom
- segs[0].x1 = x + loop;
- segs[0].y1 = y + height - loop - 1;
- segs[0].x2 = x + width - loop - 1;
- segs[0].y2 = y + height - loop - 1;
-
- // Down the right side
- segs[1].x1 = x + width - loop - 1;
- segs[1].y1 = y + loop;
- segs[1].x2 = x + width - loop - 1;
- segs[1].y2 = y + height - loop - 1;
- XDrawSegments (XtDisplay (_base), XtWindow (_base), bottomShadowGC, segs, nsegs);
- }
- }
- // _drawLine
- void _XsMotifBase::_drawLine (Position x1, Position y1, Position x2, Position y2, GC &gc)
- {
- assert (_base != 0);
- XDrawLine (XtDisplay (_base), XtWindow (_base), gc, x1, y1, x2, y2);
- }
-
- // _map
- void _XsMotifBase::_map ( )
- {
- // Create the graphics contexts
- unsigned long valuemask;
- XGCValues values;
- Pixel topShadow;
- Pixel bottomShadow;
- XtVaGetValues (_win->base ( ), XmNtopShadowColor, &topShadow, XmNbottomShadowColor,
- &bottomShadow, NULL);
- // Create the graphics contexts
- valuemask = GCForeground | GCLineWidth | GCGraphicsExposures;
- values.line_width = 0;
- values.graphics_exposures = False;
-
- values.foreground = topShadow;
- _topShadowGC = XtGetGC (_base, valuemask, &values);
- values.foreground = bottomShadow;
- _bottomShadowGC = XtGetGC (_base, valuemask, &values);
- }
- // _mapEventHandler
- void _XsMotifBase::_mapEventHandler (Widget, XtPointer clientData, XEvent *event, Boolean*)
- {
- if (event->type == MapNotify)
- {
- _XsMotifBase *obj = (_XsMotifBase*)clientData;
- obj->_map ( );
- // Remove the event handler
- XtRemoveEventHandler (obj->_base, StructureNotifyMask, False, obj->_mapEventHandler, clientData);
- }
- }
- /*
- ----------------------------------------------------------------------------
- _XsMotifComponent
- */
-
- Cursor _XsMotifComponent::_cursors[_XsMotifComponent::NumCursors];
- int _XsMotifComponent::_mutex = 0;
- XtResource _XsMotifComponent::_resourceList[] = {
- {
- "borderSize",
- "BorderSize",
- XmRDimension,
- sizeof (Dimension),
- XtOffset (_XsMotifComponent*, _borderSize),
- XmRImmediate,
- (XtPointer)BorderSize_
- },
- {
- "buttonSize",
- "ButtonSize",
- XmRDimension,
- sizeof (Dimension),
- XtOffset (_XsMotifComponent*, _buttonSize),
- XmRImmediate,
- (XtPointer)ButtonSize_
- }
- };
- // Constructor
- _XsMotifComponent::_XsMotifComponent (const char *name, XsMotifWindow *win,
- Widget parent) : _XsMotifBase (name, win)
- {
-
- // Create cursors (if necessary)
- if (_mutex == 0)
- {
- Display *dpy = XtDisplay (win->base ( ));
- _cursors[TopCursor] = XCreateFontCursor (dpy, XC_top_side);
- _cursors[BottomCursor] = XCreateFontCursor (dpy, XC_bottom_side);
- _cursors[LeftCursor] = XCreateFontCursor (dpy, XC_left_side);
- _cursors[RightCursor] = XCreateFontCursor (dpy, XC_right_side);
- _cursors[TopLeftCursor] = XCreateFontCursor (dpy, XC_top_left_corner);
- _cursors[TopRightCursor] = XCreateFontCursor (dpy, XC_top_right_corner);
- _cursors[BottomLeftCursor] = XCreateFontCursor (dpy, XC_bottom_left_corner);
- _cursors[BottomRightCursor] = XCreateFontCursor (dpy, XC_bottom_right_corner);
- _mutex = 1;
- }
- // Create the component
- _base = XtVaCreateWidget (name, widgetClass, (parent != 0) ? parent : _win->base ( ), NULL);
- // Install destroy handler
- _installDestroyHandler ( );
-
- // Get resources
-
- _getResources (_resourceList, XtNumber (_resourceList));
- // Compute the corner size
- _cornerSize = _buttonSize + _borderSize;
- // Install event handlers
- XtAddEventHandler (_base, ExposureMask, False, _exposeEventHandler, (XtPointer)this);
- XtAddEventHandler (_base, ButtonPressMask | ButtonReleaseMask | Button1MotionMask | Button2MotionMask, False, _inputEventHandler, (XtPointer)this);
- }
- // Destructor
- _XsMotifComponent::~_XsMotifComponent ( )
- {
- // Empty
- }
- // className
- const char* _XsMotifComponent::className ( ) const
- {
- return ("_XsMotifComponent");
- }
- // _input
- void _XsMotifComponent::_input (XEvent*)
- {
- // Empty
- }
- // _exposeEventHandler
- void _XsMotifComponent::_exposeEventHandler (Widget, XtPointer clientData, XEvent *event, Boolean*)
- {
- _XsMotifComponent *obj = (_XsMotifComponent*)clientData;
- if (event->xexpose.count == 0)
- obj->_expose (event);
- }
- // _inputEventHandler
- void _XsMotifComponent::_inputEventHandler (Widget, XtPointer clientData, XEvent *event, Boolean*)
- {
- _XsMotifComponent *obj = (_XsMotifComponent*)clientData;
- obj->_input (event);
- }
- /*
- ----------------------------------------------------------------------------
- _XsMotifCorner
- */
- // Constructor
- _XsMotifCorner::_XsMotifCorner (const char *name, XsMotifWindow *win, Corner corner)
- : _XsMotifComponent (name, win)
- {
-
- // Initialize
- _corner = corner;
- // Configure component
- XtVaSetValues (_base, XmNwidth, _cornerSize, XmNheight, _cornerSize,
- XmNborderWidth, (Dimension)0, NULL);
- }
- // Destructor
- _XsMotifCorner::~_XsMotifCorner ( )
- {
- // Empty
- }
- // className
- const char *_XsMotifCorner::className ( ) const
- {
- return ("_XsMotifCorner");
- }
- // _expose
- void _XsMotifCorner::_expose (XEvent*)
- {
- Dimension w, h;
- if (_topShadowGC == 0) // JACS
- return;
- // Get the size of the corner
- XtVaGetValues (_base, XmNwidth, &w, XmNheight, &h, NULL);
-
- // Draw the shadow
- _drawShadows (0, 0, w, h, 1);
- // Draw the extra lines and relief
- switch (_corner)
- {
- case TopLeft:
- {
- _drawLine (1, 1, w - 2, 1, _topShadowGC);
- _drawLine (1, 1, 1, h - 2, _topShadowGC);
- // Relief
- _drawLine (_borderSize - 1, _borderSize - 1, _borderSize +
- _buttonSize - 2, _borderSize - 1, _bottomShadowGC);
- _drawLine (_borderSize - 1, _borderSize - 1, _borderSize - 1,
- _borderSize + _buttonSize - 2, _bottomShadowGC);
-
- break;
- }
- case TopRight:
- {
- _drawLine (1, 1, w - 2, 1, _topShadowGC);
- _drawLine (w - 2, 1, w - 2, h - 2, _bottomShadowGC);
- // Relief
- _drawLine (0, _borderSize - 1, _buttonSize - 1, _borderSize - 1,
- _bottomShadowGC);
- _drawLine (w - _borderSize, _borderSize - 1, w - _borderSize,
- _borderSize + _buttonSize - 2, _topShadowGC);
- break;
- }
- case BottomLeft:
- {
- _drawLine (1, 1, 1, h - 2, _topShadowGC);
- _drawLine (1, h - 2, w - 2, h - 2, _bottomShadowGC);
- // Relief
- _drawLine (_borderSize - 1, h - _borderSize, _borderSize +
- _buttonSize - 2, h - _borderSize, _topShadowGC);
- _drawLine (_borderSize - 1, 1, _borderSize - 1,
- _buttonSize - 1, _bottomShadowGC);
- break;
- }
- case BottomRight:
- {
- _drawLine (1, h - 2, w - 2, h - 2, _bottomShadowGC);
- _drawLine (w - 2, 1, w - 2, h - 2, _bottomShadowGC);
- // Relief
- _drawLine (1, h - _borderSize, _buttonSize, h - _borderSize,
- _topShadowGC);
- _drawLine (w - _borderSize, 1, w - _borderSize,
- _buttonSize - 1, _topShadowGC);
- break;
- }
- default:
- assert (0);
- }
- }
- // _input
- void _XsMotifCorner::_input (XEvent *event)
- {
- switch (event->type)
- {
- case ButtonPress:
- {
- if (event->xbutton.button == 2)
- {
- XsMoveOutline move (_win->base ( ));
- // Start the move
- if (move.go ( ) != False)
- {
- // Relocate the window
-
- _win->setPosition (move.x ( ), move.y ( ));
- }
- }
- else if (event->xbutton.button == 3)
- _win->popupMenu ( );
- break;
- }
- case ButtonRelease:
- {
- switch (event->xbutton.button)
- {
- case 1:
- case 2:
- {
- _win->raise ( ); // Raise the window
- break;
- }
- }
- break;
- }
- case MotionNotify:
- {
- // Figure kind of resize we are doing
- int dir;
-
- if (_corner == TopLeft)
- dir = XsResizeOutline::Up | XsResizeOutline::Left;
- else if (_corner == TopRight)
- dir = XsResizeOutline::Up | XsResizeOutline::Right;
- else if (_corner == BottomLeft)
- dir = XsResizeOutline::Down | XsResizeOutline::Left;
- else if (_corner == BottomRight)
- dir = XsResizeOutline::Down | XsResizeOutline::Right;
- else
- assert (0);
- XsResizeOutline resize (_win->base ( ), dir);
- resize.setMinSize (_win->minWidth ( ), _win->minHeight ( ));
-
- // Start the resize
- if (resize.go ( ) != False)
- {
- // Relocate the window
-
- _win->setPosition (resize.x ( ), resize.y ( ));
- _win->setSize (resize.width ( ), resize.height ( ));
- }
- break;
- }
- }
- }
- // _map
- void _XsMotifCorner::_map ( )
- {
- // Call the base-class
- _XsMotifComponent::_map ( );
- // Install the cursor
- if (_corner == TopLeft)
- XDefineCursor (XtDisplay (_base), XtWindow (_base), _cursors[TopLeftCursor]);
- else if (_corner == TopRight)
- XDefineCursor (XtDisplay (_base), XtWindow (_base), _cursors[TopRightCursor]);
- else if (_corner == BottomLeft)
- XDefineCursor (XtDisplay (_base), XtWindow (_base), _cursors[BottomLeftCursor]);
- else if (_corner == BottomRight)
- XDefineCursor (XtDisplay (_base), XtWindow (_base), _cursors[BottomRightCursor]);
- else
- assert (0);
- }
- /*
- ----------------------------------------------------------------------------
- _XsMotifSide
- */
- // Constructor
- _XsMotifSide::_XsMotifSide (const char *name, XsMotifWindow *win, Side side) :
- _XsMotifComponent (name, win)
- {
-
- // Initialize
- _side = side;
- _lastW = _lastH = -1;
- // Configure component
- switch (_side)
- {
- case Top:
- case Bottom:
- {
- XtVaSetValues (_base, XmNheight, _borderSize, XmNborderWidth,
- (Dimension)0, NULL);
- break;
- }
- case Left:
- case Right:
- {
- XtVaSetValues (_base, XmNwidth, _borderSize, XmNborderWidth,
- (Dimension)0, NULL);
- break;
- }
- default:
- assert (0);
- }
- // Install event handler
- XtAddEventHandler (_base, StructureNotifyMask, False, _configureEventHandler, (XtPointer)this);
- }
- // Destructor
- _XsMotifSide::~_XsMotifSide ( )
- {
- // Empty
- }
- // className
- const char *_XsMotifSide::className ( ) const
- {
- return ("_XsMotifSide");
- }
- // _expose
- void _XsMotifSide::_expose (XEvent *event)
- {
- if (_topShadowGC == 0) // JACS
- return;
- // Clear out the window first
- if (event != 0)
- XClearWindow (XtDisplay (_base), XtWindow (_base));
-
- Dimension w, h;
- // Get the size of the side
- XtVaGetValues (_base, XmNwidth, &w, XmNheight, &h, NULL);
-
- // Draw the shadow
- _drawShadows (0, 0, w, h, 1);
- // Draw the extra lines
- switch (_side)
- {
- case Top:
- {
- _drawLine (1, 1, w - 2, 1, _topShadowGC);
- break;
- }
- case Bottom:
- {
- _drawLine (1, h - 2, w - 2, h - 2, _bottomShadowGC);
- break;
- }
- case Left:
- {
- _drawLine (1, 1, 1, h - 2, _topShadowGC);
- break;
- }
- case Right:
- {
- _drawLine (w - 2, 1, w - 2, h - 2, _bottomShadowGC);
- break;
- }
- default:
- assert (0);
- }
- }
-
- // _input
- void _XsMotifSide::_input (XEvent *event)
- {
- switch (event->type)
- {
- case ButtonPress:
- {
- if (event->xbutton.button == 2)
- {
- XsMoveOutline move (_win->base ( ));
- // Start the move
- if (move.go ( ) != False)
- {
- // Relocate the window
-
- _win->setPosition (move.x ( ), move.y ( ));
- }
- }
- else if (event->xbutton.button == 3)
- _win->popupMenu ( );
- break;
- }
- case ButtonRelease:
- {
- switch (event->xbutton.button)
- {
- case 1:
- case 2:
- {
- _win->raise ( ); // Raise the window
- break;
- }
- }
- break;
- }
- case MotionNotify:
- {
- // Figure kind of resize we are doing
- int dir;
-
- if (_side == Top)
- dir = XsResizeOutline::Up;
- else if (_side == Bottom)
- dir = XsResizeOutline::Down;
- else if (_side == Left)
- dir = XsResizeOutline::Left;
- else if (_side == Right)
- dir = XsResizeOutline::Right;
- else
- assert (0);
- XsResizeOutline resize (_win->base ( ), dir);
- resize.setMinSize (_win->minWidth ( ), _win->minHeight ( ));
- // Start the resize
- if (resize.go ( ) != False)
- {
- // Relocate the window
-
- _win->setPosition (resize.x ( ), resize.y ( ));
- _win->setSize (resize.width ( ), resize.height ( ));
- }
- break;
- }
- }
- }
- // _map
- void _XsMotifSide::_map ( )
- {
- // Call the base-class
- _XsMotifComponent::_map ( );
- // Install the cursor
- if (_side == Top)
- XDefineCursor (XtDisplay (_base), XtWindow (_base), _cursors[TopCursor]);
- else if (_side == Bottom)
- XDefineCursor (XtDisplay (_base), XtWindow (_base), _cursors[BottomCursor]);
- else if (_side == Left)
- XDefineCursor (XtDisplay (_base), XtWindow (_base), _cursors[LeftCursor]);
- else if (_side == Right)
- XDefineCursor (XtDisplay (_base), XtWindow (_base), _cursors[RightCursor]);
- else
- assert (0);
- }
- // _configure
- void _XsMotifSide::_configure (XEvent *event)
- {
- XConfigureEvent *ce = (XConfigureEvent*)event;
-
- /*
- Check if window has been resized. If so, generate an expose event
- to redraw its contents.
- */
- if ((_lastW != ce->width) || (_lastH != ce->height))
- {
- if ((_base != 0) && XtIsManaged (_base))
- XClearArea (XtDisplay (_base), XtWindow (_base), 0, 0, 0, 0, True);
- _lastW = ce->width;
- _lastH = ce->height;
- }
- }
- // _configureEventHandler
- void _XsMotifSide::_configureEventHandler (Widget, XtPointer clientData, XEvent *event, Boolean*)
- {
- if (event->type == ConfigureNotify)
- {
- _XsMotifSide *obj = (_XsMotifSide*)clientData;
- obj->_configure (event);
- }
- }
- /*
- ----------------------------------------------------------------------------
- _XsMotifButton
- */
- // Constructor
- _XsMotifButton::_XsMotifButton (const char *name, XsMotifWindow *win, Button button) :
- _XsMotifComponent (name, win)
- {
-
- // Initialize
- _pressed = False;
- _button = button;
- // Configure the component
- XtVaSetValues (_base, XmNheight, _buttonSize, XmNwidth, _buttonSize,
- XmNborderWidth, (Dimension)0, NULL);
- }
- // Destructor
- _XsMotifButton::~_XsMotifButton ( )
- {
- // Empty
- }
- // redraw
- void _XsMotifButton::redraw ( )
- {
- // Make sure component is viewable
- if (!XtIsRealized (_base))
- return;
-
- // Check if window is viewable
- XWindowAttributes attrs;
- XGetWindowAttributes (XtDisplay (_base), XtWindow (_base), &attrs);
-
- if (attrs.map_state == IsViewable)
- _expose (0); // Just pretend we got an expose event
- }
-
- // className
- const char *_XsMotifButton::className ( ) const
- {
- return ("_XsMotifButton");
- }
- // _expose
- void _XsMotifButton::_expose (XEvent *event)
- {
- if (_topShadowGC == 0) // JACS
- return;
- Dimension w, h;
- // Get the size of the button
- XtVaGetValues (_base, XmNwidth, &w, XmNheight, &h, NULL);
-
- // Draw the shadow
- _drawShadows (0, 0, w, h, 1, _pressed);
- // Draw the extra line
- _drawLine (1, h - 2, w - 2, h - 2, (_pressed) ? _topShadowGC : _bottomShadowGC);
- // Check if we need to draw the decal
- if ((_button != Maximize) && (event == 0))
- return;
-
- // Compute the decal size
- Dimension dw, dh;
- Boolean reverse = False;
-
- switch (_button)
- {
- case Menu:
- {
- dw = _buttonSize - 6;
- dh = 4;
- break;
- }
- case Minimize:
- {
- dw = dh = 4;
- break;
- }
- case Maximize:
- {
- dw = _buttonSize - 6;
- dh = dw - 1;
- if (_win->maximized ( ))
- reverse = True;
-
- break;
- }
- default:
- assert (0);
- }
- // Draw the decal
- _drawShadows ((w / 2) - (dw / 2), (h / 2) - (dh / 2), dw, dh, 1, reverse);
- }
- // _input
- void _XsMotifButton::_input (XEvent *event)
- {
- static Time lastTime = (Time)0;
-
- switch (event->type)
- {
- case ButtonPress:
- {
- if (event->xbutton.button == 1)
- {
- _pressed = True;
-
- if (_button == Menu)
- {
- // Get double-click time
- int multiClick = XtGetMultiClickTime (XtDisplay (_base));
- // Check for double-click
- if ((event->xbutton.time - lastTime) <= multiClick)
- {
- _win->close ( );
- return;
- }
- else
- lastTime = event->xbutton.time;
- // Redraw the button (pushed-in)
- redraw ( );
- // Popup the menu
- _win->popupMenu (False);
- // The menu will consume the ButtonRelease, so fake one
- _pressed = False;
- redraw ( );
- }
- else if ((_button == Minimize) || (_button == Maximize))
- {
- redraw ( );
- }
- }
- else if (event->xbutton.button == 2)
- {
- XsMoveOutline move (_win->base ( ));
- // Start the move
- if (move.go ( ) != False)
- {
- // Relocate the window
-
- _win->setPosition (move.x ( ), move.y ( ));
- }
- }
- else if (event->xbutton.button == 3)
- _win->popupMenu ( );
- break;
- }
- case ButtonRelease:
- {
- if (event->xbutton.button == 1)
- {
- _pressed = False;
- // Check if pointer is really in the window
- XButtonEvent *b = &event->xbutton;
- Dimension width, height;
- Boolean inWindow = False;
- XtVaGetValues (_base, XmNwidth, &width, XmNheight, &height, NULL);
- if ((b->x >= 0) && (b->y >= 0) && (b->x < width) && (b->y < height))
- inWindow = True;
- if (_button == Minimize)
- {
- if (inWindow)
- {
- if (_win->minimized ( ))
- _win->restore ( );
- else
- _win->minimize ( );
- }
- else
- redraw ( );
- }
- else if (_button == Maximize)
- {
- if (inWindow)
- {
- if (_win->maximized ( ))
- _win->restore ( );
- else
- _win->maximize ( );
- }
- else
- redraw ( );
- }
- }
- break;
- }
- }
- }
- // _map
- void _XsMotifButton::_map ( )
- {
-
- // Call the base-class
-
- _XsMotifComponent::_map ( );
-
- // Raise ourself
- XRaiseWindow (XtDisplay (_base), XtWindow (_base));
- }
-
- /*
- ----------------------------------------------------------------------------
- _XsMotifTitle
- */
- XtResource _XsMotifTitle::_resourceList[] = {
- {
- "title",
- "Title",
- XmRString,
- sizeof (String),
- XtOffset (_XsMotifTitle*, _titleString),
- XmRImmediate,
- NULL
- },
- {
- "titleFont",
- "TitleFont",
- XmRFontStruct,
- sizeof (XFontStruct*),
- XtOffset (_XsMotifTitle*, _titleFont),
- XmRString,
- "-*-helvetica-bold-o-normal-*-14-*-*-*-*-*-iso8859-1"
- }
- };
- // Constructor
- _XsMotifTitle::_XsMotifTitle (const char *name, XsMotifWindow *win) :
- _XsMotifComponent (name, win)
- {
-
- // Initialize
- _pressed = False;
- _titleString = 0;
- _titleFont = 0;
- _fontGC = 0;
- _lastW = _lastH = -1;
-
- // Get resources
-
- _getResources (_resourceList, XtNumber (_resourceList));
- // Copy title string to local memory
- if (_titleString != 0)
- {
- char *tmp = new char[strlen (_titleString) + 1];
- strcpy (tmp, _titleString);
- _titleString = tmp;
- }
-
- // Configure the title
- XtVaSetValues (_base, XmNheight, _buttonSize, XmNborderWidth,
- (Dimension)0, NULL);
- // Install event handler
- XtAddEventHandler (_base, StructureNotifyMask, False, _configureEventHandler, (XtPointer)this);
- }
- // Destructor
- _XsMotifTitle::~_XsMotifTitle ( )
- {
- if (_fontGC)
- XtReleaseGC (_base, _fontGC);
- delete [] _titleString;
- }
- // setTitle
- void _XsMotifTitle::setTitle (const char *title)
- {
- assert (title != 0);
-
- delete [] _titleString;
-
- _titleString = new char[strlen (title) + 1];
- strcpy (_titleString, title);
- }
- // className
- const char *_XsMotifTitle::className ( ) const
- {
- return ("_XsMotifTitle");
- }
- // _componentDestroyed
- void _XsMotifTitle::_componentDestroyed ( )
- {
-
- // Clean up the GCs
- if (_fontGC)
- XtReleaseGC (_base, _fontGC);
- _fontGC = 0;
-
- // Call base-class
- _XsMotifComponent::_componentDestroyed ( );
- }
-
- // _redraw
- void _XsMotifTitle::_redraw ( )
- {
- _expose (0); // Just pretend we got an expose event
- }
- // _expose
- void _XsMotifTitle::_expose (XEvent *event)
- {
- if (_topShadowGC == 0) // JACS
- return;
- // Clear out the window first
- if (event != 0)
- XClearWindow (XtDisplay (_base), XtWindow (_base));
-
- Dimension w, h;
- // Get the size of the button
- XtVaGetValues (_base, XmNwidth, &w, XmNheight, &h, NULL);
-
- // Draw the shadow
- _drawShadows (0, 0, w, h, 1, _pressed);
- // Draw the extra line
- _drawLine (1, h - 2, w - 2, h - 2, (_pressed) ? _topShadowGC : _bottomShadowGC);
- // If this is an artificial event, no need continuing
- if (event == 0)
- return;
-
- // Draw the text string
- const int LeftOffset = 5;
- const int TopOffset = 2;
- // Figure out the title
- const char *title = (_titleString != 0) ? _titleString : _win->name ( );
-
- if ((title != 0) && (title[0] != '\0'))
- {
- int len = strlen (title);
- XDrawString (XtDisplay (_base), XtWindow (_base), _fontGC,
- LeftOffset, TopOffset + _titleFont->ascent, title, len);
- }
- }
- // _input
- void _XsMotifTitle::_input (XEvent *event)
- {
- switch (event->type)
- {
- case ButtonPress:
- {
- switch (event->xbutton.button)
- {
- case 1:
- {
- _pressed = True;
- _redraw ( );
- break;
- }
- case 2:
- {
- XsMoveOutline move (_win->base ( ));
- // Start the move
- if (move.go ( ) != False)
- {
- // Relocate the window
-
- _win->setPosition (move.x ( ), move.y ( ));
- }
- break;
- }
- case 3:
- {
- _win->popupMenu ( );
- break;
- }
- }
- break;
- }
- case ButtonRelease:
- {
- switch (event->xbutton.button)
- {
- case 1:
- case 2:
- {
- _pressed = False;
- _redraw ( );
- _win->raise ( );
- break;
- }
- }
- break;
- }
- case MotionNotify:
- {
- XsMoveOutline move (_win->base ( ));
- // Start the move
- if (move.go ( ) != False)
- {
- // Relocate the window
-
- _win->setPosition (move.x ( ), move.y ( ));
- // Redraw the title bar
- _pressed = False;
- _redraw ( );
- }
- break;
- }
- }
- }
- // _map
- void _XsMotifTitle::_map ( )
- {
-
- // Call the base-class
- _XsMotifComponent::_map ( );
- // Raise ourself
-
- XRaiseWindow (XtDisplay (_base), XtWindow (_base));
-
- unsigned long valuemask;
- XGCValues values;
- Pixel foreground;
- Pixel background;
- // Get the pixels
- XtVaGetValues (_win->base ( ), XmNforeground, &foreground, XmNbackground, &background, NULL);
- // Create the font graphics context
- valuemask = GCForeground | GCBackground | GCGraphicsExposures | GCFont;
- values.foreground = foreground;
- values.background = background;
- values.font = _titleFont->fid;
- values.graphics_exposures = False;
- _fontGC = XtGetGC (_base, valuemask, &values);
- }
- // _configure
- void _XsMotifTitle::_configure (XEvent *event)
- {
- XConfigureEvent *ce = (XConfigureEvent*)event;
-
- /*
- Check if window has been resized. If so, generate an expose event
- to redraw its contents.
- */
- if ((_lastW != ce->width) || (_lastH != ce->height))
- {
- if ((_base != 0) && XtIsManaged (_base))
- XClearArea (XtDisplay (_base), XtWindow (_base), 0, 0, 0, 0, True);
- _lastW = ce->width;
- _lastH = ce->height;
- }
- }
- // _configureEventHandler
- void _XsMotifTitle::_configureEventHandler (Widget, XtPointer clientData, XEvent *event, Boolean*)
- {
- if (event->type == ConfigureNotify)
- {
- _XsMotifTitle *obj = (_XsMotifTitle*)clientData;
- obj->_configure (event);
- }
- }
- /*
- ----------------------------------------------------------------------------
- _XsMotifIcon
- */
- XtResource _XsMotifIcon::_resourceList[] = {
- {
- "iconSize",
- "IconSize",
- XmRDimension,
- sizeof (Dimension),
- XtOffset (_XsMotifIcon*, _iconSize),
- XmRImmediate,
- (XtPointer)IconSize_
- },
- {
- "iconName",
- "IconName",
- XmRString,
- sizeof (String),
- XtOffset (_XsMotifIcon*, _iconName),
- XmRImmediate,
- NULL
- },
- {
- "iconFont",
- "IconFont",
- XmRFontStruct,
- sizeof (XFontStruct*),
- XtOffset (_XsMotifIcon*, _iconFont),
- XmRString,
- "-*-helvetica-bold-r-normal-*-12-*-*-*-*-*-iso8859-1"
- },
- {
- XmNiconX,
- XmCIconX,
- XmRPosition,
- sizeof (Position),
- XtOffset (_XsMotifIcon*, _iconX),
- XmRImmediate,
- (XtPointer)-1
- },
- {
- XmNiconY,
- XmCIconY,
- XmRPosition,
- sizeof (Position),
- XtOffset (_XsMotifIcon*, _iconY),
- XmRImmediate,
- (XtPointer)-1
- }
- };
- // Constructor
- _XsMotifIcon::_XsMotifIcon (const char *name, XsMotifWindow *win, Widget parent) :
- _XsMotifComponent (name, win, parent)
- {
-
- // Initialize
- _pixmapGC = 0;
- _fontGC = 0;
- _iconName = 0;
- _pixmap = 0;
- _freePixmap = False;
-
- _width = _height = 0;
- _placed = 0;
-
- // Get resources
-
- _getResources (_resourceList, XtNumber (_resourceList));
- // Copy icon name to local memory
- if (_iconName != 0)
- {
- char *tmp = new char[strlen (_iconName) + 1];
- strcpy (tmp, _iconName);
- _iconName = tmp;
- }
- // Configure the icon
- XtVaSetValues (_base, XmNwidth, _iconSize, XmNheight, _iconSize, NULL);
- }
- // Destructor
- _XsMotifIcon::~_XsMotifIcon ( )
- {
- if (_fontGC)
- XtReleaseGC (_base, _fontGC);
-
- if (_pixmapGC)
- XtReleaseGC (_base, _pixmapGC);
-
- if (_freePixmap)
- XFreePixmap (XtDisplay (_base), _pixmap);
- delete [] _iconName;
- }
- // show
- void _XsMotifIcon::show ( )
- {
- /*
- Configure the icon position. Either use the position specified
- in the resource, or place the icon at the top-left corner of the
- window.
- */
- if (_placed == False)
- {
- Position x, y;
-
- if (_iconX == -1)
- {
- XtVaGetValues (_win->base ( ), XmNx, &x, NULL);
- if (x < 0) x = 0;
- _iconX = x;
- }
- else
- x = _iconX;
-
- if (_iconY == -1)
- {
- XtVaGetValues (_win->base ( ), XmNy, &y, NULL);
- if (y < 0) y = 0;
- _iconY = y;
- }
- else
- y = _iconY;
-
- XtVaSetValues (_base, XmNx, x, XmNy, y, NULL);
- _placed = True;
- }
-
- // Call the base class
- _XsMotifComponent::show ( );
- }
- // setIconName
- void _XsMotifIcon::setIconName (const char *iconName)
- {
- assert (iconName != 0);
- delete [] _iconName;
-
- _iconName = new char[strlen (iconName) + 1];
- strcpy (_iconName, iconName);
- }
- // setPixmap
- void _XsMotifIcon::setPixmap (Pixmap pixmap)
- {
- assert (pixmap != 0);
-
- // Free the existing pixmap (if necessary)
- if (_freePixmap)
- {
- XFreePixmap (XtDisplay (_base), _pixmap);
- _freePixmap = False;
- }
-
- // Save the new pixmap
- _pixmap = pixmap;
- // Get the pixmap width and height
- Window dummy;
- int xd, yd;
- unsigned int uw, uh, ub, ud;
-
- XGetGeometry (XtDisplay (_base), _pixmap, &dummy, &xd, &yd, &uw, &uh, &ub, &ud);
- _width = uw;
- _height = uh;
- }
-
- // className
- const char *_XsMotifIcon::className ( ) const
- {
- return ("_XsMotifIcon");
- }
- // _componentDestroyed
- void _XsMotifIcon::_componentDestroyed ( )
- {
-
- // Clear up the GCs
- if (_fontGC)
- XtReleaseGC (_base, _fontGC);
- if (_pixmapGC)
- XtReleaseGC (_base, _pixmapGC);
- if (_freePixmap)
- XFreePixmap (XtDisplay (_base), _pixmap);
- _fontGC = 0;
- _pixmapGC = 0;
- _freePixmap = 0;
-
- // Call the base-class
- _XsMotifComponent::_componentDestroyed ( );
- }
-
- // _input
- void _XsMotifIcon::_input (XEvent *event)
- {
- static Time lastTime = (Time)0;
-
- switch (event->type)
- {
- case ButtonPress:
- {
- switch (event->xbutton.button)
- {
- case 1:
- break;
- case 2:
- {
- XsMoveOutline move (_base);
- // Start the move
- if (move.go ( ) != False)
- {
- // Relocate the window
-
- _win->setPosition (move.x ( ), move.y ( ));
- }
- break;
- }
- case 3:
- {
- _win->popupMenu ( );
- break;
- }
- }
- break;
- }
- case ButtonRelease:
- {
- switch (event->xbutton.button)
- {
- case 1:
- {
- // Get double-click time
- int multiClick = XtGetMultiClickTime (XtDisplay (_base));
- // Check for double-click
- if ((event->xbutton.time - lastTime) <= multiClick)
- _win->restore ( );
- else
- {
- lastTime = event->xbutton.time;
- _win->raise ( );
- }
- break;
- }
- }
- break;
- }
- case MotionNotify:
- {
- XsMoveOutline move (_base);
- // Start the move
- if (move.go ( ) != False)
- {
- // Relocate the icon
-
- _win->setPosition (move.x ( ), move.y ( ));
- }
- break;
- }
- }
- }
- // _expose
- void _XsMotifIcon::_expose (XEvent *)
- {
- if (_topShadowGC == 0) // JACS
- return;
- Dimension iconHeight;
- Dimension iconWidth;
- // Compute icon size
- XtVaGetValues (_base, XmNwidth, &iconWidth, XmNheight, &iconHeight, NULL);
-
- // Draw the shadow
- _drawShadows (0, 0, iconWidth, iconHeight, 2);
- // Figure out the icon string
- const char *iconName = (_iconName != 0) ? _iconName : (_win->title ( ) != 0) ?
- _win->title ( ) : _win->name ( );
-
- const int fontX = 3;
- const int fontY = 3;
-
- if ((iconName != 0) && (iconName[0] != '\0'))
- {
- int textWidth;
- int len = strlen (iconName);
-
- // Compute the text size
- textWidth = XTextWidth (_iconFont, iconName, len);
- // Center the text in the bottom of the icon (or left-justify it)
-
- int x, y;
- if (textWidth <= (iconWidth - (fontX * 2)))
- x = (iconWidth - (int)textWidth) / 2;
- else
- x = fontX;
-
- y = (int)iconHeight - _iconFont->descent - fontY;
- // Draw the string
- XDrawString (XtDisplay (_base), XtWindow (_base), _fontGC,
- x, y, iconName, len);
- }
- // Compute label size
- int labelHeight = _iconFont->descent + _iconFont->ascent + (fontY * 2);
-
- if (labelHeight >= (iconHeight - 6))
- return;
-
- // Draw the separator
- int sepY = (iconHeight) - labelHeight;
- _drawLine (1, sepY, iconWidth - 2, sepY, _bottomShadowGC);
- _drawLine (1, sepY + 1, iconWidth - 2, sepY + 1, _topShadowGC);
- // Draw the pixmap frame
- const int frameX = 4;
- const int frameY = 4;
-
- if ((frameX + 6) >= sepY)
- return;
-
- int frameWidth = iconWidth - (frameX * 2);
- int frameHeight = sepY - frameY - 2;
-
- _drawShadows (frameX, frameY, frameWidth, frameHeight, 1, True);
- frameWidth -= 2;
- frameHeight -= 2;
-
- _drawShadows (frameX + 1, frameY + 1, frameWidth, frameHeight, 1);
-
- frameWidth -= 2;
- frameHeight -= 2;
- // Blit the pixmap
- if (_pixmap != 0)
- {
- if ((frameWidth > 0) && (frameHeight > 0))
- {
- int origX, origY;
- int drawW, drawH;
-
- // Center the pixmap or top-left orient it
- if (frameWidth > _width)
- {
- origX = (frameWidth - _width) / 2;
- origX += frameX + 2;
- drawW = _width;
- }
- else
- {
- origX = frameX + 2;
- drawW = frameWidth;
- }
-
- if (frameHeight > _height)
- {
- origY = (frameHeight - _height) / 2;
- origY += frameY + 2;
- drawH = _height;
- }
- else
- {
- origY = frameY + 2;
- drawH = frameHeight;
- }
-
- XCopyArea (XtDisplay (_base), _pixmap, XtWindow (_base), _pixmapGC,
- 0, 0, drawW, drawH, origX, origY);
- }
- }
- }
-
- // _map
- void _XsMotifIcon::_map ( )
- {
- unsigned long valuemask;
- XGCValues values;
- Pixel fg;
- Pixel bg;
- int depth;
-
- // Call the base-class
-
- _XsMotifComponent::_map ( );
-
- // Get the icon pixels
- XtVaGetValues (_win->base ( ), XmNdepth, &depth, XmNbackground, &bg,
- XmNforeground, &fg, NULL);
-
- // Create the default icon pixmap
- if (_pixmap == 0)
- {
- _pixmap = XCreatePixmapFromBitmapData (XtDisplay (_base), XtWindow (_base),
- xs_motif_icon_bits, xs_motif_icon_width, xs_motif_icon_height,
- fg, bg, depth);
- // Set this pixmap
- setPixmap (_pixmap);
-
- _freePixmap = True;
-
- // Create the icon pixmap graphics context
- valuemask = GCGraphicsExposures | GCForeground | GCBackground;
-
- values.graphics_exposures = False;
- values.foreground = fg;
- values.background = bg;
- _pixmapGC = XtGetGC (_base, valuemask, &values);
- }
- // Create the font graphics context
- valuemask = GCForeground | GCBackground | GCGraphicsExposures | GCFont;
- values.foreground = fg;
- values.background = bg;
- values.font = _iconFont->fid;
- values.graphics_exposures = False;
- _fontGC = XtGetGC (_base, valuemask, &values);
- }
-
- /*
- ----------------------------------------------------------------------------
- _XsMotifMenu
- */
- // Static definitions
- int _XsMotifMenu::_count = 0;
- Cursor _XsMotifMenu::_cursor = None;
- Pixmap _XsMotifMenu::_stipple = None;
- Display *_XsMotifMenu::_dpy = 0;
- // Resources
- XtResource _XsMotifMenu::_resourceList[] = {
- {
- "saveUnder",
- "SaveUnder",
- XmRBoolean,
- sizeof (Boolean),
- XtOffset (_XsMotifMenu*, _saveUnder),
- XmRImmediate,
- (XtPointer)True
- },
- {
- "restoreString",
- "RestoreString",
- XmRString,
- sizeof (String),
- XtOffset (_XsMotifMenu*, _strings[Restore]),
- XmRString,
- "Restore"
- },
- {
- "moveString",
- "MoveString",
- XmRString,
- sizeof (String),
- XtOffset (_XsMotifMenu*, _strings[Move]),
- XmRString,
- "Move"
- },
- {
- "sizeString",
- "SizeString",
- XmRString,
- sizeof (String),
- XtOffset (_XsMotifMenu*, _strings[Size]),
- XmRString,
- "Size"
- },
- {
- "minimizeString",
- "MinimizeString",
- XmRString,
- sizeof (String),
- XtOffset (_XsMotifMenu*, _strings[Minimize]),
- XmRString,
- "Minimize"
- },
- {
- "maximizeString",
- "MaximizeString",
- XmRString,
- sizeof (String),
- XtOffset (_XsMotifMenu*, _strings[Maximize]),
- XmRString,
- "Maximize"
- },
- {
- "raiseString",
- "RaiseString",
- XmRString,
- sizeof (String),
- XtOffset (_XsMotifMenu*, _strings[Raise]),
- XmRString,
- "Raise"
- },
- {
- "lowerString",
- "LowerString",
- XmRString,
- sizeof (String),
- XtOffset (_XsMotifMenu*, _strings[Lower]),
- XmRString,
- "Lower"
- },
- {
- "closeString",
- "CloseString",
- XmRString,
- sizeof (String),
- XtOffset (_XsMotifMenu*, _strings[Close]),
- XmRString,
- "Close"
- },
- {
- "menuFont",
- "menuFont",
- XmRFontStruct,
- sizeof (XFontStruct*),
- XtOffset (_XsMotifMenu*, _menuFont),
- XmRString,
- "-*-helvetica-bold-o-normal-*-14-*-*-*-*-*-iso8859-1"
- }
- };
- // Constructor
- _XsMotifMenu::_XsMotifMenu (const char *name, XsMotifWindow *win) :
- _XsMotifBase (name, win)
- {
- // Create the cursor (if necessary)
- if (_count++ == 0)
- {
- // Create the menu cursor
- _cursor = XCreateFontCursor (XtDisplay (win->base ( )), XC_arrow);
- // Create a stippled pixmap
- Widget parent = _win->base ( );
- Pixel foreground;
- Pixel background;
- int depth;
-
- XtVaGetValues (parent, XmNforeground, &foreground, XmNbackground,
- &background, XmNdepth, &depth, NULL);
-
- const int pixmapWidth = 2;
- const int pixmapHeight = 2;
- static unsigned char pixmapBits[] = { 0x02, 0x01 };
- _dpy = XtDisplay (parent);
- _stipple = XCreatePixmapFromBitmapData (_dpy, DefaultRootWindow (_dpy),
- (char*)pixmapBits, pixmapWidth, pixmapHeight, foreground, background,
- depth);
- }
- // Initialize
- _fontGC = 0;
- _grayGC = 0;
- _backgroundGC = 0;
-
- // Create the component (why doesn't overrideShell work?)
- _base = XtVaCreatePopupShell (_name, topLevelShellWidgetClass,
- XtParent (_win->base ( )), XmNoverrideRedirect, True,
- XmNborderWidth, 1, NULL);
- // Install destroy handler
- _installDestroyHandler ( );
-
- // Install event handler ('cause we never call _XsMotifBase::show)
- XtAddEventHandler (_base, StructureNotifyMask, False, _mapEventHandler, (XtPointer)this);
- // Get resources
-
- _getResources (_resourceList, XtNumber (_resourceList));
- // Get the background color
- Pixel bg;
- XtVaGetValues (_win->base ( ), XmNbackground, &bg, NULL);
-
- // Compute the size of the (largest) menu item
- int textHeight = _menuFont->ascent + _menuFont->descent;
- int textWidth = 0;
- int tmp;
-
- for (int loop = 0; loop < Num; loop++)
- {
- tmp = XTextWidth (_menuFont, _strings[loop], strlen (_strings[loop]));
- if (tmp > textWidth)
- textWidth = tmp;
- }
-
- // Put a border around the buttons
- textWidth += (2 * HorizTextOffset);
- textHeight += (2 * VertTextOffset);
-
- /*
- The menu height is the menu-shadow (1 pixel on top and bottom) + the
- items themselves.
- */
- int menuHeight = (2 * ShadowThickness) + // Top and bottom shadow
- (textHeight * Num); // The menu items
-
- /*
- The menu width is the menu-shadow (1 pixel on the left and right) +
- the largest menu text (calculated above)
- */
- int menuWidth = (2 * ShadowThickness) + // Left and right shadow
- textWidth; // Largest text item
- // Configure the popup
-
- XtVaSetValues (_base, XmNsaveUnder, _saveUnder, XmNwidth, menuWidth,
- XmNheight, menuHeight, NULL);
- }
- // Destructor
- _XsMotifMenu::~_XsMotifMenu ( )
- {
- if (_fontGC)
- XtReleaseGC (_base, _fontGC);
- if (_grayGC)
- XtReleaseGC (_base, _grayGC);
-
- if (_backgroundGC)
- XtReleaseGC (_base, _backgroundGC);
- // Free the pixmap (if necessary)
- if (--_count == 0)
- XFreePixmap (_dpy, _stipple);
- }
- // popup
- void _XsMotifMenu::popup (Boolean atPointer)
- {
- assert (_base != 0);
-
- Position x, y;
- // Compute the location of the menu.
- if (atPointer)
- {
- unsigned int mask;
- Window win;
- int winX, winY;
- int rootX, rootY;
-
- // Menu at pointer location
- XQueryPointer (XtDisplay (_base), XtWindow (XtParent (_base)),
- &win, &win, &rootX, &rootY, &winX, &winY, &mask);
-
- x = (Position)rootX;
- y = (Position)rootY;
- }
- else
- {
-
- // Menu at top-left corner of client area
- XtTranslateCoords (_win->clientArea ( ), 0, 0, &x, &y);
- }
- // Move the menu
- XtVaSetValues (_base, XmNx, x, XmNy, y, NULL);
-
- // Initialize the item
- _curItem = NoItem;
-
- // Pop it up
- XtPopup (_base, XtGrabNone);
-
- // Grab the pointer
- if (_grabPointer ( ) == FALSE)
- return;
-
- // Update the menu
- _processEvents ( );
-
- // Pop the menu down
- XtPopdown (_base);
- // Ungrab the pointer
- _ungrabPointer ( );
- if (_curItem != NoItem)
- {
-
- /*
- Post a work-proc to process this item. This will allow everything
- to get caught up before we process the menu item
- */
- XtAppContext appContext = XtWidgetToApplicationContext (_base);
- XtAppAddWorkProc (appContext, _workProc, (XtPointer)this);
- }
- }
- // className
- const char *_XsMotifMenu::className ( ) const
- {
- return ("_XsMotifMenu");
- }
- // _componentDestroyed
- void _XsMotifMenu::_componentDestroyed ( )
- {
- // Clean up the GCs
- if (_fontGC)
- XtReleaseGC (_base, _fontGC);
- if (_grayGC)
- XtReleaseGC (_base, _grayGC);
-
- if (_backgroundGC)
- XtReleaseGC (_base, _backgroundGC);
- _fontGC = 0;
- _grayGC = 0;
- _backgroundGC = 0;
-
- // Call the base-class
- _XsMotifBase::_componentDestroyed ( );
- }
-
- // _processEvents
- void _XsMotifMenu::_processEvents ( )
- {
- assert (_base != 0);
-
- XtAppContext appContext = XtWidgetToApplicationContext (_base);
- XEvent event;
- Display *dpy = XtDisplay (_base);
- int done = 0;
-
- while (!done)
- {
- XtAppNextEvent (appContext, &event);
- // Process this event
- switch (event.type)
- {
- case ButtonRelease:
- {
- done = 1;
- break;
- }
- case Expose:
- {
- _redrawMenu ( );
- break;
- }
- case MotionNotify:
- {
- XEvent next;
- // Process only the last motion event
- while (XPending (dpy) > 0)
- {
- XPeekEvent (dpy, &next);
- if (next.type != MotionNotify)
- break;
- XtAppNextEvent (appContext, &event);
- }
- // Track the mouse and toggle the menu items
- Item item = _trackPointer ((XMotionEvent*)&event);
- // Unselect the current item (if the item is different)
-
- if (item != _curItem)
- {
- _toggleItem (_curItem, False);
-
- // Select the new item
-
- _toggleItem ((_curItem = item), True);
- }
-
- break;
- }
- default:
- {
- XtDispatchEvent (&event);
- break;
- }
- }
- }
- }
- // _processItem
- void _XsMotifMenu::_processItem (Item item)
- {
- if (item == NoItem)
- return;
- switch (item)
- {
- case Restore:
- {
- _win->restore ( );
- break;
- }
- case Move:
- {
- Widget base = (_win->minimized ( )) ? _win->icon ( ) : _win->base ( );
- // Warp the pointer to the center of the window
- Dimension width, height;
- XtVaGetValues (base, XmNwidth, &width, XmNheight, &height, NULL);
-
- XWarpPointer (XtDisplay (_base), None, XtWindow (base), 0, 0, 0, 0,
- (width / 2), (height / 2));
-
- // Move the window
- XsMoveOutline move (base);
- // Start the move
- if (move.go (True) != False)
- {
- // Relocate the window
-
- _win->setPosition (move.x ( ), move.y ( ));
- }
- break;
- }
- case Size:
- {
- Widget base = (_win->minimized ( )) ? _win->icon ( ) : _win->base ( );
- // Warp the pointer to the center of the window
- Dimension width, height;
- XtVaGetValues (base, XmNwidth, &width, XmNheight, &height, NULL);
-
- XWarpPointer (XtDisplay (_base), None, XtWindow (base), 0, 0, 0, 0,
- (width / 2), (height / 2));
-
- // Resize the window
- XsResizeOutline resize (_win->base ( ), XsResizeOutline::Undetermined);
- resize.setMinSize (_win->minWidth ( ), _win->minHeight ( ));
- // Start the resize
- if (resize.go (True) != False)
- {
- // Relocate the window
-
- _win->setPosition (resize.x ( ), resize.y ( ));
- _win->setSize (resize.width ( ), resize.height ( ));
- }
- break;
- }
- case Minimize:
- {
- _win->minimize ( );
- break;
- }
- case Maximize:
- {
- _win->maximize ( );
- break;
- }
- case Raise:
- {
- _win->raise ( );
- break;
- }
- case Lower:
- {
- _win->lower ( );
- break;
- }
- case Close:
- {
- _win->close ( );
- break;
- }
- default:
- assert (0);
- }
- }
- // _redrawMenu
- void _XsMotifMenu::_redrawMenu ( )
- {
- Dimension w, h;
-
- // Get the size of the menu
- XtVaGetValues (_base, XmNwidth, &w, XmNheight, &h, NULL);
-
- // Draw a shadow around the menu
- _drawShadows (0, 0, w, h, ShadowThickness);
- // Cycle and draw all of the elements
- for (int loop = 0; loop < Num; loop++)
- _redrawItem ((Item)loop);
- }
- // _redrawItem
- void _XsMotifMenu::_redrawItem (Item item)
- {
- if (item == NoItem)
- return;
-
- int x = ShadowThickness + HorizTextOffset;
- int y;
-
- /*
- Compute the y-position of the element. This will be the size of the
- top-shadow + the items before it + the offset of the item itself
- */
- y = ShadowThickness + // Top shadow
- (item * ((VertTextOffset * 2) + (_menuFont->descent + _menuFont->ascent))) +
- (VertTextOffset + _menuFont->ascent); // The item iteself
- // Figure out the graphics-context
- GC gc;
-
- if (_win->minimized ( ))
- gc = ((item == Size) || (item == Minimize)) ? _grayGC : _fontGC;
- else if (_win->maximized ( ))
- gc = (item == Maximize) ? _grayGC : _fontGC;
- else
- gc = (item == Restore) ? _grayGC : _fontGC;
-
- // Draw the string
- XDrawString (XtDisplay (_base), XtWindow (_base), gc, x, y,
- _strings[item], strlen (_strings[item]));
- }
- // _toggleItem
- void _XsMotifMenu::_toggleItem (Item item, Boolean active)
- {
- if (item == NoItem)
- return;
-
- /*
- Either draw the background of the specified item in the active color
- or the standard background color
- */
- GC gc = (active) ? _to