📄 xsmotifwindow.c
字号:
_redrawItem (item);
}
// _trackPointer
_XsMotifMenu::Item _XsMotifMenu::_trackPointer (XMotionEvent *event)
{
assert (_base != 0);
Dimension menuWidth;
Dimension menuHeight;
Position x, y;
// Get the menu size and position
XtVaGetValues (_base, XmNwidth, &menuWidth, XmNheight, &menuHeight,
XmNx, &x, XmNy, &y, NULL);
// Make sure the pointer is in the menu
if ((event->x_root < x) || (event->x_root > (x + menuWidth)))
return (NoItem);
if ((event->y_root < y) || (event->y_root > (y + menuHeight)))
return (NoItem);
// Make sure the pointer is on the confines of the shadow
if ((event->x < ShadowThickness) || (event->x > (menuWidth - (2 * ShadowThickness))))
return (NoItem);
if ((event->y < ShadowThickness) || (event->y > (menuHeight - (2 * ShadowThickness))))
return (NoItem);
/*
Now we are just concerned with the y-position. Subtract off the
shadow thickness to normalize the location
*/
int yPos = event->y - ShadowThickness;
// Compute which item the mouse is in
int itemHeight = (VertTextOffset * 2) + (_menuFont->descent + _menuFont->ascent);
Item item = (Item)(yPos / itemHeight);
// Validate that the item is not grayed-out
if (_win->minimized ( ))
{
if ((item == Size) || (item == Minimize))
item = NoItem;
}
else if (_win->maximized ( ))
{
if (item == Maximize)
item = NoItem;
}
else if (item == Restore)
item = NoItem;
return (item);
}
// _grabPointer
Boolean _XsMotifMenu::_grabPointer ( )
{
// Sync everything up before being grabby
XSync (XtDisplay (_base), False);
// Grab the pointer
if (XGrabPointer (XtDisplay (_base), XtWindow (_base), False,
(unsigned int)(ButtonPressMask | ButtonReleaseMask | PointerMotionMask |
EnterWindowMask | LeaveWindowMask), GrabModeAsync,
GrabModeAsync, None, _cursor, CurrentTime) != GrabSuccess)
{
XBell (XtDisplay (_base), 100);
return (False);
}
return (True);
}
// _ungrabPointer
void _XsMotifMenu::_ungrabPointer ( )
{
// Ungrab the pointer
XUngrabPointer (XtDisplay (_base), CurrentTime);
// Sync everything back up
XSync (XtDisplay (_base), False);
}
// _map
void _XsMotifMenu::_map ( )
{
// Call the base-class
_XsMotifBase::_map ( );
unsigned long valuemask;
XGCValues values;
Pixel foreground;
Pixel background;
// Get the pixels
XtVaGetValues (XtParent (_base), XmNforeground, &foreground, NULL);
XtVaGetValues (_base, XmNbackground, &background, NULL);
// Create the font graphics context
valuemask = GCForeground | GCBackground | GCGraphicsExposures | GCFont;
values.foreground = foreground;
values.background = background;
values.font = _menuFont->fid;
values.graphics_exposures = False;
_fontGC = XtGetGC (_base, valuemask, &values);
// Create the insensitive font graphics context
valuemask |= (GCFillStyle | GCTile);
values.fill_style = FillTiled;
values.tile = _stipple;
_grayGC = XtGetGC (_base, valuemask, &values);
// Create the background contexts
valuemask = GCForeground | GCLineWidth | GCGraphicsExposures;
values.line_width = 0;
values.graphics_exposures = False;
values.foreground = background;
_backgroundGC = XtGetGC (_base, valuemask, &values);
}
// _workProc
Boolean _XsMotifMenu::_workProc (XtPointer clientData)
{
_XsMotifMenu *obj = (_XsMotifMenu*)clientData;
if (obj->_curItem != NoItem)
obj->_processItem (obj->_curItem);
return (True);
}
/*
----------------------------------------------------------------------------
XsMotifWindow
*/
// Static definitions
XtResource XsMotifWindow::_resourceList[] = {
{
"showBorder",
"ShowBorder",
XmRBoolean,
sizeof (Boolean),
XtOffset (XsMotifWindow*, _showBorder),
XmRImmediate,
(XtPointer)True
},
{
"showResize",
"ShowResize",
XmRBoolean,
sizeof (Boolean),
XtOffset (XsMotifWindow*, _showResize),
XmRImmediate,
(XtPointer)True
},
{
"showTitle",
"ShowTitle",
XmRBoolean,
sizeof (Boolean),
XtOffset (XsMotifWindow*, _showTitle),
XmRImmediate,
(XtPointer)True
},
{
"showMenu",
"ShowMenu",
XmRBoolean,
sizeof (Boolean),
XtOffset (XsMotifWindow*, _showMenu),
XmRImmediate,
(XtPointer)True
},
{
"showMinimize",
"ShowMinimize",
XmRBoolean,
sizeof (Boolean),
XtOffset (XsMotifWindow*, _showMinimize),
XmRImmediate,
(XtPointer)True
},
{
"showMaximize",
"ShowMaximize",
XmRBoolean,
sizeof (Boolean),
XtOffset (XsMotifWindow*, _showMaximize),
XmRImmediate,
(XtPointer)True
},
{
"lowerOnIconify",
"LowerOnIconify",
XmRBoolean,
sizeof (Boolean),
XtOffset (XsMotifWindow*, _lowerOnIconify),
XmRImmediate,
(XtPointer)False
},
{
XmNminWidth,
XmCMinWidth,
XmRDimension,
sizeof (Dimension),
XtOffset (XsMotifWindow*, _minW),
XmRImmediate,
(XtPointer)((BorderSize_ + ButtonSize_) * 3)
},
{
XmNmaxWidth,
XmCMaxWidth,
XmRDimension,
sizeof (Dimension),
XtOffset (XsMotifWindow*, _maxW),
XmRImmediate,
(XtPointer)-1
},
{
XmNminHeight,
XmCMinHeight,
XmRDimension,
sizeof (Dimension),
XtOffset (XsMotifWindow*, _minH),
XmRImmediate,
(XtPointer)((BorderSize_ + ButtonSize_) * 3)
},
{
XmNmaxHeight,
XmCMaxHeight,
XmRDimension,
sizeof (Dimension),
XtOffset (XsMotifWindow*, _maxH),
XmRImmediate,
(XtPointer)-1
}
};
// Constructor
XsMotifWindow::XsMotifWindow (const char *name) : XsMDIWindow (name)
{
int loop;
// Initialize
for (loop = 0; loop < _XsMotifSide::Max; loop++)
{
_corners[loop] = 0;
_sides[loop] = 0;
}
for (loop = 0; loop < _XsMotifButton::Max; loop++)
_buttons[loop] = 0;
_title = 0;
_icon = 0;
_menu = 0;
_maximized = False;
_minimized = False;
}
// Destructor
XsMotifWindow::~XsMotifWindow ( )
{
int loop;
for (loop = 0; loop < _XsMotifSide::Max; loop++)
{
delete _corners[loop];
delete _sides[loop];
}
for (loop = 0; loop < _XsMotifButton::Max; loop++)
delete _buttons[loop];
delete _title;
delete _icon;
delete _menu;
}
// raise
void XsMotifWindow::raise ( )
{
Widget w = (_minimized == True) ? _icon->base ( ) : _base;
assert (w != 0);
XRaiseWindow (XtDisplay (w), XtWindow (w));
}
// lower
void XsMotifWindow::lower ( )
{
Widget w = (_minimized == True) ? _icon->base ( ) : _base;
assert (w != 0);
XLowerWindow (XtDisplay (w), XtWindow (w));
}
// minimize
void XsMotifWindow::minimize ( )
{
assert (_base != 0);
// Check if we are already minimized
if (_minimized == True)
return;
// Minimize the window
hide ( );
_minimized = True;
// Lower (if necessary)
if (_lowerOnIconify)
lower ( );
_icon->show ( );
}
// maximize
void XsMotifWindow::maximize ( )
{
assert (_base != 0);
// Check if we are already in this state
if (_maximized == True)
return;
// Restore (if necessary)
if (_minimized)
restore ( );
// Save current dimensions
XtVaGetValues (_base, XmNx, &_savedX, XmNy, &_savedY, XmNwidth,
&_savedWidth, XmNheight, &_savedHeight, NULL);
/*
Constrain the new window size. The size of the maximized window
is equal to the size of the current clip-window of the canvas.
*/
const Dimension offset = 5; // Border around max'd window
Widget clipWindow = XtParent (XtParent (_base));
assert (clipWindow != 0);
Dimension clipW, clipH;
Window child;
int newX, newY;
XtVaGetValues (clipWindow, XmNheight, &clipH, XmNwidth, &clipW, NULL);
// Add in offset
if (clipW > (offset * 2))
clipW -= (offset * 2);
if (clipH > (offset * 2))
clipH -= (offset * 2);
// Compute the new window position (map clip-window to work-area)
XTranslateCoordinates (XtDisplay (_base), XtWindow (clipWindow),
XtWindow (XtParent (_base)), (int)offset, (int)offset,
&newX, &newY, &child);
// Set new maximum dimensions
setPosition ((Position)newX, (Position)newY);
setSize (clipW, clipH);
_maximized = True;
// Redraw the maximize button
_buttons[_XsMotifButton::Maximize]->redraw ( );
}
// restore
void XsMotifWindow::restore ( )
{
assert (_base != 0);
// Check if we are already restored
if ((_maximized == False) && (_minimized == False))
return;
// Either un-minimize or un-maximize
if (_minimized)
{
// Restore the window
_icon->hide ( );
_minimized = False;
// If maximized, restore again
if (_maximized)
restore ( );
// Show the window
show ( );
}
else
{
// Restore saved dimensions
setPosition (_savedX, _savedY);
setSize (_savedWidth, _savedHeight);
}
}
// close
void XsMotifWindow::close ( )
{
/*
Don't delete the window (because its not ours to delete).
Just hide it.
*/
if (_minimized)
_icon->hide ( );
else
hide ( );
}
// setTitle
void XsMotifWindow::setTitle (const char *title)
{
if (_title != 0)
_title->setTitle (title);
}
// setIconName
void XsMotifWindow::setIconName (const char *iconName)
{
if (_icon != 0)
_icon->setIconName (iconName);
}
// setPixmap
void XsMotifWindow::setPixmap (Pixmap pixmap)
{
if (_icon != 0)
_icon->setPixmap (pixmap);
}
// popupMenu
void XsMotifWindow::popupMenu (Boolean b)
{
if (_menu != 0)
_menu->popup (b);
}
// setPosition
void XsMotifWindow::setPosition (Position x, Position y)
{
if (_base != 0)
{
Widget w = (_minimized == True) ? _icon->base ( ) : _base;
assert (w != 0);
XtVaSetValues (w, XmNx, x, XmNy, y, NULL);
}
else
XsMDIWindow::setPosition (x, y); // Cache the points
}
// setSize
void XsMotifWindow::setSize (Dimension w, Dimension h)
{
// Set the window size
if (_base != 0)
{
if (w < _minW)
w = _minW;
else if ((_maxW != (Dimension)-1) && (w > _maxW))
w = _maxW;
if (h < _minH)
h = _minH;
else if ((_maxH != (Dimension)-1) && (h > _maxH))
h = _maxH;
if (_minimized == False)
XtVaSetValues (_base, XmNwidth, w, XmNheight, h, NULL);
// If window was maximized, change the window state back to normal
if (_maximized == True)
{
_maximized = False;
// Redraw the maximize button
_buttons[_XsMotifButton::Maximize]->redraw ( );
}
}
else
XsMDIWindow::setSize (w, h); // Cache the points
}
// className
const char* XsMotifWindow::className ( ) const
{
return ("XsMotifWindow");
}
// _createWindow
void XsMotifWindow::_createWindow (Widget parent)
{
assert (parent != 0);
// Create the window frame
_base = XtVaCreateWidget (_name, xmFormWidgetClass, parent,
XmNborderWidth, (Dimension)1, NULL);
// Install destroy handler
_installDestroyHandler ( );
// Get resources
_getResources (_resourceList, XtNumber (_resourceList));
/*
Fix configuration inter-dependencies. Here are the rules:
1) If there is no border, then there are no resize handles
2) If there is no title, then there are no buttons (would look stupid)
*/
if (_showBorder == False)
_showResize = False;
if (_showTitle == False)
{
_showMenu = False;
_showMinimize = False;
_showMaximize = False;
}
/*
Cor
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -