Bug 317375. Reorganize frame painting and mouse event targeting around frame display lists. Some review from dbaron, lots of testing help from Martijn, Julien and others

This commit is contained in:
roc+@cs.cmu.edu
2006-01-26 02:29:17 +00:00
parent 436218a94d
commit a1b6a30f14
174 changed files with 8094 additions and 7747 deletions

View File

@@ -93,6 +93,7 @@
#include "nsIDOMMouseMotionListener.h"
#include "nsIDOMKeyListener.h"
#include "nsLayoutUtils.h"
#include "nsDisplayList.h"
// Constants
const nscoord kMaxDropDownRows = 20; // This matches the setting for 4.x browsers
@@ -342,73 +343,35 @@ nsListControlFrame::Destroy(nsPresContext *aPresContext)
}
NS_IMETHODIMP
nsListControlFrame::Paint(nsPresContext* aPresContext,
nsIRenderingContext& aRenderingContext,
const nsRect& aDirtyRect,
nsFramePaintLayer aWhichLayer,
PRUint32 aFlags)
nsListControlFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
const nsRect& aDirtyRect,
const nsDisplayListSet& aLists)
{
if (!GetStyleVisibility()->IsVisible()) {
return PR_FALSE;
}
// We allow visibility:hidden <select>s to contain visible options.
// Don't allow painting of list controls when painting is suppressed.
PRBool paintingSuppressed = PR_FALSE;
aPresContext->PresShell()->IsPaintingSuppressed(&paintingSuppressed);
if (paintingSuppressed)
// XXX why do we need this here? we should never reach this. Maybe
// because these can have widgets? Hmm
if (aBuilder->IsBackgroundOnly())
return NS_OK;
// Start by assuming we are visible and need to be painted
PRBool isVisible = PR_TRUE;
if (aPresContext->IsPaginated()) {
if (aPresContext->IsRenderingOnlySelection()) {
// Check the quick way first
PRBool isSelected = (mState & NS_FRAME_SELECTED_CONTENT) == NS_FRAME_SELECTED_CONTENT;
// if we aren't selected in the mState we could be a container
// so check to see if we are in the selection range
if (!isSelected) {
nsCOMPtr<nsISelectionController> selcon;
selcon = do_QueryInterface(aPresContext->PresShell());
if (selcon) {
nsCOMPtr<nsISelection> selection;
selcon->GetSelection(nsISelectionController::SELECTION_NORMAL, getter_AddRefs(selection));
nsCOMPtr<nsIDOMNode> node(do_QueryInterface(mContent));
selection->ContainsNode(node, PR_TRUE, &isVisible);
} else {
isVisible = PR_FALSE;
}
}
}
}
if (isVisible) {
if (aWhichLayer == NS_FRAME_PAINT_LAYER_BACKGROUND) {
const nsStyleDisplay* displayData = GetStyleDisplay();
if (displayData->mAppearance) {
nsITheme *theme = aPresContext->GetTheme();
nsRect rect(0, 0, mRect.width, mRect.height);
if (theme && theme->ThemeSupportsWidget(aPresContext, this, displayData->mAppearance))
theme->DrawWidgetBackground(&aRenderingContext, this,
displayData->mAppearance, rect, aDirtyRect);
}
}
return nsHTMLScrollFrame::Paint(aPresContext, aRenderingContext, aDirtyRect, aWhichLayer);
}
DO_GLOBAL_REFLOW_COUNT_DSP("nsListControlFrame", &aRenderingContext);
return NS_OK;
// REVIEW: The selection visibility code that used to be here is what
// we already do by default.
// REVIEW: There was code here to paint the theme background. But as far
// as I can tell, we'd just paint the theme background twice because
// it was redundant with nsCSSRendering::PaintBackground
return nsHTMLScrollFrame::BuildDisplayList(aBuilder, aDirtyRect, aLists);
}
/* Note: this is called by the SelectsAreaFrame, which is the same
as the frame returned by GetOptionsContainer. It's the frame which is
scrolled by us. */
void nsListControlFrame::PaintFocus(nsIRenderingContext& aRC, nsFramePaintLayer aWhichLayer)
/**
* This is called by the SelectsAreaFrame, which is the same
* as the frame returned by GetOptionsContainer. It's the frame which is
* scrolled by us.
* @param aPt the offset of this frame, relative to the rendering reference
* frame
*/
void nsListControlFrame::PaintFocus(nsIRenderingContext& aRC, nsPoint aPt)
{
if (NS_FRAME_PAINT_LAYER_FOREGROUND != aWhichLayer) return;
if (mFocused != this) return;
// The mEndSelectionIndex is what is currently being selected
@@ -494,14 +457,15 @@ void nsListControlFrame::PaintFocus(nsIRenderingContext& aRC, nsFramePaintLayer
if (childframe) {
// get the child rect
fRect = childframe->GetRect();
// get it into the coordinates of containerFrame
fRect.MoveBy(childframe->GetParent()->GetOffsetTo(containerFrame));
// get it into the our coordinates
fRect.MoveBy(childframe->GetParent()->GetOffsetTo(this));
} else {
fRect.x = fRect.y = 0;
fRect.width = mRect.width;
fRect.height = CalcFallbackRowHeight(0);
fRect.MoveBy(containerFrame->GetOffsetTo(this));
}
fRect += aPt;
PRBool lastItemIsSelected = PR_FALSE;
if (focusedIndex != kNothingSelected) {
@@ -2547,9 +2511,8 @@ nsresult
nsListControlFrame::GetIndexFromDOMEvent(nsIDOMEvent* aMouseEvent,
PRInt32& aCurIndex)
{
if (IgnoreMouseEventForSelection(aMouseEvent)) {
if (IgnoreMouseEventForSelection(aMouseEvent))
return NS_ERROR_FAILURE;
}
nsIView* view = GetScrolledFrame()->GetView();
nsIViewManager* viewMan = view->GetViewManager();