Mozilla/mozilla/cmd/xfe/src/PopupMenu.cpp
slamm%netscape.com e3ed4915d7 Move XFE_RDFPopupMenu in PopupMenu.(cpp|h)
so the toolbars can use it too.


git-svn-id: svn://10.0.0.236/trunk@12754 18797224-902f-48f8-a5cc-f745e15eee43
1998-10-13 23:46:51 +00:00

311 lines
7.6 KiB
C++

/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
/*
PopupMenu.cpp -- implementation file for PopupMenu
Created: Chris Toshok <toshok@netscape.com>, 7-Aug-96.
*/
#if DEBUG_slamm
#define D(x) x
#else
#define D(x)
#endif
#include "Frame.h"
#include "PopupMenu.h"
#include "DisplayFactory.h"
#include <Xm/RowColumn.h>
#include <Xfe/Xfe.h>
MenuSpec XFE_PopupMenu::title_spec[] = {
// { "title", LABEL },
//MENU_SEPARATOR,
{ NULL }
};
extern "C"
{
// Needed to determine the colormap used by the floating shell colormap
Colormap fe_getColormap(fe_colormap *colormap);
}
XFE_PopupMenuBase::XFE_PopupMenuBase(String name, Widget parent)
{
// Create the popup menu
m_popup_menu = XFE_PopupMenuBase::CreatePopupMenu(parent,name,NULL,0);
}
static XtPointer
fe_popup_destroy_mappee(Widget widget, XtPointer data)
{
Widget menu;
if (XtIsSubclass(widget, xmCascadeButtonGadgetClass)) {
XtVaGetValues(widget, XmNsubMenuId, &menu, 0);
if (menu != 0)
fe_WidgetTreeWalk(menu, fe_popup_destroy_mappee, NULL);
}
XtDestroyWidget(widget);
return 0;
}
XFE_PopupMenuBase::~XFE_PopupMenuBase()
{
//
// we need to destroy the shell parent of our base widget, which
// happens to be the row column.
// In case the popup has submenus, walk the tree following
// cascade/sub-menu linkages.
//
fe_WidgetTreeWalk(XtParent(m_popup_menu), fe_popup_destroy_mappee, NULL);
}
void
XFE_PopupMenuBase::position(XEvent *event)
{
XP_ASSERT(event->type == ButtonPress);
XP_ASSERT( XfeIsAlive(m_popup_menu) );
XmMenuPosition(m_popup_menu, (XButtonPressedEvent*)event);
}
/* static */ Widget
XFE_PopupMenuBase::CreatePopupMenu(Widget pw,String name,ArgList av,Cardinal ac)
{
Widget popup;
ArgList new_av;
Cardinal new_ac;
Cardinal i;
XP_ASSERT( XfeIsAlive(pw) );
XP_ASSERT( name != NULL );
new_ac = ac + 3;
new_av = (ArgList) XtMalloc(sizeof(Arg) * new_ac);
for (i = 0; i < ac; i++)
{
XtSetArg(new_av[i],av[i].name,av[i].value);
}
// Make sure the display factory is running
fe_startDisplayFactory(FE_GetToplevelWidget());
fe_colormap * colormap;
Colormap x_colormap;
Visual * visual;
int depth;
// Obtain the colormap / depth / and visual
colormap = XFE_DisplayFactory::theFactory()->getSharedColormap();
x_colormap = fe_getColormap(colormap);
depth = XFE_DisplayFactory::theFactory()->getVisualDepth();
visual = XFE_DisplayFactory::theFactory()->getVisual();
XtSetArg(new_av[ac + 0],XmNcolormap,x_colormap);
XtSetArg(new_av[ac + 1],XmNvisual,visual);
XtSetArg(new_av[ac + 2],XmNdepth,depth);
popup = XmCreatePopupMenu(pw,name,new_av,new_ac);
XtFree((char *) new_av);
return popup;
}
// Remove the osfLeft and osfRight translations of the popup's children.
// For bug 71620. See the bug description for details. Basically, for
// some strange reason, motif assumes that either a left or a right
// naviation widget exists for this popup menu and core dumps trying
// to dereference a NULL widget.
static char _leftRightTranslations[] = "\
:<Key>osfLeft: \n\
:<Key>osfRight: ";
void
XFE_PopupMenuBase::removeLeftRightTranslations()
{
WidgetList children;
Cardinal num_children;
Cardinal i;
XP_ASSERT( XfeIsAlive(m_popup_menu) );
XP_ASSERT( XmIsRowColumn(m_popup_menu) );
if (!XfeIsAlive(m_popup_menu))
{
return;
}
XfeChildrenGet(m_popup_menu,&children,&num_children);
if (!children || !num_children)
{
return;
}
for(i = 0; i < num_children; i++)
{
if (XmIsPrimitive(children[i]))
{
XfeOverrideTranslations(children[i],_leftRightTranslations);
}
}
}
void
XFE_PopupMenuBase::raise()
{
XP_ASSERT( XfeIsAlive(m_popup_menu) );
XRaiseWindow(XtDisplay(XtParent(m_popup_menu)),
XtWindow(XtParent(m_popup_menu)));
}
//////////////////////////////////////////////////////////////////////
XFE_PopupMenu::XFE_PopupMenu(String name,
XFE_Frame * parent_frame,
Widget parent,
MenuSpec * spec,
XFE_Component *cmdDispatcher)
: XFE_Menu(parent_frame, (MenuSpec *) NULL,
(Widget) NULL, cmdDispatcher),
XFE_PopupMenuBase(name,parent)
{
setBaseWidget(m_popup_menu);
setMenuSpec(spec);
if (spec)
createWidgets(spec);
}
#if 0
// Not sure if this is needed
XFE_PopupMenu::~XFE_PopupMenu()
{
m_widget = NULL;
}
#endif
//////////////////////////////////////////////////////////////////////
XFE_SimplePopupMenu::XFE_SimplePopupMenu(String name, Widget parent)
: XFE_PopupMenuBase(name,parent)
{
; // Nothing to do.
}
void
XFE_SimplePopupMenu::show()
{
XtManageChild(m_popup_menu);
}
void
XFE_SimplePopupMenu::addSeparator()
{
Widget sep = XtCreateWidget("separator",
xmSeparatorGadgetClass,
m_popup_menu,
NULL, 0);
XtManageChild(sep);
}
void
XFE_SimplePopupMenu::addPushButton(String name, void *userData, Boolean isSensitive)
{
Widget button = XtCreateWidget("push",
xmPushButtonWidgetClass,
m_popup_menu,
NULL, 0);
XmString str;
str = XmStringCreate(name, XmFONTLIST_DEFAULT_TAG);
XtVaSetValues(button,
XmNuserData, (XtPointer)userData,
XmNsensitive, isSensitive,
XmNlabelString, str,
NULL);
XmStringFree(str);
XtAddCallback(button, XmNactivateCallback, pushb_activate_cb, this);
XtManageChild(button);
}
void
XFE_SimplePopupMenu::pushb_activate_cb(Widget w,
XtPointer clientData, XtPointer callData)
{
XFE_SimplePopupMenu* obj = (XFE_SimplePopupMenu*)clientData;
//XmPushButtonCallbackStruct* cd = (XmPushButtonCallbackStruct *)callData;
XtPointer userData;
XtVaGetValues(w,
XmNuserData, &userData,
NULL);
obj->PushButtonActivate(w,userData);
}
void
XFE_SimplePopupMenu::PushButtonActivate(Widget w, XtPointer userData)
{
; // Do nothing for now.
}
//////////////////////////////////////////////////////////////////////////
//
// RDFPopupMenu
//
//////////////////////////////////////////////////////////////////////////
XFE_RDFPopupMenu::XFE_RDFPopupMenu(String name, Widget parent,
HT_View view,
Boolean isWorkspace, Boolean isBackground)
: XFE_SimplePopupMenu(name, parent)
{
m_pane = HT_GetPane(view);
HT_Cursor cursor = HT_NewContextualMenuCursor(view,
isWorkspace, isBackground);
HT_MenuCmd command;
while(HT_NextContextMenuItem(cursor, &command))
{
if (command == HT_CMD_SEPARATOR)
addSeparator();
else
addPushButton(HT_GetMenuCmdName(command), (XtPointer)command,
HT_IsMenuCmdEnabled(m_pane, command));
}
}
void
XFE_RDFPopupMenu::PushButtonActivate(Widget /* w */, XtPointer userData)
{
HT_DoMenuCmd(m_pane, (HT_MenuCmd)(int)userData);
}