home *** CD-ROM | disk | FTP | other *** search
/ Tools / WinSN5.0Ver.iso / NETSCAP.50 / WIN1998.ZIP / ns / cmd / xfe / src / PopupMenu.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1998-04-08  |  4.7 KB  |  208 lines

  1. /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
  2.  *
  3.  * The contents of this file are subject to the Netscape Public License
  4.  * Version 1.0 (the "NPL"); you may not use this file except in
  5.  * compliance with the NPL.  You may obtain a copy of the NPL at
  6.  * http://www.mozilla.org/NPL/
  7.  *
  8.  * Software distributed under the NPL is distributed on an "AS IS" basis,
  9.  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
  10.  * for the specific language governing rights and limitations under the
  11.  * NPL.
  12.  *
  13.  * The Initial Developer of this code under the NPL is Netscape
  14.  * Communications Corporation.  Portions created by Netscape are
  15.  * Copyright (C) 1998 Netscape Communications Corporation.  All Rights
  16.  * Reserved.
  17.  */
  18. /* 
  19.    PopupMenu.cpp -- implementation file for PopupMenu
  20.    Created: Chris Toshok <toshok@netscape.com>, 7-Aug-96.
  21.  */
  22.  
  23.  
  24.  
  25. #if DEBUG_toshok
  26. #define D(x) x
  27. #else
  28. #define D(x)
  29. #endif
  30.  
  31. #include "Frame.h"
  32. #include "PopupMenu.h"
  33. #include "DisplayFactory.h"
  34.  
  35. #include <Xm/RowColumn.h>
  36. #include <Xfe/Xfe.h>
  37.  
  38. MenuSpec XFE_PopupMenu::title_spec[] = {
  39.   //  { "title", LABEL },
  40.   //MENU_SEPARATOR,
  41.   { NULL }
  42. };
  43.  
  44. extern "C" 
  45. {
  46.     // Needed to determine the colormap used by the floating shell colormap
  47.     Colormap fe_getColormap(fe_colormap *colormap);
  48. }
  49.  
  50. XFE_PopupMenu::XFE_PopupMenu(String            name,
  51.                              XFE_Frame *    parent_frame,
  52.                              Widget            parent,
  53.                              MenuSpec *        spec) :
  54.     XFE_Menu(parent_frame,
  55.              NULL,
  56.              NULL)
  57. {
  58.     // Create the popup menu
  59.     Widget popup_menu = XFE_PopupMenu::CreatePopupMenu(parent,name,NULL,0);
  60.  
  61.     setBaseWidget(popup_menu);
  62.  
  63.     setMenuSpec(spec);
  64.  
  65.     if (spec)
  66.         createWidgets(spec);
  67. }
  68.  
  69. static XtPointer
  70. fe_popup_destroy_mappee(Widget widget, XtPointer data)
  71. {
  72.     Widget menu;
  73.  
  74.     if (XtIsSubclass(widget, xmCascadeButtonGadgetClass)) {
  75.         XtVaGetValues(widget, XmNsubMenuId, &menu, 0);
  76.         if (menu != 0)
  77.             fe_WidgetTreeWalk(menu, fe_popup_destroy_mappee, NULL);
  78.     }
  79.     
  80.     XtDestroyWidget(widget);
  81.  
  82.     return 0;
  83. }
  84.  
  85. XFE_PopupMenu::~XFE_PopupMenu()
  86. {
  87.     //
  88.     // we need to destroy the shell parent of our base widget, which
  89.     // happens to be the row column.
  90.     // In case the popup has submenus, walk the tree following
  91.     // cascade/sub-menu linkages.
  92.     // 
  93.     fe_WidgetTreeWalk(XtParent(m_widget), fe_popup_destroy_mappee, NULL);
  94.  
  95.     m_widget = NULL;
  96. }
  97.  
  98. void
  99. XFE_PopupMenu::position(XEvent *event)
  100. {
  101.   XP_ASSERT(event->type == ButtonPress);
  102.   
  103.   XmMenuPosition(m_widget, (XButtonPressedEvent*)event);
  104. }
  105.  
  106. void
  107. XFE_PopupMenu::show()
  108. {
  109.   update();
  110.  
  111.   XFE_Menu::show();
  112. }
  113.  
  114. /* static */ Widget
  115. XFE_PopupMenu::CreatePopupMenu(Widget pw,String name,ArgList av,Cardinal ac)
  116. {
  117.     Widget            popup;
  118.     ArgList            new_av;
  119.     Cardinal        new_ac;
  120.     Cardinal        i;
  121.  
  122.     XP_ASSERT( XfeIsAlive(pw) );
  123.     XP_ASSERT( name != NULL );
  124.  
  125.     new_ac = ac + 3;
  126.  
  127.     new_av = (ArgList) XtMalloc(sizeof(Arg) * new_ac);
  128.  
  129.     for (i = 0; i < ac; i++)
  130.     {
  131.         XtSetArg(new_av[i],av[i].name,av[i].value);
  132.     }
  133.  
  134.     // Make sure the display factory is running
  135.     fe_startDisplayFactory(FE_GetToplevelWidget());
  136.  
  137.     fe_colormap *    colormap;
  138.     Colormap        x_colormap;
  139.     Visual *        visual;
  140.     int                depth;
  141.  
  142.     // Obtain the colormap / depth / and visual 
  143.     colormap    = XFE_DisplayFactory::theFactory()->getSharedColormap();
  144.     x_colormap    = fe_getColormap(colormap);
  145.     depth        = XFE_DisplayFactory::theFactory()->getVisualDepth();
  146.     visual        = XFE_DisplayFactory::theFactory()->getVisual();
  147.  
  148.     XtSetArg(new_av[ac + 0],XmNcolormap,x_colormap);
  149.     XtSetArg(new_av[ac + 1],XmNvisual,visual);
  150.     XtSetArg(new_av[ac + 2],XmNdepth,depth);
  151.  
  152.     popup = XmCreatePopupMenu(pw,name,new_av,new_ac);
  153.  
  154.     XtFree((char *) new_av);
  155.  
  156.     return popup;
  157. }
  158.  
  159. // Remove the osfLeft and osfRight translations of the popup's children.
  160. // For bug 71620.  See the bug description for details.  Basically, for
  161. // some strange reason, motif assumes that either a left or a right 
  162. // naviation widget exists for this popup menu and core dumps trying 
  163. // to dereference a NULL widget.
  164.  
  165. static char _leftRightTranslations[] = "\
  166. :<Key>osfLeft:            \n\
  167. :<Key>osfRight:            ";
  168.  
  169. void
  170. XFE_PopupMenu::removeLeftRightTranslations()
  171. {
  172.     WidgetList    children;
  173.     Cardinal    num_children;
  174.     Cardinal    i;
  175.  
  176.     XP_ASSERT( XfeIsAlive(m_widget) );
  177.     XP_ASSERT( XmIsRowColumn(m_widget) );
  178.  
  179.     if (!XfeIsAlive(m_widget))
  180.     {
  181.         return;
  182.     }
  183.     
  184.     XfeChildrenGet(m_widget,&children,&num_children);
  185.  
  186.     if (!children || !num_children)
  187.     {
  188.         return;
  189.     }
  190.     
  191.     for(i = 0; i < num_children; i++)
  192.     {
  193.         if (XmIsPrimitive(children[i]))
  194.         {
  195.             XfeOverrideTranslations(children[i],_leftRightTranslations);
  196.         }
  197.     }
  198. }
  199.  
  200. void
  201. XFE_PopupMenu::raise()
  202. {
  203.     XP_ASSERT( isAlive() );
  204.  
  205.     XRaiseWindow(XtDisplay(XtParent(m_widget)),
  206.                  XtWindow(XtParent(m_widget)));
  207. }
  208.