зеркало из https://github.com/mozilla/gecko-dev.git
Dynamic menus changes
This commit is contained in:
Родитель
0bfa10a718
Коммит
96e4bf2924
|
@ -27,6 +27,7 @@
|
|||
#include "nsScrollbar.h"
|
||||
#include "nsFileWidget.h"
|
||||
#include "nsGUIEvent.h"
|
||||
#include "nsIMenu.h"
|
||||
#include "nsIMenuItem.h"
|
||||
#include "nsIMenuListener.h"
|
||||
|
||||
|
@ -413,7 +414,7 @@ gint handle_focus_out_event(GtkWidget *w, GdkEventFocus * event, gpointer p)
|
|||
//==============================================================
|
||||
void menu_item_activate_handler(GtkWidget *w, gpointer p)
|
||||
{
|
||||
g_print("menu selected\n");
|
||||
g_print("menu_item_activate_handler\n");
|
||||
|
||||
nsIMenuListener *menuListener = nsnull;
|
||||
nsIMenuItem *menuItem = (nsIMenuItem *)p;
|
||||
|
@ -436,7 +437,61 @@ void menu_item_activate_handler(GtkWidget *w, gpointer p)
|
|||
|
||||
menuItem->QueryInterface(kIMenuListenerIID, (void**)&menuListener);
|
||||
if(menuListener) {
|
||||
menuListener->MenuSelected(mevent);
|
||||
menuListener->MenuItemSelected(mevent);
|
||||
NS_IF_RELEASE(menuListener);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//==============================================================
|
||||
void menu_map_handler(GtkWidget *w, gpointer p)
|
||||
{
|
||||
nsIMenuListener *menuListener = nsnull;
|
||||
nsIMenu *menu = (nsIMenu *)p;
|
||||
if (menu != NULL) {
|
||||
nsMenuEvent mevent;
|
||||
mevent.message = NS_MENU_SELECTED;
|
||||
mevent.eventStructType = NS_MENU_EVENT;
|
||||
mevent.point.x = 0;
|
||||
mevent.point.y = 0;
|
||||
mevent.widget = nsnull;
|
||||
|
||||
mevent.time = PR_IntervalNow();
|
||||
|
||||
nsEventStatus status;
|
||||
|
||||
menu->QueryInterface(kIMenuListenerIID, (void**)&menuListener);
|
||||
if(menuListener) {
|
||||
menuListener->MenuConstruct(
|
||||
mevent,
|
||||
NULL, //parent window
|
||||
NULL, //menuNode
|
||||
NULL ); // webshell
|
||||
NS_IF_RELEASE(menuListener);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//==============================================================
|
||||
void menu_unmap_handler(GtkWidget *w, gpointer p)
|
||||
{
|
||||
nsIMenuListener *menuListener = NULL;
|
||||
nsIMenu *menu = (nsIMenu *)p;
|
||||
if (menu != NULL) {
|
||||
nsMenuEvent mevent;
|
||||
mevent.message = NS_MENU_SELECTED;
|
||||
mevent.eventStructType = NS_MENU_EVENT;
|
||||
mevent.point.x = 0;
|
||||
mevent.point.y = 0;
|
||||
mevent.widget = nsnull;
|
||||
|
||||
mevent.time = PR_IntervalNow();
|
||||
|
||||
nsEventStatus status;
|
||||
|
||||
menu->QueryInterface(kIMenuListenerIID, (void**)&menuListener);
|
||||
if(menuListener) {
|
||||
menuListener->MenuDestruct(mevent);
|
||||
NS_IF_RELEASE(menuListener);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
|
||||
class nsIWidget;
|
||||
class nsIMenuItem;
|
||||
class nsIMenu;
|
||||
|
||||
gint handle_configure_event(GtkWidget *w, GdkEventConfigure *conf, gpointer p);
|
||||
void handle_size_allocate(GtkWidget *w, GtkAllocation *alloc, gpointer p);
|
||||
|
@ -37,6 +38,9 @@ void handle_scrollbar_value_changed(GtkAdjustment *adjustment, gpointer p);
|
|||
|
||||
void menu_item_activate_handler(GtkWidget *w, gpointer p);
|
||||
|
||||
void menu_map_handler(GtkWidget *w, gpointer p);
|
||||
void menu_unmap_handler(GtkWidget *w, gpointer p);
|
||||
|
||||
//----------------------------------------------------
|
||||
|
||||
gint nsGtkWidget_FSBCancel_Callback(GtkWidget *w, gpointer p);
|
||||
|
|
|
@ -27,6 +27,17 @@
|
|||
#include "nsStringUtil.h"
|
||||
#include "nsIMenuListener.h"
|
||||
|
||||
#include "nsGtkEventHandler.h"
|
||||
|
||||
#include "nsCOMPtr.h"
|
||||
|
||||
#include "nsIComponentManager.h"
|
||||
|
||||
#include "nsWidgetsCID.h"
|
||||
static NS_DEFINE_IID(kMenuBarCID, NS_MENUBAR_CID);
|
||||
static NS_DEFINE_IID(kMenuCID, NS_MENU_CID);
|
||||
static NS_DEFINE_IID(kMenuItemCID, NS_MENUITEM_CID);
|
||||
|
||||
static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID);
|
||||
static NS_DEFINE_IID(kIMenuIID, NS_IMENU_IID);
|
||||
static NS_DEFINE_IID(kIMenuBarIID, NS_IMENUBAR_IID);
|
||||
|
@ -74,6 +85,11 @@ nsMenu::nsMenu() : nsIMenu()
|
|||
mMenuParent = nsnull;
|
||||
mMenuBarParent = nsnull;
|
||||
mListener = nsnull;
|
||||
mConstructCalled = false;
|
||||
|
||||
mDOMNode = nsnull;
|
||||
mWebShell = nsnull;
|
||||
mDOMElement = nsnull;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
|
@ -120,6 +136,12 @@ NS_METHOD nsMenu::Create(nsISupports *aParent, const nsString &aLabel)
|
|||
mLabel = aLabel;
|
||||
mMenu = gtk_menu_new();
|
||||
|
||||
gtk_signal_connect (GTK_OBJECT (mMenu), "map",
|
||||
GTK_SIGNAL_FUNC(menu_map_handler),
|
||||
this);
|
||||
gtk_signal_connect (GTK_OBJECT (mMenu), "unmap",
|
||||
GTK_SIGNAL_FUNC(menu_unmap_handler),
|
||||
this);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -184,7 +206,7 @@ NS_METHOD nsMenu::AddItem(nsISupports * aItem)
|
|||
NS_METHOD nsMenu::AddMenuItem(nsIMenuItem * aMenuItem)
|
||||
{
|
||||
GtkWidget *widget;
|
||||
void *voidData;
|
||||
void *voidData;
|
||||
|
||||
aMenuItem->GetNativeData(voidData);
|
||||
widget = GTK_WIDGET(voidData);
|
||||
|
@ -192,6 +214,10 @@ NS_METHOD nsMenu::AddMenuItem(nsIMenuItem * aMenuItem)
|
|||
gtk_menu_shell_append (GTK_MENU_SHELL (mMenu), widget);
|
||||
|
||||
// XXX add aMenuItem to internal data structor list
|
||||
NS_IF_ADDREF(aMenuItem);
|
||||
mMenuItemVoidArray.AppendElement(aMenuItem);
|
||||
mNumMenuItems++;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -204,33 +230,69 @@ NS_METHOD nsMenu::AddMenu(nsIMenu * aMenu)
|
|||
void *voidData=NULL;
|
||||
|
||||
aMenu->GetLabel(Label);
|
||||
|
||||
labelStr = Label.ToNewCString();
|
||||
|
||||
item = gtk_menu_item_new_with_label (labelStr);
|
||||
gtk_widget_show(item);
|
||||
gtk_menu_shell_append (GTK_MENU_SHELL (mMenu), item);
|
||||
// Create nsMenuItem
|
||||
nsIMenuItem * pnsMenuItem = nsnull;
|
||||
nsresult rv = nsComponentManager::CreateInstance(
|
||||
kMenuItemCID, nsnull, kIMenuItemIID, (void**)&pnsMenuItem);
|
||||
if (NS_OK == rv) {
|
||||
pnsMenuItem->Create(this, labelStr, 0);
|
||||
nsISupports * supports = nsnull;
|
||||
pnsMenuItem->QueryInterface(kISupportsIID, (void**) &supports);
|
||||
AddItem(supports); // Parent should now own menu item
|
||||
NS_RELEASE(supports);
|
||||
|
||||
//NS_RELEASE(pnsMenuItem);
|
||||
}
|
||||
//item = gtk_menu_item_new_with_label (labelStr);
|
||||
//gtk_widget_show(item);
|
||||
//gtk_menu_shell_append (GTK_MENU_SHELL (mMenu), item);
|
||||
|
||||
delete[] labelStr;
|
||||
|
||||
void * menuitem = nsnull;
|
||||
pnsMenuItem->GetNativeData(menuitem);
|
||||
|
||||
voidData = NULL;
|
||||
|
||||
aMenu->GetNativeData(&voidData);
|
||||
newmenu = GTK_WIDGET(voidData);
|
||||
|
||||
gtk_menu_item_set_submenu (GTK_MENU_ITEM (item), newmenu);
|
||||
gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem), newmenu);
|
||||
|
||||
// XXX add aMenuItem to internal data structor list
|
||||
//NS_IF_ADDREF(aMenu);
|
||||
//mMenuItemVoidArray.AppendElement(aMenu);
|
||||
//mNumMenuItems++;
|
||||
|
||||
NS_RELEASE(pnsMenuItem);
|
||||
return NS_OK;
|
||||
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
NS_METHOD nsMenu::AddSeparator()
|
||||
{
|
||||
GtkWidget *widget;
|
||||
widget = gtk_menu_item_new ();
|
||||
gtk_widget_show(widget);
|
||||
gtk_menu_shell_append (GTK_MENU_SHELL (mMenu), widget);
|
||||
//GtkWidget *widget;
|
||||
//widget = gtk_menu_item_new ();
|
||||
//gtk_widget_show(widget);
|
||||
//gtk_menu_shell_append (GTK_MENU_SHELL (mMenu), widget);
|
||||
|
||||
// Create nsMenuItem
|
||||
nsIMenuItem * pnsMenuItem = nsnull;
|
||||
nsresult rv = nsComponentManager::CreateInstance(
|
||||
kMenuItemCID, nsnull, kIMenuItemIID, (void**)&pnsMenuItem);
|
||||
if (NS_OK == rv) {
|
||||
// This is gross and I'll make it go away ASAP -cps
|
||||
nsString tmp = "separator";
|
||||
pnsMenuItem->Create(this, tmp, 0);
|
||||
nsISupports * supports = nsnull;
|
||||
pnsMenuItem->QueryInterface(kISupportsIID, (void**) &supports);
|
||||
AddItem(supports); // Parent should now own menu item
|
||||
NS_RELEASE(supports);
|
||||
|
||||
//NS_RELEASE(pnsMenuItem);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -261,12 +323,49 @@ NS_METHOD nsMenu::InsertSeparator(const PRUint32 aPos)
|
|||
//-------------------------------------------------------------------------
|
||||
NS_METHOD nsMenu::RemoveItem(const PRUint32 aPos)
|
||||
{
|
||||
|
||||
|
||||
//gtk_menu_shell_remove (GTK_MENU_SHELL (mMenu), item);
|
||||
|
||||
//delete[] labelStr;
|
||||
|
||||
//voidData = NULL;
|
||||
|
||||
//aMenu->GetNativeData(&voidData);
|
||||
//newmenu = GTK_WIDGET(voidData);
|
||||
|
||||
//gtk_menu_item_remove_submenu (GTK_MENU_ITEM (item));
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
NS_METHOD nsMenu::RemoveAll()
|
||||
{
|
||||
for (int i = mMenuItemVoidArray.Count(); i > 0; i--) {
|
||||
if(nsnull != mMenuItemVoidArray[i-1]) {
|
||||
nsIMenuItem * menuitem = nsnull;
|
||||
((nsISupports*)mMenuItemVoidArray[i-1])->QueryInterface(kIMenuItemIID, (void**)&menuitem);
|
||||
if(menuitem) {
|
||||
void * gtkmenuitem = nsnull;
|
||||
menuitem->GetNativeData(gtkmenuitem);
|
||||
if(gtkmenuitem){
|
||||
gtk_container_remove (GTK_CONTAINER (mMenu), GTK_WIDGET(gtkmenuitem) );
|
||||
}
|
||||
}else{
|
||||
nsIMenu * menu= nsnull;
|
||||
((nsISupports*)mMenuItemVoidArray[i-1])->QueryInterface(kIMenuIID, (void**)&menu);
|
||||
if(menu){
|
||||
void * gtkmenu = nsnull;
|
||||
menu->GetNativeData(>kmenu);
|
||||
if(gtkmenu){
|
||||
g_print("gtkmenu removed");
|
||||
|
||||
//gtk_menu_item_remove_submenu (GTK_MENU_ITEM (item));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -340,20 +439,55 @@ nsEventStatus nsMenu::MenuConstruct(
|
|||
const nsMenuEvent & aMenuEvent,
|
||||
nsIWidget * aParentWindow,
|
||||
void * menuNode,
|
||||
void * aWebShell)
|
||||
void * aWebShell)
|
||||
{
|
||||
if (nsnull != mListener) {
|
||||
mListener->MenuDeselected(aMenuEvent);
|
||||
g_print("nsMenu::MenuConstruct called \n");
|
||||
if(menuNode){
|
||||
SetDOMNode((nsIDOMNode*)menuNode);
|
||||
}
|
||||
|
||||
if(!aWebShell){
|
||||
aWebShell = mWebShell;
|
||||
}
|
||||
|
||||
printf("nsMenu::MenuConstruct called \n");
|
||||
// Begin menuitem inner loop
|
||||
nsCOMPtr<nsIDOMNode> menuitemNode;
|
||||
((nsIDOMNode*)mDOMNode)->GetFirstChild(getter_AddRefs(menuitemNode));
|
||||
|
||||
unsigned short menuIndex = 0;
|
||||
|
||||
while (menuitemNode) {
|
||||
nsCOMPtr<nsIDOMElement> menuitemElement(do_QueryInterface(menuitemNode));
|
||||
if (menuitemElement) {
|
||||
nsString menuitemNodeType;
|
||||
nsString menuitemName;
|
||||
menuitemElement->GetNodeName(menuitemNodeType);
|
||||
if (menuitemNodeType.Equals("menuitem")) {
|
||||
// LoadMenuItem
|
||||
LoadMenuItem(this, menuitemElement, menuitemNode, menuIndex, (nsIWebShell*)aWebShell);
|
||||
} else if (menuitemNodeType.Equals("separator")) {
|
||||
AddSeparator();
|
||||
} else if (menuitemNodeType.Equals("menu")) {
|
||||
// Load a submenu
|
||||
LoadSubMenu(this, menuitemElement, menuitemNode);
|
||||
}
|
||||
}
|
||||
|
||||
++menuIndex;
|
||||
|
||||
nsCOMPtr<nsIDOMNode> oldmenuitemNode(menuitemNode);
|
||||
oldmenuitemNode->GetNextSibling(getter_AddRefs(menuitemNode));
|
||||
} // end menu item innner loop
|
||||
return nsEventStatus_eIgnore;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
nsEventStatus nsMenu::MenuDestruct(const nsMenuEvent & aMenuEvent)
|
||||
{
|
||||
if (nsnull != mListener) {
|
||||
mListener->MenuDeselected(aMenuEvent);
|
||||
}
|
||||
g_print("nsMenu::MenuDestruct called \n");
|
||||
mConstructCalled = false;
|
||||
RemoveAll();
|
||||
return nsEventStatus_eIgnore;
|
||||
}
|
||||
|
||||
|
@ -364,7 +498,10 @@ nsEventStatus nsMenu::MenuDestruct(const nsMenuEvent & aMenuEvent)
|
|||
*/
|
||||
NS_METHOD nsMenu::SetDOMNode(nsIDOMNode * aMenuNode)
|
||||
{
|
||||
return NS_OK;
|
||||
NS_IF_RELEASE(mDOMNode);
|
||||
mDOMNode = aMenuNode;
|
||||
NS_IF_ADDREF(mDOMNode);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
|
@ -374,7 +511,10 @@ NS_METHOD nsMenu::SetDOMNode(nsIDOMNode * aMenuNode)
|
|||
*/
|
||||
NS_METHOD nsMenu::SetDOMElement(nsIDOMElement * aMenuElement)
|
||||
{
|
||||
return NS_OK;
|
||||
NS_IF_RELEASE(mDOMElement);
|
||||
mDOMElement = aMenuElement;
|
||||
NS_IF_ADDREF(mDOMElement);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
|
@ -384,6 +524,131 @@ NS_METHOD nsMenu::SetDOMElement(nsIDOMElement * aMenuElement)
|
|||
*/
|
||||
NS_METHOD nsMenu::SetWebShell(nsIWebShell * aWebShell)
|
||||
{
|
||||
return NS_OK;
|
||||
NS_IF_RELEASE(mWebShell);
|
||||
mWebShell = aWebShell;
|
||||
NS_IF_ADDREF(mWebShell);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
//----------------------------------------
|
||||
void nsMenu::LoadMenuItem(
|
||||
nsIMenu * pParentMenu,
|
||||
nsIDOMElement * menuitemElement,
|
||||
nsIDOMNode * menuitemNode,
|
||||
unsigned short menuitemIndex,
|
||||
nsIWebShell * aWebShell)
|
||||
{
|
||||
static const char* NS_STRING_TRUE = "true";
|
||||
nsString disabled;
|
||||
nsString menuitemName;
|
||||
nsString menuitemCmd;
|
||||
|
||||
menuitemElement->GetAttribute(nsAutoString("disabled"), disabled);
|
||||
menuitemElement->GetAttribute(nsAutoString("name"), menuitemName);
|
||||
menuitemElement->GetAttribute(nsAutoString("cmd"), menuitemCmd);
|
||||
// Create nsMenuItem
|
||||
nsIMenuItem * pnsMenuItem = nsnull;
|
||||
nsresult rv = nsComponentManager::CreateInstance(kMenuItemCID, nsnull, kIMenuItemIID, (void**)&pnsMenuItem);
|
||||
if (NS_OK == rv) {
|
||||
pnsMenuItem->Create(pParentMenu, menuitemName, 0);
|
||||
nsISupports * supports = nsnull;
|
||||
pnsMenuItem->QueryInterface(kISupportsIID, (void**) &supports);
|
||||
pParentMenu->AddItem(supports); // Parent should now own menu item
|
||||
|
||||
NS_RELEASE(supports);
|
||||
|
||||
// Create MenuDelegate - this is the intermediator inbetween
|
||||
// the DOM node and the nsIMenuItem
|
||||
// The nsWebShellWindow wacthes for Document changes and then notifies the
|
||||
// the appropriate nsMenuDelegate object
|
||||
nsCOMPtr<nsIDOMElement> domElement(do_QueryInterface(menuitemNode));
|
||||
if (!domElement) {
|
||||
//return NS_ERROR_FAILURE;
|
||||
return;
|
||||
}
|
||||
|
||||
nsAutoString cmdAtom("onclick");
|
||||
nsString cmdName;
|
||||
|
||||
domElement->GetAttribute(cmdAtom, cmdName);
|
||||
|
||||
pnsMenuItem->SetCommand(cmdName);
|
||||
// DO NOT use passed in wehshell because of messed up windows dynamic loading
|
||||
// code.
|
||||
pnsMenuItem->SetWebShell(mWebShell);
|
||||
pnsMenuItem->SetDOMElement(domElement);
|
||||
|
||||
if(disabled == NS_STRING_TRUE )
|
||||
//::EnableMenuItem(mMenu, menuitemIndex, MF_BYPOSITION | MF_GRAYED);
|
||||
|
||||
NS_RELEASE(pnsMenuItem);
|
||||
|
||||
}
|
||||
//return NS_OK;
|
||||
return;
|
||||
}
|
||||
|
||||
//----------------------------------------
|
||||
void nsMenu::LoadSubMenu(
|
||||
nsIMenu * pParentMenu,
|
||||
nsIDOMElement * menuElement,
|
||||
nsIDOMNode * menuNode)
|
||||
{
|
||||
nsString menuName;
|
||||
menuElement->GetAttribute(nsAutoString("name"), menuName);
|
||||
//printf("Creating Menu [%s] \n", menuName.ToNewCString()); // this leaks
|
||||
|
||||
// Create nsMenu
|
||||
nsIMenu * pnsMenu = nsnull;
|
||||
nsresult rv = nsComponentManager::CreateInstance(kMenuCID, nsnull, kIMenuIID, (void**)&pnsMenu);
|
||||
if (NS_OK == rv) {
|
||||
// Call Create
|
||||
nsISupports * supports = nsnull;
|
||||
pParentMenu->QueryInterface(kISupportsIID, (void**) &supports);
|
||||
pnsMenu->Create(supports, menuName);
|
||||
NS_RELEASE(supports); // Balance QI
|
||||
|
||||
// Set nsMenu Name
|
||||
pnsMenu->SetLabel(menuName);
|
||||
// Make nsMenu a child of parent nsMenu
|
||||
//pParentMenu->AddMenu(pnsMenu);
|
||||
supports = nsnull;
|
||||
pnsMenu->QueryInterface(kISupportsIID, (void**) &supports);
|
||||
pParentMenu->AddItem(supports);
|
||||
NS_RELEASE(supports);
|
||||
|
||||
NS_ASSERTION(mWebShell, "get debugger");
|
||||
pnsMenu->SetWebShell(mWebShell);
|
||||
pnsMenu->SetDOMNode(menuNode);
|
||||
|
||||
// Begin menuitem inner loop
|
||||
unsigned short menuIndex = 0;
|
||||
|
||||
nsCOMPtr<nsIDOMNode> menuitemNode;
|
||||
menuNode->GetFirstChild(getter_AddRefs(menuitemNode));
|
||||
while (menuitemNode) {
|
||||
nsCOMPtr<nsIDOMElement> menuitemElement(do_QueryInterface(menuitemNode));
|
||||
if (menuitemElement) {
|
||||
nsString menuitemNodeType;
|
||||
menuitemElement->GetNodeName(menuitemNodeType);
|
||||
|
||||
#ifdef DEBUG_saari
|
||||
printf("Type [%s] %d\n", menuitemNodeType.ToNewCString(), menuitemNodeType.Equals("separator"));
|
||||
#endif
|
||||
|
||||
if (menuitemNodeType.Equals("menuitem")) {
|
||||
// Load a menuitem
|
||||
LoadMenuItem(pnsMenu, menuitemElement, menuitemNode, menuIndex, mWebShell);
|
||||
} else if (menuitemNodeType.Equals("separator")) {
|
||||
pnsMenu->AddSeparator();
|
||||
} else if (menuitemNodeType.Equals("menu")) {
|
||||
// Add a submenu
|
||||
LoadSubMenu(pnsMenu, menuitemElement, menuitemNode);
|
||||
}
|
||||
}
|
||||
++menuIndex;
|
||||
nsCOMPtr<nsIDOMNode> oldmenuitemNode(menuitemNode);
|
||||
oldmenuitemNode->GetNextSibling(getter_AddRefs(menuitemNode));
|
||||
} // end menu item innner loop
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,6 +26,10 @@
|
|||
class nsIMenuBar;
|
||||
class nsIMenuListener;
|
||||
|
||||
#include "nsIDOMNode.h"
|
||||
#include "nsIDOMElement.h"
|
||||
#include "nsIWebShell.h"
|
||||
|
||||
/**
|
||||
* Native GTK+ Menu wrapper
|
||||
*/
|
||||
|
@ -75,16 +79,35 @@ public:
|
|||
NS_IMETHOD SetWebShell(nsIWebShell * aWebShell);
|
||||
|
||||
protected:
|
||||
void LoadMenuItem(
|
||||
nsIMenu * pParentMenu,
|
||||
nsIDOMElement * menuitemElement,
|
||||
nsIDOMNode * menuitemNode,
|
||||
unsigned short menuitemIndex,
|
||||
nsIWebShell * aWebShell);
|
||||
|
||||
void LoadSubMenu(
|
||||
nsIMenu * pParentMenu,
|
||||
nsIDOMElement * menuElement,
|
||||
nsIDOMNode * menuNode);
|
||||
|
||||
void Create(GtkWidget *aParent, const nsString &aLabel);
|
||||
GtkWidget *GetNativeParent();
|
||||
|
||||
nsString mLabel;
|
||||
PRUint32 mNumMenuItems;
|
||||
GtkWidget *mMenu;
|
||||
|
||||
nsVoidArray mMenuItemVoidArray;
|
||||
|
||||
nsIMenu *mMenuParent;
|
||||
nsIMenuBar *mMenuBarParent;
|
||||
nsIMenuListener * mListener;
|
||||
|
||||
bool mConstructCalled;
|
||||
nsIDOMNode * mDOMNode;
|
||||
nsIWebShell * mWebShell;
|
||||
nsIDOMElement * mDOMElement;
|
||||
};
|
||||
|
||||
#endif // nsMenu_h__
|
||||
|
|
|
@ -25,7 +25,18 @@
|
|||
#include "nsString.h"
|
||||
#include "nsStringUtil.h"
|
||||
|
||||
#include "nsGtkEventHandler.h"
|
||||
|
||||
#include "nsIComponentManager.h"
|
||||
#include "nsCOMPtr.h"
|
||||
|
||||
#include "nsWidgetsCID.h"
|
||||
static NS_DEFINE_IID(kMenuBarCID, NS_MENUBAR_CID);
|
||||
static NS_DEFINE_IID(kMenuCID, NS_MENU_CID);
|
||||
static NS_DEFINE_IID(kMenuItemCID, NS_MENUITEM_CID);
|
||||
|
||||
static NS_DEFINE_IID(kIMenuBarIID, NS_IMENUBAR_IID);
|
||||
static NS_DEFINE_IID(kIMenuIID, NS_IMENU_IID);
|
||||
static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID);
|
||||
//NS_IMPL_ISUPPORTS(nsMenuBar, kMenuBarIID)
|
||||
|
||||
|
@ -70,6 +81,8 @@ nsMenuBar::nsMenuBar() : nsIMenuBar(), nsIMenuListener()
|
|||
mMenuBar = nsnull;
|
||||
mParent = nsnull;
|
||||
mIsMenuBarAdded = PR_FALSE;
|
||||
mWebShell = nsnull;
|
||||
mDOMNode = nsnull;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
|
@ -91,8 +104,10 @@ NS_METHOD nsMenuBar::Create(nsIWidget *aParent)
|
|||
{
|
||||
SetParent(aParent);
|
||||
mMenuBar = gtk_menu_bar_new();
|
||||
|
||||
mParent->SetMenuBar(this);
|
||||
gtk_widget_show(mMenuBar);
|
||||
|
||||
return NS_OK;
|
||||
|
||||
}
|
||||
|
@ -215,9 +230,80 @@ nsEventStatus nsMenuBar::MenuDeselected(const nsMenuEvent & aMenuEvent)
|
|||
nsEventStatus nsMenuBar::MenuConstruct(
|
||||
const nsMenuEvent & aMenuEvent,
|
||||
nsIWidget * aParentWindow,
|
||||
void * menuNode,
|
||||
void * aWebShell)
|
||||
void * menubarNode,
|
||||
void * aWebShell)
|
||||
{
|
||||
mWebShell = (nsIWebShell*) aWebShell;
|
||||
mDOMNode = (nsIDOMNode*)menubarNode;
|
||||
|
||||
nsIMenuBar * pnsMenuBar = nsnull;
|
||||
nsresult rv = nsComponentManager::CreateInstance(kMenuBarCID, nsnull, kIMenuBarIID, (void**)&pnsMenuBar);
|
||||
if (NS_OK == rv) {
|
||||
if (nsnull != pnsMenuBar) {
|
||||
pnsMenuBar->Create(aParentWindow);
|
||||
|
||||
// set pnsMenuBar as a nsMenuListener on aParentWindow
|
||||
nsCOMPtr<nsIMenuListener> menuListener;
|
||||
pnsMenuBar->QueryInterface(kIMenuListenerIID, getter_AddRefs(menuListener));
|
||||
aParentWindow->AddMenuListener(menuListener);
|
||||
|
||||
nsCOMPtr<nsIDOMNode> menuNode;
|
||||
((nsIDOMNode*)menubarNode)->GetFirstChild(getter_AddRefs(menuNode));
|
||||
while (menuNode) {
|
||||
nsCOMPtr<nsIDOMElement> menuElement(do_QueryInterface(menuNode));
|
||||
if (menuElement) {
|
||||
nsString menuNodeType;
|
||||
nsString menuName;
|
||||
menuElement->GetNodeName(menuNodeType);
|
||||
if (menuNodeType.Equals("menu")) {
|
||||
menuElement->GetAttribute(nsAutoString("name"), menuName);
|
||||
// Don't create the menu yet, just add in the top level names
|
||||
|
||||
// Create nsMenu
|
||||
nsIMenu * pnsMenu = nsnull;
|
||||
rv = nsComponentManager::CreateInstance(kMenuCID, nsnull, kIMenuIID, (void**)&pnsMenu);
|
||||
if (NS_OK == rv) {
|
||||
// Call Create
|
||||
nsISupports * supports = nsnull;
|
||||
pnsMenuBar->QueryInterface(kISupportsIID, (void**) &supports);
|
||||
pnsMenu->Create(supports, menuName);
|
||||
NS_RELEASE(supports);
|
||||
|
||||
pnsMenu->SetDOMNode(menuNode);
|
||||
pnsMenu->SetDOMElement(menuElement);
|
||||
|
||||
// Set nsMenu Name
|
||||
pnsMenu->SetLabel(menuName);
|
||||
// Make nsMenu a child of nsMenuBar
|
||||
pnsMenuBar->AddMenu(pnsMenu);
|
||||
// Set the WebShell
|
||||
pnsMenu->SetWebShell(mWebShell);
|
||||
|
||||
// Release the menu now that the menubar owns it
|
||||
//NS_RELEASE(pnsMenu);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
nsCOMPtr<nsIDOMNode> oldmenuNode(menuNode);
|
||||
oldmenuNode->GetNextSibling(getter_AddRefs(menuNode));
|
||||
} // end while (nsnull != menuNode)
|
||||
|
||||
// Give the aParentWindow this nsMenuBar to hold onto.
|
||||
aParentWindow->SetMenuBar(pnsMenuBar);
|
||||
|
||||
// HACK: force a paint for now
|
||||
pnsMenuBar->Paint();
|
||||
|
||||
// HACK for M4, should be removed by M5
|
||||
#ifdef XP_MAC
|
||||
Handle tempMenuBar = ::GetMenuBar(); // Get a copy of the menu list
|
||||
pnsMenuBar->SetNativeData((void*)tempMenuBar);
|
||||
#endif
|
||||
} // end if ( nsnull != pnsMenuBar )
|
||||
}
|
||||
|
||||
return nsEventStatus_eIgnore;
|
||||
return nsEventStatus_eIgnore;
|
||||
}
|
||||
|
||||
|
|
|
@ -23,6 +23,9 @@
|
|||
#include "nsIMenuListener.h"
|
||||
#include "nsVoidArray.h"
|
||||
|
||||
#include "nsIWebShell.h"
|
||||
#include "nsIDOMNode.h"
|
||||
|
||||
class nsIWidget;
|
||||
|
||||
/**
|
||||
|
@ -69,6 +72,9 @@ protected:
|
|||
GtkWidget *mMenuBar;
|
||||
nsIWidget *mParent;
|
||||
PRBool mIsMenuBarAdded;
|
||||
|
||||
nsIWebShell * mWebShell;
|
||||
nsIDOMNode * mDOMNode;
|
||||
};
|
||||
|
||||
#endif // nsMenuBar_h__
|
||||
|
|
|
@ -28,6 +28,14 @@
|
|||
|
||||
#include "nsIPopUpMenu.h"
|
||||
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsIContentViewerContainer.h"
|
||||
#include "nsIContentViewer.h"
|
||||
#include "nsIDocumentViewer.h"
|
||||
#include "nsIPresContext.h"
|
||||
#include "nsIContent.h"
|
||||
#include "nsIWebShell.h"
|
||||
|
||||
static NS_DEFINE_IID(kIMenuIID, NS_IMENU_IID);
|
||||
static NS_DEFINE_IID(kIMenuBarIID, NS_IMENUBAR_IID);
|
||||
static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID);
|
||||
|
@ -78,7 +86,9 @@ nsMenuItem::nsMenuItem() : nsIMenuItem()
|
|||
mPopUpParent = nsnull;
|
||||
mTarget = nsnull;
|
||||
mXULCommandListener = nsnull;
|
||||
mIsSeparator = PR_FALSE;
|
||||
mIsSeparator = false;
|
||||
mWebShell = nsnull;
|
||||
mDOMElement = nsnull;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
|
@ -109,7 +119,13 @@ void nsMenuItem::Create(nsIWidget *aMBParent,
|
|||
|
||||
mTarget = aMBParent;
|
||||
char * nameStr = mLabel.ToNewCString();
|
||||
mMenuItem = gtk_menu_item_new_with_label(nameStr);
|
||||
if(!strcmp(nameStr, "separator")) {
|
||||
mIsSeparator = true;
|
||||
mMenuItem = gtk_menu_item_new();
|
||||
}else{
|
||||
mIsSeparator = false;
|
||||
mMenuItem = gtk_menu_item_new_with_label(nameStr);
|
||||
}
|
||||
gtk_widget_show(mMenuItem);
|
||||
|
||||
gtk_signal_connect (GTK_OBJECT (mMenuItem), "activate",
|
||||
|
@ -323,13 +339,15 @@ NS_METHOD nsMenuItem::IsSeparator(PRBool & aIsSep)
|
|||
//-------------------------------------------------------------------------
|
||||
nsEventStatus nsMenuItem::MenuItemSelected(const nsMenuEvent & aMenuEvent)
|
||||
{
|
||||
if(mXULCommandListener)
|
||||
return mXULCommandListener->MenuSelected(aMenuEvent);
|
||||
|
||||
g_print("nsMenuItem::MenuSelected\n");
|
||||
if(!mIsSeparator) {
|
||||
g_print("nsMenuItem::MenuItemSelected\n");
|
||||
DoCommand();
|
||||
}else{
|
||||
g_print("nsMenuItem::MenuItemSelected is separator\n");
|
||||
}
|
||||
return nsEventStatus_eIgnore;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
nsEventStatus nsMenuItem::MenuSelected(const nsMenuEvent & aMenuEvent)
|
||||
{
|
||||
if(mXULCommandListener)
|
||||
|
@ -338,13 +356,13 @@ nsEventStatus nsMenuItem::MenuSelected(const nsMenuEvent & aMenuEvent)
|
|||
g_print("nsMenuItem::MenuSelected\n");
|
||||
return nsEventStatus_eIgnore;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
nsEventStatus nsMenuItem::MenuDeselected(const nsMenuEvent & aMenuEvent)
|
||||
{
|
||||
g_print("nsMenuItem::MenuDeselected\n");
|
||||
return nsEventStatus_eIgnore;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
nsEventStatus nsMenuItem::MenuConstruct(
|
||||
const nsMenuEvent & aMenuEvent,
|
||||
nsIWidget * aParentWindow,
|
||||
|
@ -354,7 +372,7 @@ nsEventStatus nsMenuItem::MenuConstruct(
|
|||
g_print("nsMenuItem::MenuConstruct\n");
|
||||
return nsEventStatus_eIgnore;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
nsEventStatus nsMenuItem::MenuDestruct(const nsMenuEvent & aMenuEvent)
|
||||
{
|
||||
g_print("nsMenuItem::MenuDestruct\n");
|
||||
|
@ -379,24 +397,76 @@ NS_METHOD nsMenuItem::SetCommand(const nsString & aStrCmd)
|
|||
*/
|
||||
NS_METHOD nsMenuItem::DoCommand()
|
||||
{
|
||||
return NS_OK;
|
||||
nsresult rv = NS_ERROR_FAILURE;
|
||||
|
||||
if(!mWebShell || !mDOMElement)
|
||||
return rv;
|
||||
|
||||
nsCOMPtr<nsIContentViewerContainer> contentViewerContainer;
|
||||
contentViewerContainer = do_QueryInterface(mWebShell);
|
||||
if (!contentViewerContainer) {
|
||||
NS_ERROR("Webshell doesn't support the content viewer container interface");
|
||||
g_print("Webshell doesn't support the content viewer container interface");
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIContentViewer> contentViewer;
|
||||
if (NS_FAILED(rv = contentViewerContainer->GetContentViewer(getter_AddRefs(contentViewer)))) {
|
||||
NS_ERROR("Unable to retrieve content viewer.");
|
||||
g_print("Unable to retrieve content viewer.");
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDocumentViewer> docViewer;
|
||||
docViewer = do_QueryInterface(contentViewer);
|
||||
if (!docViewer) {
|
||||
NS_ERROR("Document viewer interface not supported by the content viewer.");
|
||||
g_print("Document viewer interface not supported by the content viewer.");
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIPresContext> presContext;
|
||||
if (NS_FAILED(rv = docViewer->GetPresContext(*getter_AddRefs(presContext)))) {
|
||||
NS_ERROR("Unable to retrieve the doc viewer's presentation context.");
|
||||
g_print("Unable to retrieve the doc viewer's presentation context.");
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsEventStatus status = nsEventStatus_eIgnore;
|
||||
nsMouseEvent event;
|
||||
event.eventStructType = NS_MOUSE_EVENT;
|
||||
event.message = NS_MOUSE_LEFT_CLICK;
|
||||
|
||||
nsCOMPtr<nsIContent> contentNode;
|
||||
contentNode = do_QueryInterface(mDOMElement);
|
||||
if (!contentNode) {
|
||||
NS_ERROR("DOM Node doesn't support the nsIContent interface required to handle DOM events.");
|
||||
g_print("DOM Node doesn't support the nsIContent interface required to handle DOM events.");
|
||||
return rv;
|
||||
}
|
||||
|
||||
rv = contentNode->HandleDOMEvent(*presContext, &event, nsnull, NS_EVENT_FLAG_INIT, status);
|
||||
g_print("HandleDOMEvent called");
|
||||
return rv;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
NS_METHOD nsMenuItem::SetDOMElement(nsIDOMElement * aDOMElement)
|
||||
{
|
||||
return NS_OK;
|
||||
mDOMElement = aDOMElement;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
NS_METHOD nsMenuItem::GetDOMElement(nsIDOMElement ** aDOMElement)
|
||||
{
|
||||
return NS_OK;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
NS_METHOD nsMenuItem::SetWebShell(nsIWebShell * aWebShell)
|
||||
{
|
||||
return NS_OK;
|
||||
mWebShell = aWebShell;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -23,6 +23,9 @@
|
|||
#include "nsString.h"
|
||||
#include "nsIMenuListener.h"
|
||||
|
||||
#include "nsIDOMElement.h"
|
||||
#include "nsIWebShell.h"
|
||||
|
||||
class nsIMenu;
|
||||
class nsIPopUpMenu;
|
||||
class nsIWidget;
|
||||
|
@ -96,8 +99,10 @@ protected:
|
|||
nsIWidget *mTarget;
|
||||
|
||||
GtkWidget *mMenuItem; // native cascade widget
|
||||
PRBool mIsSeparator;
|
||||
bool mIsSeparator;
|
||||
|
||||
nsIWebShell * mWebShell;
|
||||
nsIDOMElement * mDOMElement;
|
||||
};
|
||||
|
||||
#endif // nsMenuItem_h__
|
||||
|
|
Загрузка…
Ссылка в новой задаче