Fixing an XBL event handling bug and the menu accelerator bug. r=brendan, a=leaf

This commit is contained in:
hyatt%netscape.com 2000-04-06 22:32:39 +00:00
Родитель 2ffbbf0cf2
Коммит 5dc78cfa9c
8 изменённых файлов: 59 добавлений и 734 удалений

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

@ -1230,7 +1230,7 @@ nsXBLBinding::ConstructAttributeTable(nsIContent* aElement)
result == NS_CONTENT_ATTR_HAS_VALUE);
if (attrPresent) {
aElement->SetAttribute(kNameSpaceID_None, attribute, value, PR_TRUE);
aElement->SetAttribute(kNameSpaceID_None, attribute, value, PR_FALSE);
nsCOMPtr<nsIAtom> tag;
aElement->GetTag(*getter_AddRefs(tag));
if ((tag.get() == kHTMLAtom) && (attribute.get() == kValueAtom) && !value.IsEmpty()) {

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

@ -408,7 +408,7 @@ nsXBLEventHandler::ExecuteHandler(const nsString& aEventName, nsIDOMEvent* aEven
// Look for a compiled handler on the element.
// Should be compiled and bound with "on" in front of the name.
nsAutoString onEvent = "on";
nsAutoString onEvent = "onxbl";
onEvent += aEventName;
nsCOMPtr<nsIAtom> onEventAtom = getter_AddRefs(NS_NewAtom(onEvent));
@ -443,6 +443,9 @@ nsXBLEventHandler::ExecuteHandler(const nsString& aEventName, nsIDOMEvent* aEven
// Execute it.
nsCOMPtr<nsIDOMEventListener> eventListener;
NS_NewJSEventListener(getter_AddRefs(eventListener), boundContext, owner);
nsCOMPtr<nsIJSEventListener> jsListener(do_QueryInterface(eventListener));
jsListener->SetEventName(onEventAtom);
eventListener->HandleEvent(aEvent);
// Now unbind it.

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

@ -1230,7 +1230,7 @@ nsXBLBinding::ConstructAttributeTable(nsIContent* aElement)
result == NS_CONTENT_ATTR_HAS_VALUE);
if (attrPresent) {
aElement->SetAttribute(kNameSpaceID_None, attribute, value, PR_TRUE);
aElement->SetAttribute(kNameSpaceID_None, attribute, value, PR_FALSE);
nsCOMPtr<nsIAtom> tag;
aElement->GetTag(*getter_AddRefs(tag));
if ((tag.get() == kHTMLAtom) && (attribute.get() == kValueAtom) && !value.IsEmpty()) {

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

@ -408,7 +408,7 @@ nsXBLEventHandler::ExecuteHandler(const nsString& aEventName, nsIDOMEvent* aEven
// Look for a compiled handler on the element.
// Should be compiled and bound with "on" in front of the name.
nsAutoString onEvent = "on";
nsAutoString onEvent = "onxbl";
onEvent += aEventName;
nsCOMPtr<nsIAtom> onEventAtom = getter_AddRefs(NS_NewAtom(onEvent));
@ -443,6 +443,9 @@ nsXBLEventHandler::ExecuteHandler(const nsString& aEventName, nsIDOMEvent* aEven
// Execute it.
nsCOMPtr<nsIDOMEventListener> eventListener;
NS_NewJSEventListener(getter_AddRefs(eventListener), boundContext, owner);
nsCOMPtr<nsIJSEventListener> jsListener(do_QueryInterface(eventListener));
jsListener->SetEventName(onEventAtom);
eventListener->HandleEvent(aEvent);
// Now unbind it.

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

@ -205,7 +205,14 @@ nsIMenuFrame*
nsMenuBarFrame::FindMenuWithShortcut(PRUint32 aLetter)
{
// Enumerate over our list of frames.
nsIFrame* currFrame = mFrames.FirstChild();
nsIFrame* immediateParent = nsnull;
GetInsertionPoint(&immediateParent);
if (!immediateParent)
immediateParent = this;
nsIFrame* currFrame;
immediateParent->FirstChild(mPresContext, nsnull, &currFrame);
while (currFrame) {
nsCOMPtr<nsIContent> current;
currFrame->GetContent(getter_AddRefs(current));
@ -315,6 +322,11 @@ nsMenuBarFrame::KeyboardNavigation(PRUint32 aDirection, PRBool& aHandledFlag)
NS_IMETHODIMP
nsMenuBarFrame::GetNextMenuItem(nsIMenuFrame* aStart, nsIMenuFrame** aResult)
{
nsIFrame* immediateParent = nsnull;
GetInsertionPoint(&immediateParent);
if (!immediateParent)
immediateParent = this;
nsIFrame* currFrame = nsnull;
nsIFrame* startFrame = nsnull;
if (aStart) {
@ -324,7 +336,10 @@ nsMenuBarFrame::GetNextMenuItem(nsIMenuFrame* aStart, nsIMenuFrame** aResult)
currFrame->GetNextSibling(&currFrame);
}
}
else currFrame = mFrames.FirstChild();
else
immediateParent->FirstChild(mPresContext,
nsnull,
&currFrame);
while (currFrame) {
nsCOMPtr<nsIContent> current;
@ -340,7 +355,9 @@ nsMenuBarFrame::GetNextMenuItem(nsIMenuFrame* aStart, nsIMenuFrame** aResult)
currFrame->GetNextSibling(&currFrame);
}
currFrame = mFrames.FirstChild();
immediateParent->FirstChild(mPresContext,
nsnull,
&currFrame);
// Still don't have anything. Try cycling from the beginning.
while (currFrame && currFrame != startFrame) {
@ -366,16 +383,26 @@ nsMenuBarFrame::GetNextMenuItem(nsIMenuFrame* aStart, nsIMenuFrame** aResult)
NS_IMETHODIMP
nsMenuBarFrame::GetPreviousMenuItem(nsIMenuFrame* aStart, nsIMenuFrame** aResult)
{
nsIFrame* immediateParent = nsnull;
GetInsertionPoint(&immediateParent);
if (!immediateParent)
immediateParent = this;
nsIFrame* first;
immediateParent->FirstChild(mPresContext,
nsnull, &first);
nsFrameList frames(first);
nsIFrame* currFrame = nsnull;
nsIFrame* startFrame = nsnull;
if (aStart) {
aStart->QueryInterface(kIFrameIID, (void**)&currFrame);
if (currFrame) {
startFrame = currFrame;
currFrame = mFrames.GetPrevSiblingFor(currFrame);
currFrame = frames.GetPrevSiblingFor(currFrame);
}
}
else currFrame = mFrames.LastChild();
else currFrame = frames.LastChild();
while (currFrame) {
nsCOMPtr<nsIContent> current;
@ -388,10 +415,10 @@ nsMenuBarFrame::GetPreviousMenuItem(nsIMenuFrame* aStart, nsIMenuFrame** aResult
NS_IF_ADDREF(*aResult);
return NS_OK;
}
currFrame = mFrames.GetPrevSiblingFor(currFrame);
currFrame = frames.GetPrevSiblingFor(currFrame);
}
currFrame = mFrames.LastChild();
currFrame = frames.LastChild();
// Still don't have anything. Try cycling from the end.
while (currFrame && currFrame != startFrame) {
@ -406,7 +433,7 @@ nsMenuBarFrame::GetPreviousMenuItem(nsIMenuFrame* aStart, nsIMenuFrame** aResult
return NS_OK;
}
currFrame = mFrames.GetPrevSiblingFor(currFrame);
currFrame = frames.GetPrevSiblingFor(currFrame);
}
// No luck. Just return our start value.

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

@ -56,6 +56,8 @@
#include "nsIComponentManager.h"
#include "nsWidgetsCID.h"
#include "nsBoxLayoutState.h"
#include "nsIXBLBinding.h"
#include "nsIBindableContent.h"
#define NS_MENU_POPUP_LIST_INDEX (NS_AREA_FRAME_ABSOLUTE_LIST_INDEX + 1)
@ -1234,8 +1236,16 @@ nsMenuFrame::BuildAcceleratorText(nsString& aAccelString)
aAccelString += keyChar;
}
if (!aAccelString.IsEmpty())
if (!aAccelString.IsEmpty()) {
mContent->SetAttribute(kNameSpaceID_None, nsXULAtoms::acceltext, aAccelString, PR_FALSE);
nsCOMPtr<nsIBindableContent> bindable(do_QueryInterface(mContent));
if (bindable) {
nsCOMPtr<nsIXBLBinding> binding;
bindable->GetBinding(getter_AddRefs(binding));
if (binding)
binding->AttributeChanged(nsXULAtoms::acceltext, kNameSpaceID_None, PR_FALSE);
}
}
}
void

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

@ -100,22 +100,10 @@ NS_NewToolboxFrame ( nsIPresShell* aPresShell, nsIFrame** aNewFrame )
// Init, if necessary
//
nsToolboxFrame :: nsToolboxFrame (nsIPresShell* aShell):nsBoxFrame(aShell)
, mSumOfToolbarHeights(0), mNumToolbars(0),
mGrippyHilighted(kNoGrippyHilighted),
kCollapsedAtom(dont_AddRef( NS_NewAtom("collapsed"))),
kHiddenAtom(dont_AddRef( NS_NewAtom("hidden"))),
mDragListenerDelegate(nsnull), mNeedsCalc(PR_TRUE)
, mDragListenerDelegate(nsnull)
{
}
PRBool
nsToolboxFrame::GetInitialOrientation(PRBool& aIsHorizontal)
{
// by default we are vertical.
aIsHorizontal = PR_FALSE;
return nsBoxFrame::GetInitialOrientation(aIsHorizontal);
}
//
// nsToolboxFrame dstr
//
@ -127,75 +115,9 @@ nsToolboxFrame :: ~nsToolboxFrame ( )
mDragListenerDelegate->NotifyFrameDestroyed();
NS_RELEASE(mDragListenerDelegate);
}
ClearGrippyList ( mGrippies );
}
//
// RefreshStyleContext
//
// Not exactly sure what this does ;)
//
void
nsToolboxFrame :: RefreshStyleContext(nsIPresContext* aPresContext,
nsIAtom * aNewContentPseudo,
nsCOMPtr<nsIStyleContext>* aCurrentStyle,
nsIContent * aContent,
nsIStyleContext* aParentStyle)
{
nsIStyleContext* newStyleContext;
aPresContext->ProbePseudoStyleContextFor(aContent,
aNewContentPseudo,
aParentStyle,
PR_FALSE,
&newStyleContext);
if (newStyleContext != aCurrentStyle->get())
*aCurrentStyle = dont_AddRef(newStyleContext);
} // RefreshStyleContext
NS_IMETHODIMP
nsToolboxFrame::GetAdditionalStyleContext(PRInt32 aIndex,
nsIStyleContext** aStyleContext) const
{
NS_PRECONDITION(nsnull != aStyleContext, "null OUT parameter pointer");
if (aIndex < 0) {
return NS_ERROR_INVALID_ARG;
}
*aStyleContext = nsnull;
switch (aIndex) {
case NS_TOOLBOX_GRIPPY_NORMAL_CONTEXT_INDEX:
*aStyleContext = mGrippyNormalStyle;
NS_IF_ADDREF(*aStyleContext);
break;
case NS_TOOLBOX_GRIPPY_ROLLOVER_CONTEXT_INDEX:
*aStyleContext = mGrippyRolloverStyle;
NS_IF_ADDREF(*aStyleContext);
break;
default:
return NS_ERROR_INVALID_ARG;
}
return NS_OK;
}
NS_IMETHODIMP
nsToolboxFrame::SetAdditionalStyleContext(PRInt32 aIndex,
nsIStyleContext* aStyleContext)
{
if (aIndex < 0) {
return NS_ERROR_INVALID_ARG;
}
switch (aIndex) {
case NS_TOOLBOX_GRIPPY_NORMAL_CONTEXT_INDEX:
mGrippyNormalStyle = aStyleContext;
break;
case NS_TOOLBOX_GRIPPY_ROLLOVER_CONTEXT_INDEX:
mGrippyRolloverStyle = aStyleContext;
break;
}
return NS_OK;
}
NS_IMETHODIMP
nsToolboxFrame::Init(nsIPresContext* aPresContext,
@ -204,11 +126,8 @@ nsToolboxFrame::Init(nsIPresContext* aPresContext,
nsIStyleContext* aContext,
nsIFrame* aPrevInFlow)
{
mPresContext = aPresContext;
nsresult rv = nsBoxFrame::Init(aPresContext, aContent, aParent, aContext, aPrevInFlow);
UpdateStyles(aPresContext);
// Register the delegate as a drag listener.
mDragListenerDelegate = new DragListenerDelegate(this);
if (! mDragListenerDelegate)
@ -227,558 +146,6 @@ nsToolboxFrame::Init(nsIPresContext* aPresContext,
return rv;
}
void
nsToolboxFrame::UpdateStyles(nsIPresContext* aPresContext)
{
nsCOMPtr<nsIAtom> grippyRolloverPseudo ( dont_AddRef(NS_NewAtom(":toolbox-rollover")) );
RefreshStyleContext(aPresContext, grippyRolloverPseudo, &mGrippyRolloverStyle, mContent, mStyleContext);
nsCOMPtr<nsIAtom> grippyNormalPseudo ( dont_AddRef(NS_NewAtom(":toolbox-normal")) );
RefreshStyleContext(aPresContext, grippyNormalPseudo, &mGrippyNormalStyle, mContent, mStyleContext);
}
//
// Paint
//
// Paint our background and border like normal frames, but before we draw the
// children, draw our grippies for each toolbar.
//
NS_IMETHODIMP
nsToolboxFrame :: Paint ( nsIPresContext* aPresContext,
nsIRenderingContext& aRenderingContext,
const nsRect& aDirtyRect,
nsFramePaintLayer aWhichLayer)
{
// if we aren't visible then we are done.
const nsStyleDisplay* disp = (const nsStyleDisplay*)
mStyleContext->GetStyleData(eStyleStruct_Display);
if (!disp->IsVisibleOrCollapsed())
return NS_OK;
// take care of bg painting, borders and children
nsresult retVal = nsBoxFrame::Paint ( aPresContext, aRenderingContext, aDirtyRect, aWhichLayer );
// now draw what makes us special
DrawGrippies ( aPresContext, aRenderingContext );
return retVal;
} // Paint
//
// DrawGrippies
//
// Redraws all the grippies in the toolbox by iterating over each toolbar in the DOM
// and figuring out how to draw the grippies based on size/visibility information
//
void
nsToolboxFrame :: DrawGrippies ( nsIPresContext* aPresContext, nsIRenderingContext & aRenderingContext ) const
{
for ( PRInt32 i = 0; i < mGrippies.Count(); ++i ) {
TabInfo* currGrippy = NS_STATIC_CAST(TabInfo*, mGrippies[i]);
PRBool hilight = (mGrippyHilighted == i) ? PR_TRUE : PR_FALSE;
DrawGrippy ( aPresContext, aRenderingContext, currGrippy->mBoundingRect, hilight );
} // for each child
} // DrawGrippies
//
// DrawGrippy
//
// Draw a single grippy in the given rectangle, either with or without rollover feedback.
//
void
nsToolboxFrame :: DrawGrippy ( nsIPresContext* aPresContext, nsIRenderingContext & aRenderingContext,
const nsRect & aBoundingRect, PRBool aDrawHilighted ) const
{
nsCOMPtr<nsIStyleContext> style ( aDrawHilighted ? mGrippyRolloverStyle : mGrippyNormalStyle ) ;
if ( !mGrippyRolloverStyle ) {
#ifdef NS_DEBUG
printf("nsToolboxFrame::DrawGrippy() -- style context null, css file not loaded correctly??\n");
#endif
return; // something must be seriously wrong
}
const nsStyleColor* grippyColor = (const nsStyleColor*)style->GetStyleData(eStyleStruct_Color);
const nsStyleSpacing* grippySpacing = (const nsStyleSpacing*)style->GetStyleData(eStyleStruct_Spacing);
// const nsStyleFont* grippyFont = (const nsStyleFont*)style->GetStyleData(eStyleStruct_Font);
nsToolboxFrame* nonConstSelf = NS_CONST_CAST(nsToolboxFrame*, this);
nsCSSRendering::PaintBackground(aPresContext, aRenderingContext, nonConstSelf,
aBoundingRect, aBoundingRect, *grippyColor, *grippySpacing, 0, 0);
nsCSSRendering::PaintBorder(aPresContext, aRenderingContext, nonConstSelf,
aBoundingRect, aBoundingRect, *grippySpacing, style, 0);
} // DrawGrippy
/*
NS_IMETHODIMP
nsToolboxFrame::GetBoxInfo(nsIPresContext* aPresContext, const nsHTMLReflowState& aReflowState, nsBoxInfo& aSize)
{
CalculateGrippies(aPresContext);
return nsBoxFrame::GetBoxInfo(aPresContext, aReflowState, aSize);
}
*/
NS_IMETHODIMP
nsToolboxFrame::NeedsRecalc()
{
nsresult rv = nsBoxFrame::NeedsRecalc();
mNeedsCalc = PR_TRUE;
return rv;
}
NS_IMETHODIMP
nsToolboxFrame::GetInset(nsMargin& aMargin)
{
if (mNeedsCalc)
{
CalculateGrippies(mPresContext);
mNeedsCalc = PR_FALSE;
}
nsBoxFrame::GetInset(aMargin);
aMargin += mInset;
return NS_OK;
}
NS_IMETHODIMP
nsToolboxFrame::Layout(nsBoxLayoutState& aState)
{
// lay us out
nsresult rv = nsBoxFrame::Layout(aState);
LayoutGrippies(aState);
return rv;
}
// After we have been flowed this should be flowed to place the grippies at there
// physical locations.
nsresult
nsToolboxFrame::LayoutGrippies(nsBoxLayoutState& aState)
{
// get the rect we can place the grippies in. This is inside our borders and debug rect.
nsRect ourRect(0,0,0,0);
GetRect(ourRect);
ourRect.x = 0;
ourRect.y = 0;
nsRect innerRect(ourRect);
nsMargin border(0,0,0,0);
GetBorderAndPadding(border);
innerRect.Deflate(border);
nsIPresContext* presContext = aState.GetPresContext();
float p2t;
presContext->GetScaledPixelsToTwips(&p2t);
nscoord onePixel = NSIntPixelsToTwips(1, p2t);
nscoord grippyWidth = kGrippyWidthInPixels * onePixel; // remember to leave room for the grippy on the right
nscoord collapsedGrippyHeight = kCollapsedGrippyHeightInPixels * onePixel;
nsresult errCode = NS_OK;
const PRBool isHorz = IsHorizontal();
// iterate over all visible toolbar frames, moving the associated grippy
// next to the toolbar
mNumToolbars = 0;
nsIBox* childBox;
GetChildBox(&childBox);
while ( childBox ) {
// get the childs rect and figure out the grippy size
nsIFrame* childFrame = nsnull;
childBox->GetFrame(&childFrame);
nsCOMPtr<nsIContent> childContent;
childFrame->GetContent(getter_AddRefs(childContent));
nsRect grippyRect;
childBox->GetBounds(grippyRect);
if ( isHorz ) {
grippyRect.y = innerRect.y;
grippyRect.height = grippyWidth;
} else {
grippyRect.x = innerRect.x;
grippyRect.width = grippyWidth;
}
TabInfo *grippyInfo = FindGrippyForToolbar(mGrippies, childContent);
NS_ASSERTION(grippyInfo != 0, "Grippy Info Struct dissapeared!");
NS_ASSERTION(grippyInfo->mCollapsed == 0, "Collapsed toolbar has frame!");
// Set the location of the grippy to the left...
grippyInfo->SetBounds(grippyRect);
errCode = childBox->GetNextBox(&childBox);
NS_ASSERTION(errCode == NS_OK, "failed to get next child");
mNumToolbars++;
}
// now move collapsed grippies to the bottom
for ( PRInt32 i = 0; i < mGrippies.Count(); ++i ) {
TabInfo* currGrippy = NS_STATIC_CAST(TabInfo*, mGrippies[i]);
if (currGrippy->mCollapsed) {
// remember we are just inverting the coord system here so in a
// horzontal toolbox our height is our width. Thats why we just use
// height here on both x and y coords.
if ( isHorz )
currGrippy->mBoundingRect.x = ourRect.width - collapsedGrippyHeight;
else
currGrippy->mBoundingRect.y = ourRect.height - collapsedGrippyHeight;
}
}
return errCode;
}
// called to figure out how big our grippies are and how many we have
// this will be called by boxes reflow method.
void
nsToolboxFrame::CalculateGrippies(nsIPresContext* aPresContext)
{
// compute amount (in twips) each toolbar will be offset from the right because of
// the grippy
float p2t;
aPresContext->GetScaledPixelsToTwips(&p2t);
nscoord onePixel = NSIntPixelsToTwips(1, p2t);
nscoord collapsedGrippyHeight = kCollapsedGrippyHeightInPixels * onePixel;
nscoord collapsedGrippyWidth = kCollapsedGrippyWidthInPixels * onePixel;
const PRBool isHorz = IsHorizontal();
{
nscoord grippyWidth = kGrippyWidthInPixels * onePixel; // remember to leave room for the grippy on the right
// Leave room at the side for the grippies of visible toolbars. Make a margin
// of the appropriate dimensions.
mInset = nsMargin(0,0,0,0);
if ( isHorz ) // Set margins so we have a place for uncollapsed grippies
mInset.top = grippyWidth;
else
mInset.left = grippyWidth;
}
// Save old tabs so we can make newly collapsed bars as wide as they WERE tall. We will
// release the grippies in mGrippies at the very end when we dispose of |oldGrippies|
nsVoidArray oldGrippies, emptyList;
oldGrippies = mGrippies;
mGrippies = emptyList;
// ----- Calculate a new set of grippy states...
// iterate over each content node to see if we can find one with the "collapsed"
// attribute set. If so, we have a collapsed toolbar.
nsAutoString value;
int numCollapsedGrippies = 0;
nscoord grippyPos = 0;
// Get the first child of the toolbox content node
unsigned int contentCounter = 0;
nsCOMPtr<nsIContent> childContent;
nsresult errCode = mContent->ChildAt(contentCounter, *getter_AddRefs(childContent));
NS_ASSERTION(errCode == NS_OK,"failed to get first child");
// iterate over each content node to see if we can find one with the "collapsed"
// attribute set. If so, we have a collapsed toolbar.
while ( childContent ) {
// is this bar collapsed?
value = "";
childContent->GetAttribute(kNameSpaceID_None, kCollapsedAtom, value);
if (value.Equals("true")) { // The bar is collapsed!
nscoord grippyWidth;
nscoord grippyHeight;
if ( isHorz ) {
grippyWidth = collapsedGrippyHeight;
grippyHeight = collapsedGrippyWidth;
} else {
grippyWidth = collapsedGrippyWidth;
grippyHeight = collapsedGrippyHeight;
}
TabInfo* oldGrippy = FindGrippyForToolbar ( oldGrippies, childContent );
if ( oldGrippy ) { // Inherit the old size...
if ( isHorz ) { // If laying out children horizontally...
if ( oldGrippy->mCollapsed) // Did it used to be collapsed?
grippyHeight = oldGrippy->mBoundingRect.height; // Copy old width
else
grippyHeight = oldGrippy->mBoundingRect.width; // Else copy old height
} else { // If laying out children vertically...
if ( oldGrippy->mCollapsed ) // Did it used to be collapsed?
grippyWidth = oldGrippy->mBoundingRect.width; // Copy old width
else
grippyWidth = oldGrippy->mBoundingRect.height; // Else copy old height
}
}
if ( isHorz ) {
mGrippies.AppendElement( new TabInfo(childContent, PR_TRUE,
nsRect(0, grippyPos, grippyWidth, grippyHeight)) );
grippyPos += grippyHeight;
} else {
mGrippies.AppendElement( new TabInfo(childContent, PR_TRUE,
nsRect(grippyPos, 0, grippyWidth, grippyHeight)) );
grippyPos += grippyWidth;
}
++numCollapsedGrippies;
} else { // The bar is NOT collapsed!!
mGrippies.AppendElement( new TabInfo(childContent, PR_FALSE) );
}
// next!
++contentCounter;
errCode = mContent->ChildAt(contentCounter, *getter_AddRefs(childContent));
NS_ASSERTION(errCode == NS_OK,"failed to get next child");
}
// if there are any collapsed bars, we need to leave room at the bottom of
// the box for the grippies. Adjust the margins before we reflow the box.
if ( numCollapsedGrippies ) {
if ( isHorz )
mInset.left = collapsedGrippyHeight;
else
mInset.bottom = collapsedGrippyHeight;
}
// make sure we now dispose of the old grippies since we have allocated
// new ones.
ClearGrippyList ( oldGrippies );
}
//
// FindGrippyForToolbar
//
// Utility routine to scan through the grippy list looking for one in the list
// associated with the given content object (which is the toolbar's content object).
//
// Will return nsnull if it cannot find the toolbar.
//
nsToolboxFrame::TabInfo*
nsToolboxFrame :: FindGrippyForToolbar ( nsVoidArray & inList, const nsIContent* inContent ) const
{
for ( PRInt32 i = 0; i < inList.Count(); ++i ) {
TabInfo* currGrippy = NS_STATIC_CAST(TabInfo*, inList[i]);
if ( currGrippy->mToolbar == inContent )
return currGrippy;
}
return nsnull;
} // FindGrippyForToolbar
//
// ClearGrippyList
//
// Since we are assuming the array "owns" the grippies once they go in there,
// we need to make sure that when the list goes away that they are cleaned up. The
// nsVoidArray does not know how to do this, so we need to do it ourselves.
//
void
nsToolboxFrame :: ClearGrippyList ( nsVoidArray & inList )
{
for ( PRInt32 i = 0; i < inList.Count(); ++i ) {
TabInfo* currGrippy = NS_STATIC_CAST(TabInfo*, inList[i]);
delete currGrippy;
}
} // ClearGrippyList
//
// HandleEvent
//
//
NS_IMETHODIMP
nsToolboxFrame :: HandleEvent ( nsIPresContext* aPresContext,
nsGUIEvent* aEvent,
nsEventStatus* aEventStatus)
{
if ( !aEvent )
return nsEventStatus_eIgnore;
switch ( aEvent->message ) {
case NS_MOUSE_LEFT_CLICK:
// BUG 3752 aEvent->point is invalid here.
break;
case NS_MOUSE_LEFT_BUTTON_UP:
OnMouseLeftClick ( aPresContext, aEvent->point );
break;
case NS_MOUSE_MOVE:
OnMouseMove ( aPresContext, aEvent->point );
break;
case NS_MOUSE_EXIT:
OnMouseExit ( aPresContext);
break;
default:
break;
} // case of which event
return nsEventStatus_eIgnore;
} // HandleEvent
//
// ConvertToLocalPoint
//
// Given a point in the coordinate system of the parent view, convert to a point in the
// frame's local coordinate system.
//
void
nsToolboxFrame :: ConvertToLocalPoint ( nsIPresContext* aPresContext, nsPoint & ioPoint )
{
nsIView* view = nsnull; // note: |view| not AddRef'd
nsPoint offset;
if ( GetOffsetFromView(aPresContext, offset, &view) == NS_OK )
ioPoint -= offset;
} // ConvertToLocalPoint
//
// OnMouseMove
//
// Handle mouse move events for hilighting and unhilighting the grippies. |aMouseLoc|
// is not in local frame coordinates.
//
void
nsToolboxFrame :: OnMouseMove ( nsIPresContext* aPresContext, nsPoint & aMouseLoc )
{
nsPoint localMouseLoc = aMouseLoc;
ConvertToLocalPoint ( aPresContext, localMouseLoc );
for ( int i = 0; i < mGrippies.Count(); ++i ) {
TabInfo* currGrippy = NS_STATIC_CAST(TabInfo*, mGrippies[i]);
if ( currGrippy->mBoundingRect.Contains(localMouseLoc) ) {
if ( i != mGrippyHilighted ) {
// unhilight the old one
if ( mGrippyHilighted != kNoGrippyHilighted ) {
TabInfo* hilightedGrippy = NS_STATIC_CAST(TabInfo*, mGrippies[mGrippyHilighted]);
Invalidate ( aPresContext, hilightedGrippy->mBoundingRect, PR_FALSE );
}
// hilight the new one and remember it
mGrippyHilighted = i;
Invalidate ( aPresContext, currGrippy->mBoundingRect, PR_FALSE );
} // if in a new tab
}
} // for each toolbar
} // OnMouseMove
//
// OnMouseLeftClick
//
// Check if a click is in a grippy and expand/collapse appropriately. |aMouseLoc|
// is not in local frame coordinates.
//
void
nsToolboxFrame :: OnMouseLeftClick ( nsIPresContext* aPresContext, nsPoint & aMouseLoc )
{
nsPoint localMouseLoc = aMouseLoc;
ConvertToLocalPoint ( aPresContext, localMouseLoc );
for ( int i = 0; i < mGrippies.Count(); ++i ) {
TabInfo* currGrippy = NS_STATIC_CAST(TabInfo*, mGrippies[i]);
if ( currGrippy->mBoundingRect.Contains(localMouseLoc) ) {
if ( currGrippy->mCollapsed )
ExpandToolbar ( *currGrippy );
else
CollapseToolbar ( *currGrippy );
// don't keep repeating this process since toolbars have now be
// relaid out and a new toolbar may be under the current mouse
// location!
break;
}
}
} // OnMouseLeftClick
//
// OnMouseExit
//
// Update the grippies that may have been hilighted while the mouse was within the
// manager.
//
void
nsToolboxFrame :: OnMouseExit (nsIPresContext* aPresContext)
{
if ( mGrippyHilighted != kNoGrippyHilighted ) {
TabInfo* hilightedGrippy = NS_STATIC_CAST(TabInfo*, mGrippies[mGrippyHilighted]);
Invalidate ( aPresContext, hilightedGrippy->mBoundingRect, PR_FALSE );
mGrippyHilighted = kNoGrippyHilighted;
}
} // OnMouseExit
//
// CollapseToolbar
//
// Given the tab that was clicked on, collapse its corresponding toolbar. This
// assumes that the tab is expanded.
//
void
nsToolboxFrame :: CollapseToolbar ( TabInfo & inTab )
{
if ( inTab.mToolbar ) {
#ifdef NS_DEBUG
printf("CollapseToolbar:: collapsing\n");
#endif
nsresult errCode = inTab.mToolbar->SetAttribute ( kNameSpaceID_None, kCollapsedAtom, "true", PR_TRUE );
#ifdef NS_DEBUG
if ( errCode )
printf("Problem setting collapsed attribute while collapsing toolbar\n");
#endif
}
} // CollapseToolbar
//
// ExpandToolbar
//
// Given the collapsed (horizontal) tab that was clicked on, expand its
// corresponding toolbar. This assumes the tab is collapsed.
//
void
nsToolboxFrame :: ExpandToolbar ( TabInfo & inTab )
{
// nsresult errCode = mContent->UnsetAttribute ( kNameSpaceID_None, kCollapsedAtom, PR_TRUE );
nsresult errCode = inTab.mToolbar->SetAttribute ( kNameSpaceID_None, kCollapsedAtom, "false", PR_TRUE );
#ifdef NS_DEBUG
if ( errCode )
printf("Problem clearing collapsed attribute while expanding toolbar\n");
#endif
} // ExpandToolbar
////////////////////////////////////////////////////////////////////////
nsresult
nsToolboxFrame::HandleEvent(nsIDOMEvent* aEvent)

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

@ -50,39 +50,17 @@
#include "nsCOMPtr.h"
#include "nsBoxFrame.h"
#define NS_TOOLBOX_GRIPPY_NORMAL_CONTEXT_INDEX 0
#define NS_TOOLBOX_GRIPPY_ROLLOVER_CONTEXT_INDEX 1
class nsToolboxFrame : public nsBoxFrame
{
public:
friend nsresult NS_NewToolboxFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame);
// nsIBox
NS_IMETHOD Layout(nsBoxLayoutState& aBoxLayoutState);
NS_IMETHOD GetInset(nsMargin& aInset);
NS_IMETHOD NeedsRecalc();
// nsIFrame
NS_IMETHOD Paint(nsIPresContext* aPresContext,
nsIRenderingContext& aRenderingContext,
const nsRect& aDirtyRect,
nsFramePaintLayer aWhichLayer);
NS_IMETHOD HandleEvent(nsIPresContext* aPresContext,
nsGUIEvent* aEvent,
nsEventStatus* aEventStatus);
NS_IMETHOD Init(nsIPresContext* aPresContext,
nsIContent* aContent,
nsIFrame* aParent,
nsIStyleContext* aContext,
nsIFrame* aPrevInFlow);
NS_IMETHOD GetAdditionalStyleContext(PRInt32 aIndex,
nsIStyleContext** aStyleContext) const;
NS_IMETHOD SetAdditionalStyleContext(PRInt32 aIndex,
nsIStyleContext* aStyleContext);
/*BEGIN implementations of dragevent handler interface*/
virtual nsresult HandleEvent(nsIDOMEvent* aEvent);
virtual nsresult DragEnter(nsIDOMEvent* aDragEvent);
@ -99,70 +77,10 @@ public:
}
protected:
enum { kGrippyWidthInPixels = 10, kCollapsedGrippyHeightInPixels = 10, kCollapsedGrippyWidthInPixels = 50 } ;
enum { kNoGrippyHilighted = -1 } ;
struct TabInfo {
TabInfo( nsIContent * inContent, PRBool inCollapsed,
const nsRect &inBounds = nsRect(0,0,0,0))
: mToolbar(inContent),
mBoundingRect(inBounds),
mCollapsed(inCollapsed)
{
}
void SetBounds(const nsRect &inBounds) { mBoundingRect = inBounds; }
nsIContent* mToolbar; // content object associated w/ toolbar frame. We don't own it.
nsRect mBoundingRect;
PRBool mCollapsed;
};
nsToolboxFrame(nsIPresShell* aShell);
virtual ~nsToolboxFrame();
virtual PRBool GetInitialOrientation(PRBool& aIsHorizontal);
virtual void UpdateStyles(nsIPresContext* aPresContext);
virtual void CalculateGrippies(nsIPresContext* aPresContext);
virtual nsresult LayoutGrippies(nsBoxLayoutState& aBoxLayoutState);
void RefreshStyleContext(nsIPresContext* aPresContext,
nsIAtom * aNewContentPseudo,
nsCOMPtr<nsIStyleContext>* aCurrentStyle,
nsIContent * aContent,
nsIStyleContext* aParentStyle) ;
void DrawGrippies ( nsIPresContext* aPresContext, nsIRenderingContext & aContext ) const ;
void DrawGrippy ( nsIPresContext* aPresContext, nsIRenderingContext & aContext,
const nsRect & aBoundingRect, PRBool aDrawHilighted ) const ;
void CollapseToolbar ( TabInfo & inTab ) ;
void ExpandToolbar ( TabInfo & inTab ) ;
void ConvertToLocalPoint ( nsIPresContext* aPresContext, nsPoint & ioPoint ) ;
void OnMouseMove ( nsIPresContext* aPresContext, nsPoint & aMouseLoc ) ;
void OnMouseExit ( nsIPresContext* aPresContext ) ;
void OnMouseLeftClick ( nsIPresContext* aPresContext, nsPoint & aMouseLoc ) ;
// utility routines
TabInfo* FindGrippyForToolbar ( nsVoidArray & inList, const nsIContent* inContent ) const ;
void ClearGrippyList ( nsVoidArray & inList ) ;
// style context for the normal state and rollover state of grippies
nsCOMPtr<nsIStyleContext> mGrippyNormalStyle;
nsCOMPtr<nsIStyleContext> mGrippyRolloverStyle;
nsMargin mInset;
unsigned long mSumOfToolbarHeights;
nsVoidArray mGrippies; // list of all active grippies
unsigned short mNumToolbars;
short mGrippyHilighted; // used to indicate which grippy the mouse is inside
const nsCOMPtr<nsIAtom> kCollapsedAtom ;
const nsCOMPtr<nsIAtom> kHiddenAtom ;
class DragListenerDelegate : public nsIDOMDragListener
{
protected:
@ -221,9 +139,6 @@ protected:
// with an element in the UI.
nsToolboxFrame ( const nsToolboxFrame& aFrame ) ; // DO NOT IMPLEMENT
nsToolboxFrame& operator= ( const nsToolboxFrame& aFrame ) ; // DO NOT IMPLEMENT
PRBool mNeedsCalc;
nsIPresContext* mPresContext;
}; // class nsToolboxFrame
#endif