зеркало из https://github.com/mozilla/pjs.git
Improvements to XP menus.
This commit is contained in:
Родитель
b5800eb036
Коммит
c993598be9
|
@ -57,7 +57,34 @@ NS_NewMenuBarFrame(nsIFrame** aNewFrame)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP_(nsrefcnt)
|
||||
nsMenuBarFrame::AddRef(void)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP_(nsrefcnt)
|
||||
nsMenuBarFrame::Release(void)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsMenuBarFrame::QueryInterface(REFNSIID aIID, void** aInstancePtr)
|
||||
{
|
||||
if (NULL == aInstancePtr) {
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
}
|
||||
|
||||
*aInstancePtr = NULL;
|
||||
|
||||
if (aIID.Equals(nsIMenuParent::GetIID())) {
|
||||
*aInstancePtr = (void*)(nsIMenuParent*) this;
|
||||
NS_ADDREF_THIS();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
return nsBoxFrame::QueryInterface(aIID, aInstancePtr);
|
||||
}
|
||||
//
|
||||
// nsMenuBarFrame cntr
|
||||
//
|
||||
|
@ -101,7 +128,7 @@ nsMenuBarFrame::Init(nsIPresContext& aPresContext,
|
|||
void
|
||||
nsMenuBarFrame::ToggleMenuActiveState()
|
||||
{
|
||||
if (IsActive()) {
|
||||
if (mIsActive) {
|
||||
// Deactivate the menu bar
|
||||
mIsActive = PR_FALSE;
|
||||
if (mCurrentMenu) {
|
||||
|
@ -152,7 +179,7 @@ nsMenuBarFrame::KeyboardNavigation(PRUint32 aDirection)
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
NS_IMETHODIMP
|
||||
nsMenuBarFrame::GetNextMenuItem(nsIContent* aStart, nsIContent** aResult)
|
||||
{
|
||||
PRInt32 index = 0;
|
||||
|
@ -177,7 +204,7 @@ nsMenuBarFrame::GetNextMenuItem(nsIContent* aStart, nsIContent** aResult)
|
|||
if (tag.get() == nsXULAtoms::xpmenu) {
|
||||
*aResult = current;
|
||||
NS_IF_ADDREF(*aResult);
|
||||
return;
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -192,16 +219,18 @@ nsMenuBarFrame::GetNextMenuItem(nsIContent* aStart, nsIContent** aResult)
|
|||
if (tag.get() == nsXULAtoms::xpmenu) {
|
||||
*aResult = current;
|
||||
NS_IF_ADDREF(*aResult);
|
||||
return;
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
|
||||
// No luck. Just return our start value.
|
||||
*aResult = aStart;
|
||||
NS_IF_ADDREF(aStart);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
NS_IMETHODIMP
|
||||
nsMenuBarFrame::GetPreviousMenuItem(nsIContent* aStart, nsIContent** aResult)
|
||||
{
|
||||
PRInt32 count;
|
||||
|
@ -227,7 +256,7 @@ nsMenuBarFrame::GetPreviousMenuItem(nsIContent* aStart, nsIContent** aResult)
|
|||
if (tag.get() == nsXULAtoms::xpmenu) {
|
||||
*aResult = current;
|
||||
NS_IF_ADDREF(*aResult);
|
||||
return;
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -242,19 +271,21 @@ nsMenuBarFrame::GetPreviousMenuItem(nsIContent* aStart, nsIContent** aResult)
|
|||
if (tag.get() == nsXULAtoms::xpmenu) {
|
||||
*aResult = current;
|
||||
NS_IF_ADDREF(*aResult);
|
||||
return;
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
|
||||
// No luck. Just return our start value.
|
||||
*aResult = aStart;
|
||||
NS_IF_ADDREF(aStart);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void nsMenuBarFrame::SetCurrentMenuItem(nsIContent* aMenuItem)
|
||||
NS_IMETHODIMP nsMenuBarFrame::SetCurrentMenuItem(nsIContent* aMenuItem)
|
||||
{
|
||||
if (mCurrentMenu == aMenuItem)
|
||||
return;
|
||||
return NS_OK;
|
||||
|
||||
// Unset the current child.
|
||||
if (mCurrentMenu)
|
||||
|
@ -264,4 +295,6 @@ void nsMenuBarFrame::SetCurrentMenuItem(nsIContent* aMenuItem)
|
|||
if (aMenuItem)
|
||||
aMenuItem->SetAttribute(kNameSpaceID_None, nsXULAtoms::menuactive, "true", PR_TRUE);
|
||||
mCurrentMenu = aMenuItem;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
|
|
@ -28,16 +28,26 @@
|
|||
#include "nsCOMPtr.h"
|
||||
#include "nsToolbarFrame.h"
|
||||
#include "nsMenuBarListener.h"
|
||||
#include "nsIMenuParent.h"
|
||||
|
||||
class nsIContent;
|
||||
|
||||
nsresult NS_NewMenuBarFrame(nsIFrame** aResult) ;
|
||||
|
||||
class nsMenuBarFrame : public nsToolbarFrame
|
||||
class nsMenuBarFrame : public nsToolbarFrame, public nsIMenuParent
|
||||
{
|
||||
public:
|
||||
nsMenuBarFrame();
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
// nsIMenuParentInterface
|
||||
NS_IMETHOD SetCurrentMenuItem(nsIContent* aMenuItem);
|
||||
NS_IMETHOD GetNextMenuItem(nsIContent* aStart, nsIContent** aResult);
|
||||
NS_IMETHOD GetPreviousMenuItem(nsIContent* aStart, nsIContent** aResult);
|
||||
|
||||
NS_IMETHOD IsActive() { return mIsActive; };
|
||||
|
||||
NS_IMETHOD Init(nsIPresContext& aPresContext,
|
||||
nsIContent* aContent,
|
||||
nsIFrame* aParent,
|
||||
|
@ -45,14 +55,9 @@ public:
|
|||
nsIFrame* aPrevInFlow);
|
||||
|
||||
// Non-interface helpers
|
||||
PRBool IsActive() { return mIsActive; };
|
||||
void ToggleMenuActiveState();
|
||||
void GetNextMenuItem(nsIContent* aStart, nsIContent** aResult);
|
||||
void GetPreviousMenuItem(nsIContent* aStart, nsIContent** aResult);
|
||||
void KeyboardNavigation(PRUint32 aDirection);
|
||||
|
||||
void SetCurrentMenuItem(nsIContent* aMenuItem);
|
||||
|
||||
protected:
|
||||
nsMenuBarListener* mMenuBarListener; // The listener that tells us about key and mouse events.
|
||||
PRBool mIsActive; // Whether or not the menu bar is active (a menu item is highlighted or shown).
|
||||
|
|
|
@ -74,21 +74,11 @@ nsMenuBarListener::QueryInterface(REFNSIID aIID, void** aInstancePtr)
|
|||
NS_ADDREF_THIS();
|
||||
return NS_OK;
|
||||
}
|
||||
if (aIID.Equals(nsCOMTypeInfo<nsIDOMMouseListener>::GetIID())) {
|
||||
*aInstancePtr = (void*)(nsIDOMMouseListener*)this;
|
||||
NS_ADDREF_THIS();
|
||||
return NS_OK;
|
||||
}
|
||||
if (aIID.Equals(nsCOMTypeInfo<nsIDOMKeyListener>::GetIID())) {
|
||||
*aInstancePtr = (void*)(nsIDOMKeyListener*)this;
|
||||
NS_ADDREF_THIS();
|
||||
return NS_OK;
|
||||
}
|
||||
if (aIID.Equals(nsCOMTypeInfo<nsIDOMMouseMotionListener>::GetIID())) {
|
||||
*aInstancePtr = (void*)(nsIDOMMouseMotionListener*)this;
|
||||
NS_ADDREF_THIS();
|
||||
return NS_OK;
|
||||
}
|
||||
if (aIID.Equals(nsCOMTypeInfo<nsISupports>::GetIID())) {
|
||||
*aInstancePtr = (void*)(nsISupports*)(nsIDOMMouseMotionListener*)this;
|
||||
NS_ADDREF_THIS();
|
||||
|
@ -96,7 +86,7 @@ nsMenuBarListener::QueryInterface(REFNSIID aIID, void** aInstancePtr)
|
|||
}
|
||||
return NS_NOINTERFACE;
|
||||
}
|
||||
|
||||
/*
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// This is temporary until the bubbling of events for CSS actions work
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
@ -121,13 +111,6 @@ static void ForceDrawFrame(nsIFrame * aFrame)
|
|||
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
nsresult
|
||||
nsMenuBarListener::HandleEvent(nsIDOMEvent* aEvent)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
nsresult
|
||||
|
@ -219,6 +202,7 @@ nsMenuBarListener::MouseOut(nsIDOMEvent* aMouseEvent)
|
|||
|
||||
return NS_OK;
|
||||
}
|
||||
*/
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
nsresult
|
||||
|
@ -236,7 +220,8 @@ nsMenuBarListener::KeyUp(nsIDOMEvent* aKeyEvent)
|
|||
mMenuBarFrame->ToggleMenuActiveState();
|
||||
}
|
||||
|
||||
if (mMenuBarFrame->IsActive())
|
||||
PRBool active = mMenuBarFrame->IsActive();
|
||||
if (active)
|
||||
return NS_ERROR_BASE; // I am consuming event
|
||||
return NS_OK; // means I am NOT consuming event
|
||||
}
|
||||
|
@ -245,6 +230,8 @@ nsMenuBarListener::KeyUp(nsIDOMEvent* aKeyEvent)
|
|||
nsresult
|
||||
nsMenuBarListener::KeyDown(nsIDOMEvent* aKeyEvent)
|
||||
{
|
||||
PRBool active = mMenuBarFrame->IsActive();
|
||||
|
||||
nsCOMPtr<nsIDOMUIEvent> theEvent = do_QueryInterface(aKeyEvent);
|
||||
PRUint32 theChar;
|
||||
theEvent->GetKeyCode(&theChar);
|
||||
|
@ -258,11 +245,11 @@ nsMenuBarListener::KeyDown(nsIDOMEvent* aKeyEvent)
|
|||
theChar == NS_VK_DOWN) {
|
||||
// The arrow keys were pressed. User is moving around within
|
||||
// the menus.
|
||||
if (mMenuBarFrame->IsActive())
|
||||
if (active)
|
||||
mMenuBarFrame->KeyboardNavigation(theChar);
|
||||
}
|
||||
|
||||
if (mMenuBarFrame->IsActive())
|
||||
if (active)
|
||||
return NS_ERROR_BASE; // I am consuming event
|
||||
return NS_OK; // means I am NOT consuming event
|
||||
}
|
||||
|
@ -279,7 +266,17 @@ nsMenuBarListener::KeyPress(nsIDOMEvent* aKeyEvent)
|
|||
PRBool isAlt = PR_FALSE;
|
||||
theEvent->GetAltKey(&isAlt);
|
||||
|
||||
if (mMenuBarFrame->IsActive())
|
||||
PRBool active = mMenuBarFrame->IsActive();
|
||||
if (active)
|
||||
return NS_ERROR_BASE; // I am consuming event
|
||||
return NS_OK; // means I am NOT consuming event
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
nsresult
|
||||
nsMenuBarListener::HandleEvent(nsIDOMEvent* aEvent)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -29,8 +29,7 @@ class nsIPresContext;
|
|||
|
||||
/** editor Implementation of the DragListener interface
|
||||
*/
|
||||
class nsMenuBarListener : public nsIDOMKeyListener, public nsIDOMMouseListener,
|
||||
public nsIDOMMouseMotionListener
|
||||
class nsMenuBarListener : public nsIDOMKeyListener
|
||||
{
|
||||
public:
|
||||
/** default constructor
|
||||
|
@ -41,14 +40,7 @@ public:
|
|||
virtual ~nsMenuBarListener();
|
||||
|
||||
virtual nsresult HandleEvent(nsIDOMEvent* aEvent);
|
||||
virtual nsresult MouseMove(nsIDOMEvent* aMouseEvent);
|
||||
virtual nsresult DragMove(nsIDOMEvent* aMouseEvent);
|
||||
virtual nsresult MouseDown(nsIDOMEvent* aMouseEvent);
|
||||
virtual nsresult MouseUp(nsIDOMEvent* aMouseEvent);
|
||||
virtual nsresult MouseClick(nsIDOMEvent* aMouseEvent);
|
||||
virtual nsresult MouseDblClick(nsIDOMEvent* aMouseEvent);
|
||||
virtual nsresult MouseOver(nsIDOMEvent* aMouseEvent);
|
||||
virtual nsresult MouseOut(nsIDOMEvent* aMouseEvent);
|
||||
|
||||
virtual nsresult KeyUp(nsIDOMEvent* aMouseEvent);
|
||||
virtual nsresult KeyDown(nsIDOMEvent* aMouseEvent);
|
||||
virtual nsresult KeyPress(nsIDOMEvent* aMouseEvent);
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
#include "nsINameSpaceManager.h"
|
||||
#include "nsLayoutAtoms.h"
|
||||
#include "nsMenuPopupFrame.h"
|
||||
#include "nsMenuBarFrame.h"
|
||||
|
||||
#define NS_MENU_POPUP_LIST_INDEX (NS_AREA_FRAME_ABSOLUTE_LIST_INDEX + 1)
|
||||
|
||||
|
@ -50,16 +51,51 @@ NS_NewMenuFrame(nsIFrame** aNewFrame)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP_(nsrefcnt)
|
||||
nsMenuFrame::AddRef(void)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP_(nsrefcnt)
|
||||
nsMenuFrame::Release(void)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsMenuFrame::QueryInterface(REFNSIID aIID, void** aInstancePtr)
|
||||
{
|
||||
if (NULL == aInstancePtr) {
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
}
|
||||
*aInstancePtr = NULL;
|
||||
return nsBoxFrame::QueryInterface(aIID, aInstancePtr);
|
||||
}
|
||||
|
||||
//
|
||||
// nsMenuFrame cntr
|
||||
//
|
||||
nsMenuFrame::nsMenuFrame()
|
||||
:mMenuOpen(PR_FALSE),mOnMenuBar(PR_TRUE)
|
||||
:mMenuOpen(PR_FALSE),mMenuParent(nsnull)
|
||||
{
|
||||
|
||||
} // cntr
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsMenuFrame::Init(nsIPresContext& aPresContext,
|
||||
nsIContent* aContent,
|
||||
nsIFrame* aParent,
|
||||
nsIStyleContext* aContext,
|
||||
nsIFrame* aPrevInFlow)
|
||||
{
|
||||
nsresult rv = nsBoxFrame::Init(aPresContext, aContent, aParent, aContext, aPrevInFlow);
|
||||
|
||||
// Set our menu parent.
|
||||
nsCOMPtr<nsIMenuParent> menuparent = do_QueryInterface(aParent);
|
||||
mMenuParent = menuparent.get();
|
||||
return rv;
|
||||
}
|
||||
|
||||
// The following methods are all overridden to ensure that the xpmenuchildren frame
|
||||
// is placed in the appropriate list.
|
||||
NS_IMETHODIMP
|
||||
|
@ -156,28 +192,67 @@ nsMenuFrame::HandleEvent(nsIPresContext& aPresContext,
|
|||
if (frame) {
|
||||
// We have children.
|
||||
nsMenuPopupFrame* popup = (nsMenuPopupFrame*)frame;
|
||||
popup->SyncViewWithFrame(mOnMenuBar);
|
||||
PRBool onMenuBar = PR_TRUE;
|
||||
popup->SyncViewWithFrame(onMenuBar);
|
||||
ToggleMenuState();
|
||||
}
|
||||
}
|
||||
else if (aEvent->message == NS_MOUSE_EXIT) {
|
||||
// Deactivate the menu.
|
||||
if (mMenuParent && !mMenuOpen)
|
||||
mMenuParent->SetCurrentMenuItem(nsnull);
|
||||
}
|
||||
else if (aEvent->message == NS_MOUSE_ENTER) {
|
||||
// Let the menu parent know we're the new item.
|
||||
if (mMenuParent)
|
||||
mMenuParent->SetCurrentMenuItem(mContent);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
nsMenuFrame::ToggleMenuState()
|
||||
{
|
||||
if (mMenuOpen) {
|
||||
OpenMenu(PR_FALSE);
|
||||
}
|
||||
else {
|
||||
OpenMenu(PR_TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsMenuFrame::SelectMenu(PRBool aActivateFlag)
|
||||
{
|
||||
if (aActivateFlag) {
|
||||
// Highlight the menu.
|
||||
mContent->SetAttribute(kNameSpaceID_None, nsXULAtoms::menuactive, "true", PR_TRUE);
|
||||
}
|
||||
else {
|
||||
// Unhighlight the menu.
|
||||
mContent->UnsetAttribute(kNameSpaceID_None, nsXULAtoms::menuactive, PR_TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsMenuFrame::OpenMenu(PRBool aActivateFlag)
|
||||
{
|
||||
nsCOMPtr<nsIContent> child;
|
||||
GetMenuChildrenElement(getter_AddRefs(child));
|
||||
|
||||
if (mMenuOpen) {
|
||||
// Close the menu.
|
||||
child->SetAttribute(kNameSpaceID_None, nsXULAtoms::menuactive, "false", PR_TRUE);
|
||||
mMenuOpen = PR_FALSE;
|
||||
|
||||
if (aActivateFlag) {
|
||||
// Open the menu.
|
||||
mContent->SetAttribute(kNameSpaceID_None, nsXULAtoms::open, "true", PR_TRUE);
|
||||
if (child)
|
||||
child->SetAttribute(kNameSpaceID_None, nsXULAtoms::menuactive, "true", PR_TRUE);
|
||||
mMenuOpen = PR_TRUE;
|
||||
}
|
||||
else {
|
||||
// Open the menu.
|
||||
child->SetAttribute(kNameSpaceID_None, nsXULAtoms::menuactive, "true", PR_TRUE);
|
||||
mMenuOpen = PR_TRUE;
|
||||
// Close the menu.
|
||||
mContent->UnsetAttribute(kNameSpaceID_None, nsXULAtoms::open, PR_TRUE);
|
||||
if (child)
|
||||
child->UnsetAttribute(kNameSpaceID_None, nsXULAtoms::menuactive, PR_TRUE);
|
||||
mMenuOpen = PR_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -29,15 +29,27 @@
|
|||
|
||||
#include "nsBoxFrame.h"
|
||||
#include "nsFrameList.h"
|
||||
#include "nsIMenuParent.h"
|
||||
|
||||
nsresult NS_NewMenuFrame(nsIFrame** aResult) ;
|
||||
|
||||
class nsMenuBarFrame;
|
||||
|
||||
class nsMenuFrame : public nsBoxFrame
|
||||
{
|
||||
public:
|
||||
nsMenuFrame();
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
NS_IMETHOD Init(nsIPresContext& aPresContext,
|
||||
nsIContent* aContent,
|
||||
nsIFrame* aParent,
|
||||
nsIStyleContext* aContext,
|
||||
nsIFrame* aPrevInFlow);
|
||||
|
||||
NS_IMETHOD IsActive(PRBool& aResult) { aResult = PR_TRUE; return NS_OK; };
|
||||
|
||||
// The following four methods are all overridden so that the menu children
|
||||
// can be stored in a separate list (so that they don't impact reflow of the
|
||||
// actual menu item at all).
|
||||
|
@ -65,6 +77,8 @@ public:
|
|||
nsReflowStatus& aStatus);
|
||||
|
||||
void ToggleMenuState();
|
||||
void SelectMenu(PRBool aActivateFlag);
|
||||
void OpenMenu(PRBool aActivateFlag);
|
||||
|
||||
protected:
|
||||
void GetMenuChildrenElement(nsIContent** aResult);
|
||||
|
@ -72,8 +86,8 @@ protected:
|
|||
protected:
|
||||
nsFrameList mPopupFrames;
|
||||
PRBool mMenuOpen;
|
||||
PRBool mOnMenuBar;
|
||||
|
||||
nsMenuBarFrame* mMenuBar;
|
||||
nsIMenuParent* mMenuParent; // Our parent menu.
|
||||
}; // class nsMenuFrame
|
||||
|
||||
#endif
|
||||
|
|
|
@ -52,11 +52,41 @@ NS_NewMenuPopupFrame(nsIFrame** aNewFrame)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP_(nsrefcnt)
|
||||
nsMenuPopupFrame::AddRef(void)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP_(nsrefcnt)
|
||||
nsMenuPopupFrame::Release(void)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsMenuPopupFrame::QueryInterface(REFNSIID aIID, void** aInstancePtr)
|
||||
{
|
||||
if (NULL == aInstancePtr) {
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
}
|
||||
|
||||
*aInstancePtr = NULL;
|
||||
|
||||
if (aIID.Equals(nsIMenuParent::GetIID())) {
|
||||
*aInstancePtr = (void*)(nsIMenuParent*) this;
|
||||
NS_ADDREF_THIS();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
return nsBoxFrame::QueryInterface(aIID, aInstancePtr);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// nsMenuPopupFrame cntr
|
||||
//
|
||||
nsMenuPopupFrame::nsMenuPopupFrame()
|
||||
:mCurrentMenu(nsnull)
|
||||
{
|
||||
|
||||
} // cntr
|
||||
|
@ -182,3 +212,123 @@ nsMenuPopupFrame::DidReflow(nsIPresContext& aPresContext,
|
|||
//SyncViewWithFrame();
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsMenuPopupFrame::GetNextMenuItem(nsIContent* aStart, nsIContent** aResult)
|
||||
{
|
||||
PRInt32 index = 0;
|
||||
if (aStart) {
|
||||
// Determine the index of start.
|
||||
mContent->IndexOf(aStart, index);
|
||||
index++;
|
||||
}
|
||||
|
||||
PRInt32 count;
|
||||
mContent->ChildCount(count);
|
||||
|
||||
// Begin the search from index.
|
||||
PRInt32 i;
|
||||
for (i = index; i < count; i++) {
|
||||
nsCOMPtr<nsIContent> current;
|
||||
mContent->ChildAt(i, *getter_AddRefs(current));
|
||||
|
||||
// See if it's a menu item.
|
||||
nsCOMPtr<nsIAtom> tag;
|
||||
current->GetTag(*getter_AddRefs(tag));
|
||||
if (tag.get() == nsXULAtoms::xpmenu) {
|
||||
*aResult = current;
|
||||
NS_IF_ADDREF(*aResult);
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
|
||||
// Still don't have anything. Try cycling from the beginning.
|
||||
for (i = 0; i <= index; i++) {
|
||||
nsCOMPtr<nsIContent> current;
|
||||
mContent->ChildAt(i, *getter_AddRefs(current));
|
||||
|
||||
// See if it's a menu item.
|
||||
nsCOMPtr<nsIAtom> tag;
|
||||
current->GetTag(*getter_AddRefs(tag));
|
||||
if (tag.get() == nsXULAtoms::xpmenu) {
|
||||
*aResult = current;
|
||||
NS_IF_ADDREF(*aResult);
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
|
||||
// No luck. Just return our start value.
|
||||
*aResult = aStart;
|
||||
NS_IF_ADDREF(aStart);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsMenuPopupFrame::GetPreviousMenuItem(nsIContent* aStart, nsIContent** aResult)
|
||||
{
|
||||
PRInt32 count;
|
||||
mContent->ChildCount(count);
|
||||
|
||||
PRInt32 index = count-1;
|
||||
if (aStart) {
|
||||
// Determine the index of start.
|
||||
mContent->IndexOf(aStart, index);
|
||||
index--;
|
||||
}
|
||||
|
||||
|
||||
// Begin the search from index.
|
||||
PRInt32 i;
|
||||
for (i = index; i >= 0; i--) {
|
||||
nsCOMPtr<nsIContent> current;
|
||||
mContent->ChildAt(i, *getter_AddRefs(current));
|
||||
|
||||
// See if it's a menu item.
|
||||
nsCOMPtr<nsIAtom> tag;
|
||||
current->GetTag(*getter_AddRefs(tag));
|
||||
if (tag.get() == nsXULAtoms::xpmenu) {
|
||||
*aResult = current;
|
||||
NS_IF_ADDREF(*aResult);
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
|
||||
// Still don't have anything. Try cycling from the beginning.
|
||||
for (i = count-1; i >= index; i--) {
|
||||
nsCOMPtr<nsIContent> current;
|
||||
mContent->ChildAt(i, *getter_AddRefs(current));
|
||||
|
||||
// See if it's a menu item.
|
||||
nsCOMPtr<nsIAtom> tag;
|
||||
current->GetTag(*getter_AddRefs(tag));
|
||||
if (tag.get() == nsXULAtoms::xpmenu) {
|
||||
*aResult = current;
|
||||
NS_IF_ADDREF(*aResult);
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
|
||||
// No luck. Just return our start value.
|
||||
*aResult = aStart;
|
||||
NS_IF_ADDREF(aStart);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsMenuPopupFrame::SetCurrentMenuItem(nsIContent* aMenuItem)
|
||||
{
|
||||
if (mCurrentMenu == aMenuItem)
|
||||
return NS_OK;
|
||||
|
||||
// Unset the current child.
|
||||
if (mCurrentMenu)
|
||||
mCurrentMenu->UnsetAttribute(kNameSpaceID_None, nsXULAtoms::menuactive, PR_TRUE);
|
||||
|
||||
// Set the new child.
|
||||
if (aMenuItem)
|
||||
aMenuItem->SetAttribute(kNameSpaceID_None, nsXULAtoms::menuactive, "true", PR_TRUE);
|
||||
mCurrentMenu = aMenuItem;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
|
|
@ -28,17 +28,26 @@
|
|||
#include "nsCOMPtr.h"
|
||||
|
||||
#include "nsBoxFrame.h"
|
||||
#include "nsIMenuParent.h"
|
||||
|
||||
nsresult NS_NewMenuPopupFrame(nsIFrame** aResult) ;
|
||||
|
||||
class nsIViewManager;
|
||||
class nsIView;
|
||||
|
||||
class nsMenuPopupFrame : public nsBoxFrame
|
||||
class nsMenuPopupFrame : public nsBoxFrame, public nsIMenuParent
|
||||
{
|
||||
public:
|
||||
nsMenuPopupFrame();
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
// nsIMenuParentInterface
|
||||
NS_IMETHOD SetCurrentMenuItem(nsIContent* aMenuItem);
|
||||
NS_IMETHOD GetNextMenuItem(nsIContent* aStart, nsIContent** aResult);
|
||||
NS_IMETHOD GetPreviousMenuItem(nsIContent* aStart, nsIContent** aResult);
|
||||
|
||||
// Overridden methods
|
||||
NS_IMETHOD Init(nsIPresContext& aPresContext,
|
||||
nsIContent* aContent,
|
||||
nsIFrame* aParent,
|
||||
|
@ -52,7 +61,7 @@ public:
|
|||
nsresult SyncViewWithFrame(PRBool aOnMenuBar);
|
||||
|
||||
protected:
|
||||
|
||||
nsIContent* mCurrentMenu; // The current menu that is active.
|
||||
}; // class nsMenuPopupFrame
|
||||
|
||||
#endif
|
||||
|
|
Загрузка…
Ссылка в новой задаче