This commit is contained in:
hyatt%netscape.com 1999-07-21 07:42:16 +00:00
Родитель b5800eb036
Коммит c993598be9
8 изменённых файлов: 336 добавлений и 61 удалений

Просмотреть файл

@ -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