📄 xsmotifwindow.c
字号:
/*
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
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -