⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 xsmotifwindow.c

📁 Wxpython Implemented on Windows CE, Source code
💻 C
📖 第 1 页 / 共 5 页
字号:

   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) ? _topShadowGC : _backgroundGC;
   
// Get the width of the menu

   Dimension menuWidth;
   XtVaGetValues (_base, XmNwidth, &menuWidth, NULL);

// Compute the location and size of the rectangle

   int   x, y;
   unsigned int width, height;

   x = ShadowThickness;
   height = ((VertTextOffset * 2) + (_menuFont->descent + _menuFont->ascent));
   y = ShadowThickness + (item * height);
   width = menuWidth - (2 * ShadowThickness);
   
// Draw the filled rectangle

   XFillRectangle (XtDisplay (_base), XtWindow (_base), gc, x, y, width, height);

// Redraw the text

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -