From 8e1aa657ab5b1c8b77bb3131bce9ac89c8dbf205 Mon Sep 17 00:00:00 2001 From: "kmcclusk%netscape.com" Date: Tue, 9 Feb 1999 18:25:40 +0000 Subject: [PATCH] Added support to gfx-render radio buttons. Both checkboxes and radio buttons now use CSS style to get colors for rendering. Checkboxes also use the CSS border rendering code. Added New utility methods to nsFormControlFrame to PaintCircular backgrounds and borders. Set compiler directive to gfx-render radiobuttons and checkboxes both for printing and on-screen display. --- layout/forms/nsFormControlFrame.cpp | 168 +++++++++--------- layout/forms/nsFormControlFrame.h | 2 +- layout/forms/nsFormControlHelper.cpp | 87 ++++++--- layout/forms/nsFormControlHelper.h | 43 ++++- .../html/forms/src/nsButtonControlFrame.cpp | 2 +- .../html/forms/src/nsCheckboxControlFrame.cpp | 6 +- layout/html/forms/src/nsFormControlFrame.cpp | 168 +++++++++--------- layout/html/forms/src/nsFormControlFrame.h | 2 +- layout/html/forms/src/nsFormControlHelper.cpp | 87 ++++++--- layout/html/forms/src/nsFormControlHelper.h | 43 ++++- layout/html/forms/src/nsRadioControlFrame.cpp | 26 ++- 11 files changed, 397 insertions(+), 237 deletions(-) diff --git a/layout/forms/nsFormControlFrame.cpp b/layout/forms/nsFormControlFrame.cpp index a61df00a8d33..dc992c6e09b4 100644 --- a/layout/forms/nsFormControlFrame.cpp +++ b/layout/forms/nsFormControlFrame.cpp @@ -223,102 +223,101 @@ nsFormControlFrame::Reflow(nsIPresContext& aPresContext, nsIDeviceContext* dx = nsnull; dx = aPresContext.GetDeviceContext(); - PRBool supportsWidgets = PR_TRUE; - //XXX: Temporary flag for getting GFX rendered widgets on the screen - PRBool useGfxWidgets = PR_FALSE; - - if (PR_FALSE == useGfxWidgets) { - supportsWidgets = PR_TRUE; - if (nsnull != dx) { - dx->SupportsNativeWidgets(supportsWidgets); - NS_RELEASE(dx); - } + PRBool requiresWidget = PR_TRUE; + + // Checkto see if the device context supports widgets at all + if (nsnull != dx) { + dx->SupportsNativeWidgets(requiresWidget); + NS_RELEASE(dx); } - else - supportsWidgets = PR_FALSE; + +#ifdef NS_GFX_RENDER_FORM_ELEMENTS + // Check with the frame to see if requires a widget to render + if (PR_TRUE == requiresWidget) { + RequiresWidget(requiresWidget); + } +#endif GetDesiredSize(&aPresContext, aReflowState, aDesiredSize, mWidgetSize); if (!mDidInit) { - nsIPresShell *presShell = aPresContext.GetShell(); // need to release - nsIViewManager *viewMan = presShell->GetViewManager(); // need to release - NS_RELEASE(presShell); - nsRect boundBox(0, 0, aDesiredSize.width, aDesiredSize.height); + if (PR_TRUE == requiresWidget) { + nsIPresShell *presShell = aPresContext.GetShell(); // need to release + nsIViewManager *viewMan = presShell->GetViewManager(); // need to release + NS_RELEASE(presShell); + nsRect boundBox(0, 0, aDesiredSize.width, aDesiredSize.height); - // absolutely positioned controls already have a view but not a widget - nsIView* view = nsnull; - GetView(view); - if (nsnull == view) { - result = nsRepository::CreateInstance(kViewCID, nsnull, kIViewIID, (void **)&view); - if (!NS_SUCCEEDED(result)) { - NS_ASSERTION(0, "Could not create view for form control"); - aStatus = NS_FRAME_NOT_COMPLETE; - return result; - } + // absolutely positioned controls already have a view but not a widget + nsIView* view = nsnull; + GetView(view); + if (nsnull == view) { + result = nsRepository::CreateInstance(kViewCID, nsnull, kIViewIID, (void **)&view); + if (!NS_SUCCEEDED(result)) { + NS_ASSERTION(0, "Could not create view for form control"); + aStatus = NS_FRAME_NOT_COMPLETE; + return result; + } - nsIFrame* parWithView; - nsIView *parView; + nsIFrame* parWithView; + nsIView *parView; - GetParentWithView(parWithView); - parWithView->GetView(parView); + GetParentWithView(parWithView); + parWithView->GetView(parView); - // initialize the view as hidden since we don't know the (x,y) until Paint - result = view->Init(viewMan, boundBox, parView, nsnull, nsViewVisibility_kHide); - if (NS_OK != result) { - NS_ASSERTION(0, "view initialization failed"); - aStatus = NS_FRAME_NOT_COMPLETE; - return NS_OK; - } + // initialize the view as hidden since we don't know the (x,y) until Paint + result = view->Init(viewMan, boundBox, parView, nsnull, nsViewVisibility_kHide); + if (NS_OK != result) { + NS_ASSERTION(0, "view initialization failed"); + aStatus = NS_FRAME_NOT_COMPLETE; + return NS_OK; + } - viewMan->InsertChild(parView, view, 0); - SetView(view); - } - - PRInt32 type; - GetType(&type); - const nsIID& id = GetCID(); - -#ifdef NS_GFX_RENDER_FORM_ELEMENTS - RequiresWidget(supportsWidgets); -#else - supportsWidgets = PR_TRUE; -#endif - - if ((NS_FORM_INPUT_HIDDEN != type) && (PR_TRUE == supportsWidgets)) { - // Do the following only if a widget is created - nsWidgetInitData* initData = GetWidgetInitData(aPresContext); // needs to be deleted - view->CreateWidget(id, initData); - - if (nsnull != initData) { - delete(initData); - } - - // set our widget - result = GetWidget(view, &mWidget); - if ((NS_OK == result) && mWidget) { // keep the ref on mWidget - nsIFormControl* formControl = nsnull; - result = mContent->QueryInterface(kIFormControlIID, (void**)&formControl); - if ((NS_OK == result) && formControl) { - // set the content's widget, so it can get content modified by the widget - formControl->SetWidget(mWidget); - NS_RELEASE(formControl); + viewMan->InsertChild(parView, view, 0); + SetView(view); } - // PostCreateWidget(&aPresContext, aDesiredSize.width, aDesiredSize.height); - // mDidInit = PR_TRUE; - } else { - NS_ASSERTION(0, "could not get widget"); - } - } - - PostCreateWidget(&aPresContext, aDesiredSize.width, aDesiredSize.height); - mDidInit = PR_TRUE; - if ((aDesiredSize.width != boundBox.width) || (aDesiredSize.height != boundBox.height)) { - viewMan->ResizeView(view, aDesiredSize.width, aDesiredSize.height); + PRInt32 type; + GetType(&type); + const nsIID& id = GetCID(); + + if ((NS_FORM_INPUT_HIDDEN != type) && (PR_TRUE == requiresWidget)) { + // Do the following only if a widget is created + nsWidgetInitData* initData = GetWidgetInitData(aPresContext); // needs to be deleted + view->CreateWidget(id, initData); + + if (nsnull != initData) { + delete(initData); + } + + // set our widget + result = GetWidget(view, &mWidget); + if ((NS_OK == result) && mWidget) { // keep the ref on mWidget + nsIFormControl* formControl = nsnull; + result = mContent->QueryInterface(kIFormControlIID, (void**)&formControl); + if ((NS_OK == result) && formControl) { + // set the content's widget, so it can get content modified by the widget + formControl->SetWidget(mWidget); + NS_RELEASE(formControl); + } + } else { + NS_ASSERTION(0, "could not get widget"); + } + } + + PostCreateWidget(&aPresContext, aDesiredSize.width, aDesiredSize.height); + mDidInit = PR_TRUE; + + if ((aDesiredSize.width != boundBox.width) || (aDesiredSize.height != boundBox.height)) { + viewMan->ResizeView(view, aDesiredSize.width, aDesiredSize.height); + } + + NS_IF_RELEASE(viewMan); } - - NS_IF_RELEASE(viewMan); - } + else { + PostCreateWidget(&aPresContext, aDesiredSize.width, aDesiredSize.height); + mDidInit = PR_TRUE; + } + } aDesiredSize.ascent = aDesiredSize.height; aDesiredSize.descent = 0; @@ -643,8 +642,7 @@ nsFormControlFrame::GetFont(nsIPresContext* aPresContext, } nsresult nsFormControlFrame::GetDefaultCheckState(PRBool *aState) -{ - nsresult res = NS_OK; +{ nsresult res = NS_OK; nsIDOMHTMLInputElement* inputElement; if (NS_OK == mContent->QueryInterface(kIDOMHTMLInputElementIID, (void**)&inputElement)) { res = inputElement->GetDefaultChecked(aState); diff --git a/layout/forms/nsFormControlFrame.h b/layout/forms/nsFormControlFrame.h index bfa4771cf3ca..ce0428966d64 100644 --- a/layout/forms/nsFormControlFrame.h +++ b/layout/forms/nsFormControlFrame.h @@ -40,7 +40,7 @@ class nsFormFrame; // using GFX calls, rather than creating a widget. Undefining it // causes widgets to be used for form elements. @see RequiresWidget method // to see which widgets will obey this directive. -#undef NS_GFX_RENDER_FORM_ELEMENTS +#define NS_GFX_RENDER_FORM_ELEMENTS /** * nsFormControlFrame is the base class for frames of form controls. It diff --git a/layout/forms/nsFormControlHelper.cpp b/layout/forms/nsFormControlHelper.cpp index c3233ce10341..3fa29463bf98 100644 --- a/layout/forms/nsFormControlHelper.cpp +++ b/layout/forms/nsFormControlHelper.cpp @@ -568,13 +568,12 @@ nsFormControlHelper::PaintScrollbar(nsIRenderingContext& aRenderingContext, } + void nsFormControlHelper::PaintFixedSizeCheckMark(nsIRenderingContext& aRenderingContext, float aPixelsToTwips) { - //XXX: Check mark is always draw in black. If the this code is used to Render the widget - //to the screen the color should be set using the CSS style color instead. - aRenderingContext.SetColor(NS_RGB(0, 0, 0)); + // Offsets to x,y location, These offsets are used to place the checkmark in the middle // of it's 12X12 pixel box. const PRUint32 ox = 3; @@ -630,9 +629,20 @@ nsFormControlHelper::PaintFixedSizeCheckMarkBorder(nsIRenderingContext& aRenderi //Draw a checkmark in any size. void -nsFormControlHelper::PaintScaledCheckMark(nsIRenderingContext& aRenderingContext, +nsFormControlHelper::PaintCheckMark(nsIRenderingContext& aRenderingContext, float aPixelsToTwips, PRUint32 aWidth, PRUint32 aHeight) { + // Width and height of the fixed size checkmark in TWIPS. + const PRUint32 fixedSizeCheckmarkWidth = 165; + const PRUint32 fixedSizeCheckmarkHeight = 165; + + if ((fixedSizeCheckmarkWidth == aWidth) && + (fixedSizeCheckmarkHeight == aHeight)) { + // Standard size, so draw a fixed size check mark instead of a scaled check mark. + PaintFixedSizeCheckMark(aRenderingContext, aPixelsToTwips); + return; + } + const PRUint32 checkpoints = 7; const PRUint32 checksize = 9; //This is value is determined by added 2 units to the end //of the 7X& pixel rectangle below to provide some white space @@ -773,14 +783,53 @@ nsFormControlHelper::PaintRectangularButton(nsIPresContext& aPresContext, } +void +nsFormControlHelper::GetCircularRect(PRUint32 aWidth, PRUint32 aHeight, nsRect& aRect) +{ + if (aWidth > aHeight) + aRect.SetRect((aWidth/2) - (aHeight/2), 0, aHeight, aHeight); + else + aRect.SetRect(0, (aHeight/2) - (aWidth/2), aWidth, aWidth); +} + + +void +nsFormControlHelper::PaintCircularBackground(nsIPresContext& aPresContext, + nsIRenderingContext& aRenderingContext, + const nsRect& aDirtyRect, nsIStyleContext* aStyleContext, PRBool aInset, + nsIFrame* aForFrame, PRUint32 aWidth, PRUint32 aHeight) +{ + float p2t; + aPresContext.GetScaledPixelsToTwips(p2t); + nscoord onePixel = NSIntPixelsToTwips(1, p2t); + + nsRect outside; + nsFormControlHelper::GetCircularRect(aWidth, aHeight, outside); + + outside.Deflate(onePixel, onePixel); + outside.Deflate(onePixel, onePixel); + const nsStyleColor* color = (const nsStyleColor*) + aStyleContext->GetStyleData(eStyleStruct_Color); + aRenderingContext.SetColor(color->mBackgroundColor); + aRenderingContext.FillArc(outside, 0, 180); + aRenderingContext.FillArc(outside, 180, 360); +} + + void nsFormControlHelper::PaintCircularBorder(nsIPresContext& aPresContext, nsIRenderingContext& aRenderingContext, const nsRect& aDirtyRect, nsIStyleContext* aStyleContext, PRBool aInset, nsIFrame* aForFrame, PRUint32 aWidth, PRUint32 aHeight) { + const PRUint32 standardWidth = 180; + const PRUint32 standardHeight = 180; + aRenderingContext.PushState(); + const nsStyleColor* color = (const nsStyleColor*) + aStyleContext->GetStyleData(eStyleStruct_Color); + float p2t; aPresContext.GetScaledPixelsToTwips(p2t); @@ -793,15 +842,9 @@ nsFormControlHelper::PaintCircularBorder(nsIPresContext& aPresContext, nsRect outside(0, 0, aWidth, aHeight); - aRenderingContext.SetColor(NS_RGB(192,192,192)); - aRenderingContext.FillRect(outside); - - PRBool standardSize = PR_FALSE; - if (standardSize) { + PRBool standardSize = ((aWidth == standardWidth) && (aHeight == standardHeight)); + if (PR_TRUE == standardSize) { outside.SetRect(0, 0, twelvePixels, twelvePixels); - aRenderingContext.SetColor(NS_RGB(255,255,255)); - aRenderingContext.FillArc(outside, 0, 180); - aRenderingContext.FillArc(outside, 180, 360); if (PR_TRUE == aInset) { outside.Deflate(onePixel, onePixel); @@ -812,8 +855,12 @@ nsFormControlHelper::PaintCircularBorder(nsIPresContext& aPresContext, outside.SetRect(0, 0, twelvePixels, twelvePixels); } - // DrakGray + // DrakGray +// PRUint8 borderStyle = aBorderStyle.GetBorderStyle(NS_SIDE_TOP), +// nscolor borderColor = aBorderStyle.GetBorderColor(NS_SIDE_TOP), + aRenderingContext.SetColor(NS_RGB(128,128,128)); +// aRenderingContext.SetColor(borderColor); PaintLine(aRenderingContext, 4, 0, 7, 0, PR_TRUE, 1, onePixel); PaintLine(aRenderingContext, 2, 1, 3, 1, PR_TRUE, 1, onePixel); PaintLine(aRenderingContext, 8, 1, 9, 1, PR_TRUE, 1, onePixel); @@ -823,6 +870,8 @@ nsFormControlHelper::PaintCircularBorder(nsIPresContext& aPresContext, PaintLine(aRenderingContext, 1, 8, 1, 9, PR_FALSE, 1, onePixel); // Black +// nscolor borderColor = aBorderStyle.GetBorderColor(NS_SIDE_BOTTOM); +// aRenderingContext.SetColor(borderColor); aRenderingContext.SetColor(NS_RGB(0,0,0)); PaintLine(aRenderingContext, 4, 1, 7, 1, PR_TRUE, 1, onePixel); PaintLine(aRenderingContext, 2, 2, 3, 2, PR_TRUE, 1, onePixel); @@ -847,8 +896,9 @@ nsFormControlHelper::PaintCircularBorder(nsIPresContext& aPresContext, outside.Deflate(onePixel, onePixel); outside.Deflate(onePixel, onePixel); } else { - outside.SetRect(0, 0, twelvePixels, twelvePixels); - + nsRect outside; + nsFormControlHelper::GetCircularRect(aWidth, aHeight, outside); + aRenderingContext.SetColor(NS_RGB(128,128,128)); aRenderingContext.FillArc(outside, 46, 225); aRenderingContext.SetColor(NS_RGB(255,255,255)); @@ -861,13 +911,6 @@ nsFormControlHelper::PaintCircularBorder(nsIPresContext& aPresContext, aRenderingContext.SetColor(NS_RGB(192,192,192)); aRenderingContext.FillArc(outside, 225, 360); aRenderingContext.FillArc(outside, 0, 44); - - outside.Deflate(onePixel, onePixel); - aRenderingContext.SetColor(NS_RGB(255,255,255)); - aRenderingContext.FillArc(outside, 0, 180); - aRenderingContext.FillArc(outside, 180, 360); - outside.Deflate(onePixel, onePixel); - outside.Deflate(onePixel, onePixel); } PRBool clip; diff --git a/layout/forms/nsFormControlHelper.h b/layout/forms/nsFormControlHelper.h index cd4b18a87f66..d5047d8bfb6c 100644 --- a/layout/forms/nsFormControlHelper.h +++ b/layout/forms/nsFormControlHelper.h @@ -77,6 +77,8 @@ struct nsInputDimensionSpec }; + + /** * nsFormControlHelper is the base class for frames of form controls. It * provides a uniform way of creating widgets, resizing, and painting. @@ -86,6 +88,8 @@ class nsFormControlHelper { public: + + static nscoord CalculateSize (nsIPresContext* aPresContext, nsIFormControlFrame* aFrame, const nsSize& aCSSSize, nsInputDimensionSpec& aDimensionSpec, nsSize& aBounds, PRBool& aWidthExplicit, @@ -294,7 +298,7 @@ public: float aPixelsToTwips); /** - * Paint a scaled checkmark + * Paint a checkmark * * @param aRenderingContext the rendering context * @param aPixelsToTwips scale factor for convering pixels to twips. @@ -302,15 +306,15 @@ public: * @param aHeight height in twips */ - static void PaintScaledCheckMark(nsIRenderingContext& aRenderingContext, - float aPixelsToTwips, PRUint32 aWidth, PRUint32 aHeight); + static void PaintCheckMark(nsIRenderingContext& aRenderingContext, + float aPixelsToTwips, PRUint32 aWidth, PRUint32 aHeight); /** * Paint a fixed size checkmark border * * @param aRenderingContext the rendering context * @param aPixelsToTwips scale factor for convering pixels to twips. - * @param aBackgroundColor color for background of checkbox + * @param aBackgroundColor color for background of the checkbox */ static void PaintFixedSizeCheckMarkBorder(nsIRenderingContext& aRenderingContext, @@ -349,6 +353,37 @@ public: static void PaintFocus(nsIRenderingContext& aRenderingContext, const nsRect& aDirtyRect, nsRect& aInside, nsRect& aOutside); + /** + * Get the rectangle for a circular area. To maintain the aspect ratio of the circular + * area the rectangle is offset to center the circular area within the width and height + * specified. + * + * @param aWidth width to center within + * @param aHeight height to center within + * @param aRect the computed rectangle centering the circle by setting the x and y of the rect. + */ + + static void GetCircularRect(PRUint32 aWidth, PRUint32 aHeight, nsRect& aRect); + + /** + * Paint a circular background + * + * @param aPresContext the presentation context + * @param aRenderingContext the rendering context + * @param aDirtyRect rectangle requiring update + * @param aStyleContext style context specifying colors and spacing + * @param aInset if PR_TRUE draw inset, otherwise draw outset + * @param aForFrame the frame that the scrollbar will be rendered in to + * @param aWidth width of the border in TWIPS + * @param aHeight height ofthe border in TWIPS + */ + + static void PaintCircularBackground(nsIPresContext& aPresContext, + nsIRenderingContext& aRenderingContext, + const nsRect& aDirtyRect, nsIStyleContext* aStyleContext, PRBool aInset, + nsIFrame* aForFrame, PRUint32 aWidth, PRUint32 aHeight); + + /** * Paint a circular border * diff --git a/layout/html/forms/src/nsButtonControlFrame.cpp b/layout/html/forms/src/nsButtonControlFrame.cpp index 9ae8c68797a8..41998d359f39 100644 --- a/layout/html/forms/src/nsButtonControlFrame.cpp +++ b/layout/html/forms/src/nsButtonControlFrame.cpp @@ -410,7 +410,7 @@ NS_IMETHODIMP nsButtonControlFrame::GetProperty(nsIAtom* aName, nsString& aValue nsresult nsButtonControlFrame::RequiresWidget(PRBool& aRequiresWidget) { - aRequiresWidget = PR_FALSE; + aRequiresWidget = PR_TRUE; return NS_OK; } diff --git a/layout/html/forms/src/nsCheckboxControlFrame.cpp b/layout/html/forms/src/nsCheckboxControlFrame.cpp index 61d7a99e4a81..00b1d11dbbd2 100644 --- a/layout/html/forms/src/nsCheckboxControlFrame.cpp +++ b/layout/html/forms/src/nsCheckboxControlFrame.cpp @@ -308,14 +308,12 @@ nsCheckboxControlFrame::PaintCheckBox(nsIPresContext& aPresContext, nsresult result = GetCurrentCheckState(&checked); if (PR_TRUE == checked) { // Draw check mark - //XXX: TODO Use fixed size checkmark when size matches default - //This will make the checkmark look better -->PaintFixedSizeCheckMark(aRenderingContext, p2t); const nsStyleColor* color = (const nsStyleColor*) mStyleContext->GetStyleData(eStyleStruct_Color); aRenderingContext.SetColor(color->mColor); - nsFormControlHelper::PaintScaledCheckMark(aRenderingContext, + nsFormControlHelper::PaintCheckMark(aRenderingContext, p2t, mRect.width, mRect.height); - + } PRBool clip; aRenderingContext.PopState(clip); diff --git a/layout/html/forms/src/nsFormControlFrame.cpp b/layout/html/forms/src/nsFormControlFrame.cpp index a61df00a8d33..dc992c6e09b4 100644 --- a/layout/html/forms/src/nsFormControlFrame.cpp +++ b/layout/html/forms/src/nsFormControlFrame.cpp @@ -223,102 +223,101 @@ nsFormControlFrame::Reflow(nsIPresContext& aPresContext, nsIDeviceContext* dx = nsnull; dx = aPresContext.GetDeviceContext(); - PRBool supportsWidgets = PR_TRUE; - //XXX: Temporary flag for getting GFX rendered widgets on the screen - PRBool useGfxWidgets = PR_FALSE; - - if (PR_FALSE == useGfxWidgets) { - supportsWidgets = PR_TRUE; - if (nsnull != dx) { - dx->SupportsNativeWidgets(supportsWidgets); - NS_RELEASE(dx); - } + PRBool requiresWidget = PR_TRUE; + + // Checkto see if the device context supports widgets at all + if (nsnull != dx) { + dx->SupportsNativeWidgets(requiresWidget); + NS_RELEASE(dx); } - else - supportsWidgets = PR_FALSE; + +#ifdef NS_GFX_RENDER_FORM_ELEMENTS + // Check with the frame to see if requires a widget to render + if (PR_TRUE == requiresWidget) { + RequiresWidget(requiresWidget); + } +#endif GetDesiredSize(&aPresContext, aReflowState, aDesiredSize, mWidgetSize); if (!mDidInit) { - nsIPresShell *presShell = aPresContext.GetShell(); // need to release - nsIViewManager *viewMan = presShell->GetViewManager(); // need to release - NS_RELEASE(presShell); - nsRect boundBox(0, 0, aDesiredSize.width, aDesiredSize.height); + if (PR_TRUE == requiresWidget) { + nsIPresShell *presShell = aPresContext.GetShell(); // need to release + nsIViewManager *viewMan = presShell->GetViewManager(); // need to release + NS_RELEASE(presShell); + nsRect boundBox(0, 0, aDesiredSize.width, aDesiredSize.height); - // absolutely positioned controls already have a view but not a widget - nsIView* view = nsnull; - GetView(view); - if (nsnull == view) { - result = nsRepository::CreateInstance(kViewCID, nsnull, kIViewIID, (void **)&view); - if (!NS_SUCCEEDED(result)) { - NS_ASSERTION(0, "Could not create view for form control"); - aStatus = NS_FRAME_NOT_COMPLETE; - return result; - } + // absolutely positioned controls already have a view but not a widget + nsIView* view = nsnull; + GetView(view); + if (nsnull == view) { + result = nsRepository::CreateInstance(kViewCID, nsnull, kIViewIID, (void **)&view); + if (!NS_SUCCEEDED(result)) { + NS_ASSERTION(0, "Could not create view for form control"); + aStatus = NS_FRAME_NOT_COMPLETE; + return result; + } - nsIFrame* parWithView; - nsIView *parView; + nsIFrame* parWithView; + nsIView *parView; - GetParentWithView(parWithView); - parWithView->GetView(parView); + GetParentWithView(parWithView); + parWithView->GetView(parView); - // initialize the view as hidden since we don't know the (x,y) until Paint - result = view->Init(viewMan, boundBox, parView, nsnull, nsViewVisibility_kHide); - if (NS_OK != result) { - NS_ASSERTION(0, "view initialization failed"); - aStatus = NS_FRAME_NOT_COMPLETE; - return NS_OK; - } + // initialize the view as hidden since we don't know the (x,y) until Paint + result = view->Init(viewMan, boundBox, parView, nsnull, nsViewVisibility_kHide); + if (NS_OK != result) { + NS_ASSERTION(0, "view initialization failed"); + aStatus = NS_FRAME_NOT_COMPLETE; + return NS_OK; + } - viewMan->InsertChild(parView, view, 0); - SetView(view); - } - - PRInt32 type; - GetType(&type); - const nsIID& id = GetCID(); - -#ifdef NS_GFX_RENDER_FORM_ELEMENTS - RequiresWidget(supportsWidgets); -#else - supportsWidgets = PR_TRUE; -#endif - - if ((NS_FORM_INPUT_HIDDEN != type) && (PR_TRUE == supportsWidgets)) { - // Do the following only if a widget is created - nsWidgetInitData* initData = GetWidgetInitData(aPresContext); // needs to be deleted - view->CreateWidget(id, initData); - - if (nsnull != initData) { - delete(initData); - } - - // set our widget - result = GetWidget(view, &mWidget); - if ((NS_OK == result) && mWidget) { // keep the ref on mWidget - nsIFormControl* formControl = nsnull; - result = mContent->QueryInterface(kIFormControlIID, (void**)&formControl); - if ((NS_OK == result) && formControl) { - // set the content's widget, so it can get content modified by the widget - formControl->SetWidget(mWidget); - NS_RELEASE(formControl); + viewMan->InsertChild(parView, view, 0); + SetView(view); } - // PostCreateWidget(&aPresContext, aDesiredSize.width, aDesiredSize.height); - // mDidInit = PR_TRUE; - } else { - NS_ASSERTION(0, "could not get widget"); - } - } - - PostCreateWidget(&aPresContext, aDesiredSize.width, aDesiredSize.height); - mDidInit = PR_TRUE; - if ((aDesiredSize.width != boundBox.width) || (aDesiredSize.height != boundBox.height)) { - viewMan->ResizeView(view, aDesiredSize.width, aDesiredSize.height); + PRInt32 type; + GetType(&type); + const nsIID& id = GetCID(); + + if ((NS_FORM_INPUT_HIDDEN != type) && (PR_TRUE == requiresWidget)) { + // Do the following only if a widget is created + nsWidgetInitData* initData = GetWidgetInitData(aPresContext); // needs to be deleted + view->CreateWidget(id, initData); + + if (nsnull != initData) { + delete(initData); + } + + // set our widget + result = GetWidget(view, &mWidget); + if ((NS_OK == result) && mWidget) { // keep the ref on mWidget + nsIFormControl* formControl = nsnull; + result = mContent->QueryInterface(kIFormControlIID, (void**)&formControl); + if ((NS_OK == result) && formControl) { + // set the content's widget, so it can get content modified by the widget + formControl->SetWidget(mWidget); + NS_RELEASE(formControl); + } + } else { + NS_ASSERTION(0, "could not get widget"); + } + } + + PostCreateWidget(&aPresContext, aDesiredSize.width, aDesiredSize.height); + mDidInit = PR_TRUE; + + if ((aDesiredSize.width != boundBox.width) || (aDesiredSize.height != boundBox.height)) { + viewMan->ResizeView(view, aDesiredSize.width, aDesiredSize.height); + } + + NS_IF_RELEASE(viewMan); } - - NS_IF_RELEASE(viewMan); - } + else { + PostCreateWidget(&aPresContext, aDesiredSize.width, aDesiredSize.height); + mDidInit = PR_TRUE; + } + } aDesiredSize.ascent = aDesiredSize.height; aDesiredSize.descent = 0; @@ -643,8 +642,7 @@ nsFormControlFrame::GetFont(nsIPresContext* aPresContext, } nsresult nsFormControlFrame::GetDefaultCheckState(PRBool *aState) -{ - nsresult res = NS_OK; +{ nsresult res = NS_OK; nsIDOMHTMLInputElement* inputElement; if (NS_OK == mContent->QueryInterface(kIDOMHTMLInputElementIID, (void**)&inputElement)) { res = inputElement->GetDefaultChecked(aState); diff --git a/layout/html/forms/src/nsFormControlFrame.h b/layout/html/forms/src/nsFormControlFrame.h index bfa4771cf3ca..ce0428966d64 100644 --- a/layout/html/forms/src/nsFormControlFrame.h +++ b/layout/html/forms/src/nsFormControlFrame.h @@ -40,7 +40,7 @@ class nsFormFrame; // using GFX calls, rather than creating a widget. Undefining it // causes widgets to be used for form elements. @see RequiresWidget method // to see which widgets will obey this directive. -#undef NS_GFX_RENDER_FORM_ELEMENTS +#define NS_GFX_RENDER_FORM_ELEMENTS /** * nsFormControlFrame is the base class for frames of form controls. It diff --git a/layout/html/forms/src/nsFormControlHelper.cpp b/layout/html/forms/src/nsFormControlHelper.cpp index c3233ce10341..3fa29463bf98 100644 --- a/layout/html/forms/src/nsFormControlHelper.cpp +++ b/layout/html/forms/src/nsFormControlHelper.cpp @@ -568,13 +568,12 @@ nsFormControlHelper::PaintScrollbar(nsIRenderingContext& aRenderingContext, } + void nsFormControlHelper::PaintFixedSizeCheckMark(nsIRenderingContext& aRenderingContext, float aPixelsToTwips) { - //XXX: Check mark is always draw in black. If the this code is used to Render the widget - //to the screen the color should be set using the CSS style color instead. - aRenderingContext.SetColor(NS_RGB(0, 0, 0)); + // Offsets to x,y location, These offsets are used to place the checkmark in the middle // of it's 12X12 pixel box. const PRUint32 ox = 3; @@ -630,9 +629,20 @@ nsFormControlHelper::PaintFixedSizeCheckMarkBorder(nsIRenderingContext& aRenderi //Draw a checkmark in any size. void -nsFormControlHelper::PaintScaledCheckMark(nsIRenderingContext& aRenderingContext, +nsFormControlHelper::PaintCheckMark(nsIRenderingContext& aRenderingContext, float aPixelsToTwips, PRUint32 aWidth, PRUint32 aHeight) { + // Width and height of the fixed size checkmark in TWIPS. + const PRUint32 fixedSizeCheckmarkWidth = 165; + const PRUint32 fixedSizeCheckmarkHeight = 165; + + if ((fixedSizeCheckmarkWidth == aWidth) && + (fixedSizeCheckmarkHeight == aHeight)) { + // Standard size, so draw a fixed size check mark instead of a scaled check mark. + PaintFixedSizeCheckMark(aRenderingContext, aPixelsToTwips); + return; + } + const PRUint32 checkpoints = 7; const PRUint32 checksize = 9; //This is value is determined by added 2 units to the end //of the 7X& pixel rectangle below to provide some white space @@ -773,14 +783,53 @@ nsFormControlHelper::PaintRectangularButton(nsIPresContext& aPresContext, } +void +nsFormControlHelper::GetCircularRect(PRUint32 aWidth, PRUint32 aHeight, nsRect& aRect) +{ + if (aWidth > aHeight) + aRect.SetRect((aWidth/2) - (aHeight/2), 0, aHeight, aHeight); + else + aRect.SetRect(0, (aHeight/2) - (aWidth/2), aWidth, aWidth); +} + + +void +nsFormControlHelper::PaintCircularBackground(nsIPresContext& aPresContext, + nsIRenderingContext& aRenderingContext, + const nsRect& aDirtyRect, nsIStyleContext* aStyleContext, PRBool aInset, + nsIFrame* aForFrame, PRUint32 aWidth, PRUint32 aHeight) +{ + float p2t; + aPresContext.GetScaledPixelsToTwips(p2t); + nscoord onePixel = NSIntPixelsToTwips(1, p2t); + + nsRect outside; + nsFormControlHelper::GetCircularRect(aWidth, aHeight, outside); + + outside.Deflate(onePixel, onePixel); + outside.Deflate(onePixel, onePixel); + const nsStyleColor* color = (const nsStyleColor*) + aStyleContext->GetStyleData(eStyleStruct_Color); + aRenderingContext.SetColor(color->mBackgroundColor); + aRenderingContext.FillArc(outside, 0, 180); + aRenderingContext.FillArc(outside, 180, 360); +} + + void nsFormControlHelper::PaintCircularBorder(nsIPresContext& aPresContext, nsIRenderingContext& aRenderingContext, const nsRect& aDirtyRect, nsIStyleContext* aStyleContext, PRBool aInset, nsIFrame* aForFrame, PRUint32 aWidth, PRUint32 aHeight) { + const PRUint32 standardWidth = 180; + const PRUint32 standardHeight = 180; + aRenderingContext.PushState(); + const nsStyleColor* color = (const nsStyleColor*) + aStyleContext->GetStyleData(eStyleStruct_Color); + float p2t; aPresContext.GetScaledPixelsToTwips(p2t); @@ -793,15 +842,9 @@ nsFormControlHelper::PaintCircularBorder(nsIPresContext& aPresContext, nsRect outside(0, 0, aWidth, aHeight); - aRenderingContext.SetColor(NS_RGB(192,192,192)); - aRenderingContext.FillRect(outside); - - PRBool standardSize = PR_FALSE; - if (standardSize) { + PRBool standardSize = ((aWidth == standardWidth) && (aHeight == standardHeight)); + if (PR_TRUE == standardSize) { outside.SetRect(0, 0, twelvePixels, twelvePixels); - aRenderingContext.SetColor(NS_RGB(255,255,255)); - aRenderingContext.FillArc(outside, 0, 180); - aRenderingContext.FillArc(outside, 180, 360); if (PR_TRUE == aInset) { outside.Deflate(onePixel, onePixel); @@ -812,8 +855,12 @@ nsFormControlHelper::PaintCircularBorder(nsIPresContext& aPresContext, outside.SetRect(0, 0, twelvePixels, twelvePixels); } - // DrakGray + // DrakGray +// PRUint8 borderStyle = aBorderStyle.GetBorderStyle(NS_SIDE_TOP), +// nscolor borderColor = aBorderStyle.GetBorderColor(NS_SIDE_TOP), + aRenderingContext.SetColor(NS_RGB(128,128,128)); +// aRenderingContext.SetColor(borderColor); PaintLine(aRenderingContext, 4, 0, 7, 0, PR_TRUE, 1, onePixel); PaintLine(aRenderingContext, 2, 1, 3, 1, PR_TRUE, 1, onePixel); PaintLine(aRenderingContext, 8, 1, 9, 1, PR_TRUE, 1, onePixel); @@ -823,6 +870,8 @@ nsFormControlHelper::PaintCircularBorder(nsIPresContext& aPresContext, PaintLine(aRenderingContext, 1, 8, 1, 9, PR_FALSE, 1, onePixel); // Black +// nscolor borderColor = aBorderStyle.GetBorderColor(NS_SIDE_BOTTOM); +// aRenderingContext.SetColor(borderColor); aRenderingContext.SetColor(NS_RGB(0,0,0)); PaintLine(aRenderingContext, 4, 1, 7, 1, PR_TRUE, 1, onePixel); PaintLine(aRenderingContext, 2, 2, 3, 2, PR_TRUE, 1, onePixel); @@ -847,8 +896,9 @@ nsFormControlHelper::PaintCircularBorder(nsIPresContext& aPresContext, outside.Deflate(onePixel, onePixel); outside.Deflate(onePixel, onePixel); } else { - outside.SetRect(0, 0, twelvePixels, twelvePixels); - + nsRect outside; + nsFormControlHelper::GetCircularRect(aWidth, aHeight, outside); + aRenderingContext.SetColor(NS_RGB(128,128,128)); aRenderingContext.FillArc(outside, 46, 225); aRenderingContext.SetColor(NS_RGB(255,255,255)); @@ -861,13 +911,6 @@ nsFormControlHelper::PaintCircularBorder(nsIPresContext& aPresContext, aRenderingContext.SetColor(NS_RGB(192,192,192)); aRenderingContext.FillArc(outside, 225, 360); aRenderingContext.FillArc(outside, 0, 44); - - outside.Deflate(onePixel, onePixel); - aRenderingContext.SetColor(NS_RGB(255,255,255)); - aRenderingContext.FillArc(outside, 0, 180); - aRenderingContext.FillArc(outside, 180, 360); - outside.Deflate(onePixel, onePixel); - outside.Deflate(onePixel, onePixel); } PRBool clip; diff --git a/layout/html/forms/src/nsFormControlHelper.h b/layout/html/forms/src/nsFormControlHelper.h index cd4b18a87f66..d5047d8bfb6c 100644 --- a/layout/html/forms/src/nsFormControlHelper.h +++ b/layout/html/forms/src/nsFormControlHelper.h @@ -77,6 +77,8 @@ struct nsInputDimensionSpec }; + + /** * nsFormControlHelper is the base class for frames of form controls. It * provides a uniform way of creating widgets, resizing, and painting. @@ -86,6 +88,8 @@ class nsFormControlHelper { public: + + static nscoord CalculateSize (nsIPresContext* aPresContext, nsIFormControlFrame* aFrame, const nsSize& aCSSSize, nsInputDimensionSpec& aDimensionSpec, nsSize& aBounds, PRBool& aWidthExplicit, @@ -294,7 +298,7 @@ public: float aPixelsToTwips); /** - * Paint a scaled checkmark + * Paint a checkmark * * @param aRenderingContext the rendering context * @param aPixelsToTwips scale factor for convering pixels to twips. @@ -302,15 +306,15 @@ public: * @param aHeight height in twips */ - static void PaintScaledCheckMark(nsIRenderingContext& aRenderingContext, - float aPixelsToTwips, PRUint32 aWidth, PRUint32 aHeight); + static void PaintCheckMark(nsIRenderingContext& aRenderingContext, + float aPixelsToTwips, PRUint32 aWidth, PRUint32 aHeight); /** * Paint a fixed size checkmark border * * @param aRenderingContext the rendering context * @param aPixelsToTwips scale factor for convering pixels to twips. - * @param aBackgroundColor color for background of checkbox + * @param aBackgroundColor color for background of the checkbox */ static void PaintFixedSizeCheckMarkBorder(nsIRenderingContext& aRenderingContext, @@ -349,6 +353,37 @@ public: static void PaintFocus(nsIRenderingContext& aRenderingContext, const nsRect& aDirtyRect, nsRect& aInside, nsRect& aOutside); + /** + * Get the rectangle for a circular area. To maintain the aspect ratio of the circular + * area the rectangle is offset to center the circular area within the width and height + * specified. + * + * @param aWidth width to center within + * @param aHeight height to center within + * @param aRect the computed rectangle centering the circle by setting the x and y of the rect. + */ + + static void GetCircularRect(PRUint32 aWidth, PRUint32 aHeight, nsRect& aRect); + + /** + * Paint a circular background + * + * @param aPresContext the presentation context + * @param aRenderingContext the rendering context + * @param aDirtyRect rectangle requiring update + * @param aStyleContext style context specifying colors and spacing + * @param aInset if PR_TRUE draw inset, otherwise draw outset + * @param aForFrame the frame that the scrollbar will be rendered in to + * @param aWidth width of the border in TWIPS + * @param aHeight height ofthe border in TWIPS + */ + + static void PaintCircularBackground(nsIPresContext& aPresContext, + nsIRenderingContext& aRenderingContext, + const nsRect& aDirtyRect, nsIStyleContext* aStyleContext, PRBool aInset, + nsIFrame* aForFrame, PRUint32 aWidth, PRUint32 aHeight); + + /** * Paint a circular border * diff --git a/layout/html/forms/src/nsRadioControlFrame.cpp b/layout/html/forms/src/nsRadioControlFrame.cpp index e4db1048df4a..bc9a45f9b87a 100644 --- a/layout/html/forms/src/nsRadioControlFrame.cpp +++ b/layout/html/forms/src/nsRadioControlFrame.cpp @@ -84,6 +84,7 @@ nsRadioControlFrame::GetDesiredSize(nsIPresContext* aPresContext, nsHTMLReflowMetrics& aDesiredLayoutSize, nsSize& aDesiredWidgetSize) { +#ifndef NS_GFX_RENDER_FORM_ELEMENTS float p2t; aPresContext->GetScaledPixelsToTwips(p2t); aDesiredWidgetSize.width = NSIntPixelsToTwips(NS_DESIRED_RADIOBOX_SIZE, p2t); @@ -92,6 +93,10 @@ nsRadioControlFrame::GetDesiredSize(nsIPresContext* aPresContext, aDesiredLayoutSize.height = aDesiredWidgetSize.height; aDesiredLayoutSize.ascent = aDesiredLayoutSize.height; aDesiredLayoutSize.descent = 0; +#else + nsFormControlFrame::GetDesiredSize(aPresContext,aReflowState,aDesiredLayoutSize, + aDesiredWidgetSize); +#endif } void @@ -303,11 +308,6 @@ nsRadioControlFrame::GetFrameName(nsString& aResult) const return MakeFrameName("RadioControl", aResult); } -// -// XXX: The following paint code is TEMPORARY. It is being used to get printing working -// under windows. Later it may be used to GFX-render the controls to the display. -// Expect this code to repackaged and moved to a new location in the future. -// void nsRadioControlFrame::PaintRadioButton(nsIPresContext& aPresContext, @@ -316,9 +316,17 @@ nsRadioControlFrame::PaintRadioButton(nsIPresContext& aPresContext, { aRenderingContext.PushState(); + const nsStyleColor* color = (const nsStyleColor*) + mStyleContext->GetStyleData(eStyleStruct_Color); + + //XXX: This is backwards for now. The PaintCircular border code actually draws pie slices. + nsFormControlHelper::PaintCircularBorder(aPresContext,aRenderingContext, aDirtyRect, mStyleContext, PR_FALSE, this, mRect.width, mRect.height); + nsFormControlHelper::PaintCircularBackground(aPresContext,aRenderingContext, + aDirtyRect, mStyleContext, PR_FALSE, this, mRect.width, mRect.height); + PRBool checked = PR_TRUE; GetCurrentCheckState(&checked); // Get check state from the content model if (PR_TRUE == checked) { @@ -329,14 +337,16 @@ nsRadioControlFrame::PaintRadioButton(nsIPresContext& aPresContext, nscoord onePixel = NSIntPixelsToTwips(1, p2t); nscoord twelvePixels = NSIntPixelsToTwips(12, p2t); - nsRect outside(0, 0, twelvePixels, twelvePixels); - + + nsRect outside; + nsFormControlHelper::GetCircularRect(mRect.width, mRect.height, outside); + outside.Deflate(onePixel, onePixel); outside.Deflate(onePixel, onePixel); outside.Deflate(onePixel, onePixel); outside.Deflate(onePixel, onePixel); - aRenderingContext.SetColor(NS_RGB(0,0,0)); + aRenderingContext.SetColor(color->mColor); aRenderingContext.FillArc(outside, 0, 180); aRenderingContext.FillArc(outside, 180, 360); }