From ea9f077c63a3186decbc493baa3c779e0800eef7 Mon Sep 17 00:00:00 2001 From: "rods%netscape.com" Date: Tue, 15 Dec 1998 19:03:36 +0000 Subject: [PATCH] Added painting methods for printing git-svn-id: svn://10.0.0.236/trunk@16450 18797224-902f-48f8-a5cc-f745e15eee43 --- mozilla/layout/forms/nsFormControlFrame.cpp | 235 ++++++++++++++--- mozilla/layout/forms/nsFormControlFrame.h | 92 ++++++- mozilla/layout/forms/nsTextControlFrame.cpp | 119 +++++++-- mozilla/layout/forms/nsTextControlFrame.h | 4 +- .../html/forms/src/nsButtonControlFrame.h | 10 + .../html/forms/src/nsFormControlFrame.cpp | 235 ++++++++++++++--- .../html/forms/src/nsFormControlFrame.h | 92 ++++++- .../html/forms/src/nsSelectControlFrame.cpp | 245 +++++++++++++++++- .../html/forms/src/nsTextControlFrame.cpp | 119 +++++++-- .../html/forms/src/nsTextControlFrame.h | 4 +- 10 files changed, 1023 insertions(+), 132 deletions(-) diff --git a/mozilla/layout/forms/nsFormControlFrame.cpp b/mozilla/layout/forms/nsFormControlFrame.cpp index 12f116ebcd2..b6b622f7edb 100644 --- a/mozilla/layout/forms/nsFormControlFrame.cpp +++ b/mozilla/layout/forms/nsFormControlFrame.cpp @@ -48,6 +48,8 @@ #include "nsFormFrame.h" #include "nsIContent.h" #include "nsGlobalVariables.h" +#include "nsStyleUtil.h" + static NS_DEFINE_IID(kIWidgetIID, NS_IWIDGET_IID); static NS_DEFINE_IID(kIFormControlIID, NS_IFORMCONTROL_IID); @@ -334,15 +336,15 @@ nsFormControlFrame::Reflow(nsIPresContext& aPresContext, GetView(view); if (nsnull == view) { nsresult result = - nsRepository::CreateInstance(kViewCID, nsnull, kIViewIID, (void **)&view); - if (NS_OK != result) { - NS_ASSERTION(0, "Could not create view for form control"); + nsRepository::CreateInstance(kViewCID, nsnull, kIViewIID, (void **)&view); + if (NS_OK != result) { + NS_ASSERTION(0, "Could not create view for form control"); aStatus = NS_FRAME_NOT_COMPLETE; return result; - } - nsIPresShell *presShell = aPresContext.GetShell(); // need to release - nsIViewManager *viewMan = presShell->GetViewManager(); // need to release - NS_RELEASE(presShell); + } + nsIPresShell *presShell = aPresContext.GetShell(); // need to release + nsIViewManager *viewMan = presShell->GetViewManager(); // need to release + NS_RELEASE(presShell); GetDesiredSize(&aPresContext, aReflowState, aDesiredSize, mWidgetSize); @@ -350,23 +352,23 @@ nsFormControlFrame::Reflow(nsIPresContext& aPresContext, nsRect boundBox(0, 0, aDesiredSize.width, aDesiredSize.height); nsIFrame* parWithView; - nsIView *parView; + nsIView *parView; GetParentWithView(parWithView); - parWithView->GetView(parView); + parWithView->GetView(parView); - // initialize the view as hidden since we don't know the (x,y) until Paint + // 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"); + NS_ASSERTION(0, "view initialization failed"); aStatus = NS_FRAME_NOT_COMPLETE; return NS_OK; - } + } viewMan->InsertChild(parView, view, 0); - const nsIID& id = GetCID(); + const nsIID& id = GetCID(); nsWidgetInitData* initData = GetWidgetInitData(aPresContext); // needs to be deleted view->CreateWidget(id, initData); @@ -374,9 +376,9 @@ nsFormControlFrame::Reflow(nsIPresContext& aPresContext, delete(initData); } - // set our widget - result = GetWidget(view, &mWidget); - if ((NS_OK == result) && mWidget) { // keep the ref on mWidget + // 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) { @@ -386,9 +388,9 @@ nsFormControlFrame::Reflow(nsIPresContext& aPresContext, } PostCreateWidget(&aPresContext, aDesiredSize.width, aDesiredSize.height); mDidInit = PR_TRUE; - } else { - NS_ASSERTION(0, "could not get widget"); - } + } else { + NS_ASSERTION(0, "could not get widget"); + } SetView(view); @@ -396,7 +398,7 @@ nsFormControlFrame::Reflow(nsIPresContext& aPresContext, viewMan->ResizeView(view, aDesiredSize.width, aDesiredSize.height); } - NS_IF_RELEASE(viewMan); + NS_IF_RELEASE(viewMan); } else { GetDesiredSize(&aPresContext, aReflowState, aDesiredSize, mWidgetSize); @@ -411,7 +413,7 @@ nsFormControlFrame::Reflow(nsIPresContext& aPresContext, if (nsnull != aDesiredSize.maxElementSize) { aDesiredSize.maxElementSize->width = aDesiredSize.width; - aDesiredSize.maxElementSize->height = aDesiredSize.height; + aDesiredSize.maxElementSize->height = aDesiredSize.height; } aStatus = NS_FRAME_COMPLETE; @@ -649,24 +651,24 @@ NS_METHOD nsFormControlFrame::HandleEvent(nsIPresContext& aPresContext, GetType(&type); switch (aEvent->message) { case NS_MOUSE_ENTER: - mLastMouseState = eMouseEnter; - break; + mLastMouseState = eMouseEnter; + break; case NS_MOUSE_LEFT_BUTTON_DOWN: if (NS_FORM_INPUT_IMAGE == type) { - mLastMouseState = eMouseDown; + mLastMouseState = eMouseDown; } else { - mLastMouseState = (eMouseEnter == mLastMouseState) ? eMouseDown : eMouseNone; + mLastMouseState = (eMouseEnter == mLastMouseState) ? eMouseDown : eMouseNone; } - break; + break; case NS_MOUSE_LEFT_BUTTON_UP: - if (eMouseDown == mLastMouseState) { + if (eMouseDown == mLastMouseState) { MouseClicked(&aPresContext); - } - mLastMouseState = eMouseEnter; - break; + } + mLastMouseState = eMouseEnter; + break; case NS_MOUSE_EXIT: - mLastMouseState = eMouseNone; - break; + mLastMouseState = eMouseNone; + break; case NS_KEY_DOWN: if (NS_KEY_EVENT == aEvent->eventStructType) { nsKeyEvent* keyEvent = (nsKeyEvent*)aEvent; @@ -818,14 +820,14 @@ nsFormControlFrame::CalculateSize (nsIPresContext* aPresContext, nsFormControlFr charWidth = GetTextSize(*aPresContext, aFrame, col, aBounds, aRendContext); aRowHeight = aBounds.height; // XXX aBounds.height has CSS_NOTSET } - if (aSpec.mColSizeAttrInPixels) { - aWidthExplicit = PR_TRUE; - } + if (aSpec.mColSizeAttrInPixels) { + aWidthExplicit = PR_TRUE; + } } else { if (CSS_NOTSET != aCSSSize.width) { // css provides width aBounds.width = (aCSSSize.width > 0) ? aCSSSize.width : 1; - aWidthExplicit = PR_TRUE; + aWidthExplicit = PR_TRUE; } else { if (NS_CONTENT_ATTR_HAS_VALUE == valStatus) { // use width of initial value @@ -866,7 +868,7 @@ nsFormControlFrame::CalculateSize (nsIPresContext* aPresContext, nsFormControlFr } else if (CSS_NOTSET != aCSSSize.height) { // css provides height aBounds.height = (aCSSSize.height > 0) ? aCSSSize.height : 1; - aHeightExplicit = PR_TRUE; + aHeightExplicit = PR_TRUE; } else { // use default height in num lines if (0 == charWidth) { @@ -959,6 +961,11 @@ nsFormControlFrame::Reset() { } +// +// 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 nsFormControlFrame::DrawLine(nsIRenderingContext& aRenderingContext, @@ -996,4 +1003,158 @@ nsFormControlFrame::DrawLine(nsIRenderingContext& aRenderingContext, } +//--------------------------------------------------------------------------- +//--------------------------------------------------------------------------- +//--------------------------------------------------------------------------- +// Offset for arrow centerpoint +const nscoord nsArrowOffsetX = 3; +const nscoord nsArrowOffsetY = 3; +nscoord nsArrowRightPoints[] = {0, 0, 0, 6, 6, 3 }; +nscoord nsArrowLeftPoints[] = {0, 3, 6, 0, 6, 6 }; +nscoord nsArrowUpPoints[] = {3, 0, 6, 6, 0, 6 }; //{0, 6, 3, 0, 6, 6 }; +nscoord nsArrowDownPoints[] = {0, 0, 3, 6, 6, 0 }; + +//--------------------------------------------------------------------------- +void +nsFormControlFrame::SetupPoints(PRUint32 aNumberOfPoints, nscoord* points, nsPoint* polygon, nscoord aScaleFactor, nscoord aX, nscoord aY) +{ + const nscoord arrowOffsetX = 3 * aScaleFactor; + const nscoord arrowOffsetY = 3 * aScaleFactor; + + PRUint32 i = 0; + PRUint32 count = 0; + for (i = 0; i < aNumberOfPoints; i++) { + polygon[i].x = (points[count] * aScaleFactor) + aX - arrowOffsetX; + count++; + polygon[i].y = (points[count] * aScaleFactor) + aY - arrowOffsetY; + count++; + } + polygon[i].x = (points[0] * aScaleFactor) + aX - arrowOffsetX; + polygon[i].y = (points[1] * aScaleFactor) + aY - arrowOffsetY; +} + + + +//--------------------------------------------------------------------------- +void +nsFormControlFrame::DrawArrowGlyph(nsIRenderingContext& aRenderingContext, + nscoord aSX, nscoord aSY, nsArrowDirection aArrowDirection, + nscoord aOnePixel) +{ + nsPoint polygon[4]; + + switch(aArrowDirection) + { + case eArrowDirection_Left: + SetupPoints(3, nsArrowLeftPoints, polygon, aOnePixel, aSX, aSY); + break; + + case eArrowDirection_Right: + SetupPoints(3, nsArrowRightPoints, polygon, aOnePixel, aSX, aSY); + break; + + case eArrowDirection_Up: + SetupPoints(3, nsArrowUpPoints, polygon, aOnePixel, aSX, aSY); + break; + + case eArrowDirection_Down: + SetupPoints(3, nsArrowDownPoints, polygon, aOnePixel, aSX, aSY); + break; + } + + aRenderingContext.FillPolygon(polygon, 3); +} + +//--------------------------------------------------------------------------- +void +nsFormControlFrame::DrawArrow(nsArrowDirection aArrowDirection, + nsIRenderingContext& aRenderingContext, + nsIPresContext& aPresContext, + const nsRect& aDirtyRect, + nsRect& aRect, + nscoord aOnePixel, + const nsStyleColor& aColor, + const nsStyleSpacing& aSpacing, + nsIFrame* aForFrame, + nsRect& aFrameRect) +{ + // Draw border using CSS + nsCSSRendering::PaintBackground(aPresContext, aRenderingContext, aForFrame, + aDirtyRect, aRect, aColor, 0, 0); + nsCSSRendering::PaintBorder(aPresContext, aRenderingContext, aForFrame, + aDirtyRect, aRect, aSpacing, 0); + + // Draw the glyph in black + aRenderingContext.SetColor(NS_RGB(0, 0, 0)); + // Draw arrow centered in the rectangle + DrawArrowGlyph(aRenderingContext, aRect.x + (aRect.width / 2), aRect.y + (aRect.height / 2), aArrowDirection, aOnePixel); + +} + +//--------------------------------------------------------------------------- +void +nsFormControlFrame::DrawScrollbar(nsIRenderingContext& aRenderingContext, + nsIPresContext& aPresContext, + const nsRect& aDirtyRect, + nsRect& aRect, + PRBool aHorizontal, + nscoord aOnePixel, + nsIStyleContext* aScrollbarStyleContext, + nsIStyleContext* aScrollbarArrowStyleContext, + nsIFrame* aForFrame, + nsRect& aFrameRect) +{ + // Get the Scrollbar's Style structs + const nsStyleSpacing* scrollbarSpacing = + (const nsStyleSpacing*)aScrollbarStyleContext->GetStyleData(eStyleStruct_Spacing); + const nsStyleColor* scrollbarColor = + (const nsStyleColor*)aScrollbarStyleContext->GetStyleData(eStyleStruct_Color); + + // Get the Scrollbar's Arrow's Style structs + const nsStyleSpacing* arrowSpacing = + (const nsStyleSpacing*)aScrollbarArrowStyleContext->GetStyleData(eStyleStruct_Spacing); + const nsStyleColor* arrowColor = + (const nsStyleColor*)aScrollbarArrowStyleContext->GetStyleData(eStyleStruct_Color); + + // Draw background for scrollbar + nsCSSRendering::PaintBackground(aPresContext, aRenderingContext, aForFrame, + aDirtyRect, aRect, *scrollbarColor, 0, 0); + + if (PR_TRUE == aHorizontal) { + // Draw horizontal Arrow + nscoord arrowWidth = aRect.height; + nsRect arrowLeftRect(aRect.x, aRect.y, arrowWidth, arrowWidth); + DrawArrow(eArrowDirection_Left,aRenderingContext,aPresContext, + aDirtyRect, arrowLeftRect,aOnePixel, *arrowColor, *arrowSpacing, aForFrame, aFrameRect); + + nsRect thumbRect(aRect.x+arrowWidth, aRect.y, arrowWidth, arrowWidth); + nsCSSRendering::PaintBackground(aPresContext, aRenderingContext, aForFrame, + aDirtyRect, thumbRect, *arrowColor, 0, 0); + nsCSSRendering::PaintBorder(aPresContext, aRenderingContext, aForFrame, + aDirtyRect, thumbRect, *arrowSpacing, 0); + + nsRect arrowRightRect(aRect.x + (aRect.width - arrowWidth), aRect.y, arrowWidth, arrowWidth); + DrawArrow(eArrowDirection_Right,aRenderingContext,aPresContext, + aDirtyRect, arrowRightRect,aOnePixel, *arrowColor, *arrowSpacing, aForFrame, aFrameRect); + + } + else { + // Draw vertical arrow + nscoord arrowHeight = aRect.width; + nsRect arrowUpRect(aRect.x, aRect.y, arrowHeight, arrowHeight); + DrawArrow(eArrowDirection_Up,aRenderingContext,aPresContext, + aDirtyRect, arrowUpRect,aOnePixel, *arrowColor, *arrowSpacing, aForFrame, aFrameRect); + + nsRect thumbRect(aRect.x, aRect.y+arrowHeight, arrowHeight, arrowHeight); + nsCSSRendering::PaintBackground(aPresContext, aRenderingContext, aForFrame, + aDirtyRect, thumbRect, *arrowColor, 0, 0); + nsCSSRendering::PaintBorder(aPresContext, aRenderingContext, aForFrame, + aDirtyRect, thumbRect, *arrowSpacing, 0); + + nsRect arrowDownRect(aRect.x, aRect.y + (aRect.height - arrowHeight), arrowHeight, arrowHeight); + DrawArrow(eArrowDirection_Down,aRenderingContext,aPresContext, + aDirtyRect, arrowDownRect,aOnePixel, *arrowColor, *arrowSpacing, aForFrame, aFrameRect); + } + +} diff --git a/mozilla/layout/forms/nsFormControlFrame.h b/mozilla/layout/forms/nsFormControlFrame.h index 2fd42a07c83..81aef7f503c 100644 --- a/mozilla/layout/forms/nsFormControlFrame.h +++ b/mozilla/layout/forms/nsFormControlFrame.h @@ -25,6 +25,7 @@ #include "nsIWidget.h" #include "nsLeafFrame.h" #include "nsCoord.h" +#include "nsIStyleContext.h" class nsIView; class nsIPresContext; @@ -255,25 +256,102 @@ protected: //nscoord GetStyleDim(nsIPresContext& aPresContext, nscoord aMaxDim, // nscoord aMaxWidth, const nsStyleCoord& aCoord); +// +// 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. +// + + + /** + * Enumeration of possible mouse states used to detect mouse clicks + */ + enum nsArrowDirection { + eArrowDirection_Left, + eArrowDirection_Right, + eArrowDirection_Up, + eArrowDirection_Down + }; + + /** + * Setup an array of Points + */ + + static void SetupPoints(PRUint32 aNumberOfPoints, nscoord* points, + nsPoint* polygon, nscoord aScaleFactor, nscoord aX, nscoord aY); + /** * Draw a fat line. The line is drawn as a polygon with a specified width. - * Utility used for rendering a form control during printing. - * + * Utility used for rendering a form control during printing. + * * @param aRenderingContext the rendering context * @param aSX starting x in pixels - * @param aSY starting y in pixels - * @param aEX ending x in pixels - * @param aEY ending y in pixels + * @param aSY starting y in pixels + * @param aEX ending x in pixels + * @param aEY ending y in pixels * @param aHorz PR_TRUE if aWidth is added to x coordinates to form polygon. If - * PR_FALSE then aWidth as added to the y coordinates. + * PR_FALSE then aWidth as added to the y coordinates. * @param aOnePixel number of twips in a single pixel. */ - void DrawLine(nsIRenderingContext& aRenderingContext, + static void DrawLine(nsIRenderingContext& aRenderingContext, nscoord aSX, nscoord aSY, nscoord aEX, nscoord aEY, PRBool aHorz, nscoord aWidth, nscoord aOnePixel); + /** + * Draw a arrow glyph + * + * @param aRenderingContext the rendering context + * @param aSX upper left x coordinate pixels + * @param aSY upper left y coordinate pixels + * @param aType @see nsArrowDirection + * @param aOnePixel number of twips in a single pixel. + */ + + static void DrawArrowGlyph(nsIRenderingContext& aRenderingContext, + nscoord aSX, nscoord aSY, nsArrowDirection aArrowDirection, + nscoord aOnePixel); + + /** + * Draw a arrow + * + * @param aRenderingContext the rendering context + * @param aRect location and size of in pixels + * @param aType @see nsArrowDirection + * @param aOnePixel number of twips in a single pixel. + */ + + static void DrawArrow(nsArrowDirection aArrowDirection, + nsIRenderingContext& aRenderingContext, + nsIPresContext& aPresContext, + const nsRect& aDirtyRect, + nsRect& aRect, + nscoord aOnePixel, + const nsStyleColor& aColor, + const nsStyleSpacing& aSpacing, + nsIFrame* aForFrame, + nsRect& aFrameRect); + /** + * Draw a scrollbar + * + * @param aRenderingContext the rendering context + * @param aHorizontal if TRUE a horizontal scrollbar is drawn, if FALSE a vertical scrollbar is drawn + * @param aOnePixel number of twips in a single pixel. + */ + + static void DrawScrollbar(nsIRenderingContext& aRenderingContext, + nsIPresContext& aPresContext, + const nsRect& aDirtyRect, + nsRect& aRect, + PRBool aHorizontal, + nscoord aOnePixel, + nsIStyleContext* aScrollbarStyleContext, + nsIStyleContext* aScrollbarArrowStyleContext, + nsIFrame* aForFrame, + nsRect& aFrameRect); + + nsMouseState mLastMouseState; nsIWidget* mWidget; nsSize mWidgetSize; diff --git a/mozilla/layout/forms/nsTextControlFrame.cpp b/mozilla/layout/forms/nsTextControlFrame.cpp index 12bd5609dfe..51c5d2880fa 100644 --- a/mozilla/layout/forms/nsTextControlFrame.cpp +++ b/mozilla/layout/forms/nsTextControlFrame.cpp @@ -210,11 +210,27 @@ nsTextControlFrame::GetDesiredSize(nsIPresContext* aPresContext, } if (NS_FORM_TEXTAREA == type) { - float p2t = aPresContext->GetPixelsToTwips(); - nscoord scrollbarWidth = GetScrollbarWidth(p2t); + nscoord scrollbarWidth = 0; + nscoord scrollbarHeight = 0; + float scale; + float p2t = aPresContext->GetPixelsToTwips(); + nsIDeviceContext* dx = nsnull; + dx = aPresContext->GetDeviceContext(); + if (nsnull != dx) { + float sbWidth; + float sbHeight; + dx->GetCanonicalPixelScale(scale); + dx->GetScrollBarDimensions(sbWidth, sbHeight); + scrollbarWidth = PRInt32(sbWidth * scale); + scrollbarHeight = PRInt32(sbHeight * scale); + NS_RELEASE(dx); + } else { + scrollbarWidth = GetScrollbarWidth(p2t); + scrollbarHeight = scrollbarWidth; + } if (!heightExplicit) { - size.height += scrollbarWidth; + size.height += scrollbarHeight; } if (!widthExplicit) { size.width += scrollbarWidth; @@ -484,14 +500,6 @@ nsTextControlFrame::GetFrameName(nsString& aResult) const return MakeFrameName("TextControl", aResult); } -void nsTextControlFrame::GetCurrentText(nsString & aText) -{ - nsIDOMHTMLInputElement* inputElement; - if (NS_OK == mContent->QueryInterface(kIDOMHTMLInputElementIID, (void**)&inputElement)) { - inputElement->GetValue(aText); - NS_RELEASE(inputElement); - } -} void nsTextControlFrame::PaintTextControl(nsIPresContext& aPresContext, @@ -501,6 +509,7 @@ nsTextControlFrame::PaintTextControl(nsIPresContext& aPresContext, #ifdef XP_PC aRenderingContext.PushState(); + nsFormControlFrame::Paint(aPresContext, aRenderingContext, aDirtyRect); const nsStyleSpacing* spacing = @@ -554,17 +563,97 @@ nsTextControlFrame::PaintTextControl(nsIPresContext& aPresContext, nscoord textWidth; nscoord textHeight; nsString text; - GetCurrentText(text); + + GetText(&text); aRenderingContext.GetWidth(text, textWidth); nsIFontMetrics* metrics; context->GetMetricsFor(font, metrics); metrics->GetHeight(textHeight); - nscoord x = inside.x + onePixel + onePixel; - nscoord y = ((inside.height - textHeight) / 2) + inside.y; + PRInt32 type; + GetType(&type); + if (NS_FORM_INPUT_TEXT == type || NS_FORM_INPUT_PASSWORD == type) { + nscoord x = inside.x + onePixel + onePixel; + nscoord y; + + if (NS_FORM_INPUT_TEXT == type) { + y = ((inside.height - textHeight) / 2) + inside.y; + } else { + metrics->GetMaxAscent(textHeight); + y = ((inside.height - textHeight) / 2) + inside.y; + PRInt32 i; + PRInt32 len = text.Length(); + text.SetLength(0); + for (i=0;iGetCanonicalPixelScale(scale); + context->GetScrollBarDimensions(sbWidth, sbHeight); + PRInt32 scrollbarScaledWidth = PRInt32(sbWidth * scale); + PRInt32 scrollbarScaledHeight = PRInt32(sbWidth * scale); + + inside.width -= scrollbarScaledWidth; + inside.height -= scrollbarScaledHeight; + PRBool clipEmpty; + aRenderingContext.PushState(); + aRenderingContext.SetClipRect(inside, nsClipCombine_kReplace, clipEmpty); + + nscoord x = inside.x + onePixel; + nscoord y = inside.y + onePixel; + + // Draw multi-line text + PRInt32 oldPos = 0; + PRInt32 pos = text.Find('\n', 0); + while (1) { + nsString substr; + if (-1 == pos) { + text.Right(substr, text.Length()-oldPos); + aRenderingContext.DrawString(substr, x, y, 0); + break; + } + text.Left(substr, pos); + aRenderingContext.DrawString(substr, x, y, 0); + y += textHeight; + pos++; + oldPos = pos; + pos = text.Find('\n', pos); + } + + + aRenderingContext.PopState(clipEmpty); + + // Scrollbars + const nsStyleColor* myColor = (const nsStyleColor*)mStyleContext->GetStyleData(eStyleStruct_Color); + nsIAtom * sbAtom = NS_NewAtom(":SCROLLBAR-LOOK"); + nsIStyleContext* scrollbarStyle = aPresContext.ResolvePseudoStyleContextFor(mContent, sbAtom, mStyleContext); + NS_RELEASE(sbAtom); + sbAtom = NS_NewAtom(":SCROLLBAR-ARROW-LOOK"); + nsIStyleContext* arrowStyle = aPresContext.ResolvePseudoStyleContextFor(mContent, sbAtom, mStyleContext); + NS_RELEASE(sbAtom); + + nsRect srect(mRect.width-scrollbarScaledWidth-(2*onePixel), 2*onePixel, scrollbarScaledWidth, mRect.height-(onePixel*4)-scrollbarScaledWidth); + + DrawScrollbar(aRenderingContext,aPresContext, aDirtyRect, srect, PR_FALSE, onePixel, + scrollbarStyle, arrowStyle, this, mRect); + // Horizontal + srect.SetRect(2*onePixel, mRect.height-scrollbarScaledHeight-(2*onePixel), mRect.width-(onePixel*4)-scrollbarScaledHeight, scrollbarScaledHeight); + DrawScrollbar(aRenderingContext,aPresContext, aDirtyRect, srect, PR_TRUE, onePixel, + scrollbarStyle, arrowStyle, this, mRect); + + // Draw the small rect "gap" in the bottom right that the two scrollbars don't cover + const nsStyleColor* sbColor = (const nsStyleColor*)scrollbarStyle->GetStyleData(eStyleStruct_Color); + srect.SetRect(mRect.width-scrollbarScaledWidth-(2*onePixel), mRect.height-scrollbarScaledHeight-(onePixel*2), scrollbarScaledWidth, scrollbarScaledHeight); + nsCSSRendering::PaintBackground(aPresContext, aRenderingContext, this, + aDirtyRect, srect, *sbColor, 0, 0); + } + - aRenderingContext.DrawString(text, x, y, 0); NS_RELEASE(context); PRBool status; diff --git a/mozilla/layout/forms/nsTextControlFrame.h b/mozilla/layout/forms/nsTextControlFrame.h index b9105657471..5f24f568eda 100644 --- a/mozilla/layout/forms/nsTextControlFrame.h +++ b/mozilla/layout/forms/nsTextControlFrame.h @@ -62,13 +62,11 @@ public: NS_IMETHOD GetCursor(nsIPresContext& aPresContext, nsPoint& aPoint, PRInt32& aCursor); - // + // // XXX: The following paint methods are 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. // - virtual void GetCurrentText(nsString & aText); - NS_IMETHOD Paint(nsIPresContext& aPresContext, nsIRenderingContext& aRenderingContext, const nsRect& aDirtyRect); diff --git a/mozilla/layout/html/forms/src/nsButtonControlFrame.h b/mozilla/layout/html/forms/src/nsButtonControlFrame.h index 28acd25275f..e46093e9d20 100644 --- a/mozilla/layout/html/forms/src/nsButtonControlFrame.h +++ b/mozilla/layout/html/forms/src/nsButtonControlFrame.h @@ -73,6 +73,16 @@ protected: const nsHTMLReflowState& aReflowState, nsHTMLReflowMetrics& aDesiredLayoutSize, nsSize& aDesiredWidgetSize); + // + // XXX: The following methods are TEMPORARY. They are 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. + + virtual void PaintButton(nsIPresContext& aPresContext, + nsIRenderingContext& aRenderingContext, + const nsRect& aDirtyRect); + + // XXX: End of the temporary methods nsFileControlFrame* mFileControlFrame; // for browse buttons only }; diff --git a/mozilla/layout/html/forms/src/nsFormControlFrame.cpp b/mozilla/layout/html/forms/src/nsFormControlFrame.cpp index 12f116ebcd2..b6b622f7edb 100644 --- a/mozilla/layout/html/forms/src/nsFormControlFrame.cpp +++ b/mozilla/layout/html/forms/src/nsFormControlFrame.cpp @@ -48,6 +48,8 @@ #include "nsFormFrame.h" #include "nsIContent.h" #include "nsGlobalVariables.h" +#include "nsStyleUtil.h" + static NS_DEFINE_IID(kIWidgetIID, NS_IWIDGET_IID); static NS_DEFINE_IID(kIFormControlIID, NS_IFORMCONTROL_IID); @@ -334,15 +336,15 @@ nsFormControlFrame::Reflow(nsIPresContext& aPresContext, GetView(view); if (nsnull == view) { nsresult result = - nsRepository::CreateInstance(kViewCID, nsnull, kIViewIID, (void **)&view); - if (NS_OK != result) { - NS_ASSERTION(0, "Could not create view for form control"); + nsRepository::CreateInstance(kViewCID, nsnull, kIViewIID, (void **)&view); + if (NS_OK != result) { + NS_ASSERTION(0, "Could not create view for form control"); aStatus = NS_FRAME_NOT_COMPLETE; return result; - } - nsIPresShell *presShell = aPresContext.GetShell(); // need to release - nsIViewManager *viewMan = presShell->GetViewManager(); // need to release - NS_RELEASE(presShell); + } + nsIPresShell *presShell = aPresContext.GetShell(); // need to release + nsIViewManager *viewMan = presShell->GetViewManager(); // need to release + NS_RELEASE(presShell); GetDesiredSize(&aPresContext, aReflowState, aDesiredSize, mWidgetSize); @@ -350,23 +352,23 @@ nsFormControlFrame::Reflow(nsIPresContext& aPresContext, nsRect boundBox(0, 0, aDesiredSize.width, aDesiredSize.height); nsIFrame* parWithView; - nsIView *parView; + nsIView *parView; GetParentWithView(parWithView); - parWithView->GetView(parView); + parWithView->GetView(parView); - // initialize the view as hidden since we don't know the (x,y) until Paint + // 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"); + NS_ASSERTION(0, "view initialization failed"); aStatus = NS_FRAME_NOT_COMPLETE; return NS_OK; - } + } viewMan->InsertChild(parView, view, 0); - const nsIID& id = GetCID(); + const nsIID& id = GetCID(); nsWidgetInitData* initData = GetWidgetInitData(aPresContext); // needs to be deleted view->CreateWidget(id, initData); @@ -374,9 +376,9 @@ nsFormControlFrame::Reflow(nsIPresContext& aPresContext, delete(initData); } - // set our widget - result = GetWidget(view, &mWidget); - if ((NS_OK == result) && mWidget) { // keep the ref on mWidget + // 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) { @@ -386,9 +388,9 @@ nsFormControlFrame::Reflow(nsIPresContext& aPresContext, } PostCreateWidget(&aPresContext, aDesiredSize.width, aDesiredSize.height); mDidInit = PR_TRUE; - } else { - NS_ASSERTION(0, "could not get widget"); - } + } else { + NS_ASSERTION(0, "could not get widget"); + } SetView(view); @@ -396,7 +398,7 @@ nsFormControlFrame::Reflow(nsIPresContext& aPresContext, viewMan->ResizeView(view, aDesiredSize.width, aDesiredSize.height); } - NS_IF_RELEASE(viewMan); + NS_IF_RELEASE(viewMan); } else { GetDesiredSize(&aPresContext, aReflowState, aDesiredSize, mWidgetSize); @@ -411,7 +413,7 @@ nsFormControlFrame::Reflow(nsIPresContext& aPresContext, if (nsnull != aDesiredSize.maxElementSize) { aDesiredSize.maxElementSize->width = aDesiredSize.width; - aDesiredSize.maxElementSize->height = aDesiredSize.height; + aDesiredSize.maxElementSize->height = aDesiredSize.height; } aStatus = NS_FRAME_COMPLETE; @@ -649,24 +651,24 @@ NS_METHOD nsFormControlFrame::HandleEvent(nsIPresContext& aPresContext, GetType(&type); switch (aEvent->message) { case NS_MOUSE_ENTER: - mLastMouseState = eMouseEnter; - break; + mLastMouseState = eMouseEnter; + break; case NS_MOUSE_LEFT_BUTTON_DOWN: if (NS_FORM_INPUT_IMAGE == type) { - mLastMouseState = eMouseDown; + mLastMouseState = eMouseDown; } else { - mLastMouseState = (eMouseEnter == mLastMouseState) ? eMouseDown : eMouseNone; + mLastMouseState = (eMouseEnter == mLastMouseState) ? eMouseDown : eMouseNone; } - break; + break; case NS_MOUSE_LEFT_BUTTON_UP: - if (eMouseDown == mLastMouseState) { + if (eMouseDown == mLastMouseState) { MouseClicked(&aPresContext); - } - mLastMouseState = eMouseEnter; - break; + } + mLastMouseState = eMouseEnter; + break; case NS_MOUSE_EXIT: - mLastMouseState = eMouseNone; - break; + mLastMouseState = eMouseNone; + break; case NS_KEY_DOWN: if (NS_KEY_EVENT == aEvent->eventStructType) { nsKeyEvent* keyEvent = (nsKeyEvent*)aEvent; @@ -818,14 +820,14 @@ nsFormControlFrame::CalculateSize (nsIPresContext* aPresContext, nsFormControlFr charWidth = GetTextSize(*aPresContext, aFrame, col, aBounds, aRendContext); aRowHeight = aBounds.height; // XXX aBounds.height has CSS_NOTSET } - if (aSpec.mColSizeAttrInPixels) { - aWidthExplicit = PR_TRUE; - } + if (aSpec.mColSizeAttrInPixels) { + aWidthExplicit = PR_TRUE; + } } else { if (CSS_NOTSET != aCSSSize.width) { // css provides width aBounds.width = (aCSSSize.width > 0) ? aCSSSize.width : 1; - aWidthExplicit = PR_TRUE; + aWidthExplicit = PR_TRUE; } else { if (NS_CONTENT_ATTR_HAS_VALUE == valStatus) { // use width of initial value @@ -866,7 +868,7 @@ nsFormControlFrame::CalculateSize (nsIPresContext* aPresContext, nsFormControlFr } else if (CSS_NOTSET != aCSSSize.height) { // css provides height aBounds.height = (aCSSSize.height > 0) ? aCSSSize.height : 1; - aHeightExplicit = PR_TRUE; + aHeightExplicit = PR_TRUE; } else { // use default height in num lines if (0 == charWidth) { @@ -959,6 +961,11 @@ nsFormControlFrame::Reset() { } +// +// 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 nsFormControlFrame::DrawLine(nsIRenderingContext& aRenderingContext, @@ -996,4 +1003,158 @@ nsFormControlFrame::DrawLine(nsIRenderingContext& aRenderingContext, } +//--------------------------------------------------------------------------- +//--------------------------------------------------------------------------- +//--------------------------------------------------------------------------- +// Offset for arrow centerpoint +const nscoord nsArrowOffsetX = 3; +const nscoord nsArrowOffsetY = 3; +nscoord nsArrowRightPoints[] = {0, 0, 0, 6, 6, 3 }; +nscoord nsArrowLeftPoints[] = {0, 3, 6, 0, 6, 6 }; +nscoord nsArrowUpPoints[] = {3, 0, 6, 6, 0, 6 }; //{0, 6, 3, 0, 6, 6 }; +nscoord nsArrowDownPoints[] = {0, 0, 3, 6, 6, 0 }; + +//--------------------------------------------------------------------------- +void +nsFormControlFrame::SetupPoints(PRUint32 aNumberOfPoints, nscoord* points, nsPoint* polygon, nscoord aScaleFactor, nscoord aX, nscoord aY) +{ + const nscoord arrowOffsetX = 3 * aScaleFactor; + const nscoord arrowOffsetY = 3 * aScaleFactor; + + PRUint32 i = 0; + PRUint32 count = 0; + for (i = 0; i < aNumberOfPoints; i++) { + polygon[i].x = (points[count] * aScaleFactor) + aX - arrowOffsetX; + count++; + polygon[i].y = (points[count] * aScaleFactor) + aY - arrowOffsetY; + count++; + } + polygon[i].x = (points[0] * aScaleFactor) + aX - arrowOffsetX; + polygon[i].y = (points[1] * aScaleFactor) + aY - arrowOffsetY; +} + + + +//--------------------------------------------------------------------------- +void +nsFormControlFrame::DrawArrowGlyph(nsIRenderingContext& aRenderingContext, + nscoord aSX, nscoord aSY, nsArrowDirection aArrowDirection, + nscoord aOnePixel) +{ + nsPoint polygon[4]; + + switch(aArrowDirection) + { + case eArrowDirection_Left: + SetupPoints(3, nsArrowLeftPoints, polygon, aOnePixel, aSX, aSY); + break; + + case eArrowDirection_Right: + SetupPoints(3, nsArrowRightPoints, polygon, aOnePixel, aSX, aSY); + break; + + case eArrowDirection_Up: + SetupPoints(3, nsArrowUpPoints, polygon, aOnePixel, aSX, aSY); + break; + + case eArrowDirection_Down: + SetupPoints(3, nsArrowDownPoints, polygon, aOnePixel, aSX, aSY); + break; + } + + aRenderingContext.FillPolygon(polygon, 3); +} + +//--------------------------------------------------------------------------- +void +nsFormControlFrame::DrawArrow(nsArrowDirection aArrowDirection, + nsIRenderingContext& aRenderingContext, + nsIPresContext& aPresContext, + const nsRect& aDirtyRect, + nsRect& aRect, + nscoord aOnePixel, + const nsStyleColor& aColor, + const nsStyleSpacing& aSpacing, + nsIFrame* aForFrame, + nsRect& aFrameRect) +{ + // Draw border using CSS + nsCSSRendering::PaintBackground(aPresContext, aRenderingContext, aForFrame, + aDirtyRect, aRect, aColor, 0, 0); + nsCSSRendering::PaintBorder(aPresContext, aRenderingContext, aForFrame, + aDirtyRect, aRect, aSpacing, 0); + + // Draw the glyph in black + aRenderingContext.SetColor(NS_RGB(0, 0, 0)); + // Draw arrow centered in the rectangle + DrawArrowGlyph(aRenderingContext, aRect.x + (aRect.width / 2), aRect.y + (aRect.height / 2), aArrowDirection, aOnePixel); + +} + +//--------------------------------------------------------------------------- +void +nsFormControlFrame::DrawScrollbar(nsIRenderingContext& aRenderingContext, + nsIPresContext& aPresContext, + const nsRect& aDirtyRect, + nsRect& aRect, + PRBool aHorizontal, + nscoord aOnePixel, + nsIStyleContext* aScrollbarStyleContext, + nsIStyleContext* aScrollbarArrowStyleContext, + nsIFrame* aForFrame, + nsRect& aFrameRect) +{ + // Get the Scrollbar's Style structs + const nsStyleSpacing* scrollbarSpacing = + (const nsStyleSpacing*)aScrollbarStyleContext->GetStyleData(eStyleStruct_Spacing); + const nsStyleColor* scrollbarColor = + (const nsStyleColor*)aScrollbarStyleContext->GetStyleData(eStyleStruct_Color); + + // Get the Scrollbar's Arrow's Style structs + const nsStyleSpacing* arrowSpacing = + (const nsStyleSpacing*)aScrollbarArrowStyleContext->GetStyleData(eStyleStruct_Spacing); + const nsStyleColor* arrowColor = + (const nsStyleColor*)aScrollbarArrowStyleContext->GetStyleData(eStyleStruct_Color); + + // Draw background for scrollbar + nsCSSRendering::PaintBackground(aPresContext, aRenderingContext, aForFrame, + aDirtyRect, aRect, *scrollbarColor, 0, 0); + + if (PR_TRUE == aHorizontal) { + // Draw horizontal Arrow + nscoord arrowWidth = aRect.height; + nsRect arrowLeftRect(aRect.x, aRect.y, arrowWidth, arrowWidth); + DrawArrow(eArrowDirection_Left,aRenderingContext,aPresContext, + aDirtyRect, arrowLeftRect,aOnePixel, *arrowColor, *arrowSpacing, aForFrame, aFrameRect); + + nsRect thumbRect(aRect.x+arrowWidth, aRect.y, arrowWidth, arrowWidth); + nsCSSRendering::PaintBackground(aPresContext, aRenderingContext, aForFrame, + aDirtyRect, thumbRect, *arrowColor, 0, 0); + nsCSSRendering::PaintBorder(aPresContext, aRenderingContext, aForFrame, + aDirtyRect, thumbRect, *arrowSpacing, 0); + + nsRect arrowRightRect(aRect.x + (aRect.width - arrowWidth), aRect.y, arrowWidth, arrowWidth); + DrawArrow(eArrowDirection_Right,aRenderingContext,aPresContext, + aDirtyRect, arrowRightRect,aOnePixel, *arrowColor, *arrowSpacing, aForFrame, aFrameRect); + + } + else { + // Draw vertical arrow + nscoord arrowHeight = aRect.width; + nsRect arrowUpRect(aRect.x, aRect.y, arrowHeight, arrowHeight); + DrawArrow(eArrowDirection_Up,aRenderingContext,aPresContext, + aDirtyRect, arrowUpRect,aOnePixel, *arrowColor, *arrowSpacing, aForFrame, aFrameRect); + + nsRect thumbRect(aRect.x, aRect.y+arrowHeight, arrowHeight, arrowHeight); + nsCSSRendering::PaintBackground(aPresContext, aRenderingContext, aForFrame, + aDirtyRect, thumbRect, *arrowColor, 0, 0); + nsCSSRendering::PaintBorder(aPresContext, aRenderingContext, aForFrame, + aDirtyRect, thumbRect, *arrowSpacing, 0); + + nsRect arrowDownRect(aRect.x, aRect.y + (aRect.height - arrowHeight), arrowHeight, arrowHeight); + DrawArrow(eArrowDirection_Down,aRenderingContext,aPresContext, + aDirtyRect, arrowDownRect,aOnePixel, *arrowColor, *arrowSpacing, aForFrame, aFrameRect); + } + +} diff --git a/mozilla/layout/html/forms/src/nsFormControlFrame.h b/mozilla/layout/html/forms/src/nsFormControlFrame.h index 2fd42a07c83..81aef7f503c 100644 --- a/mozilla/layout/html/forms/src/nsFormControlFrame.h +++ b/mozilla/layout/html/forms/src/nsFormControlFrame.h @@ -25,6 +25,7 @@ #include "nsIWidget.h" #include "nsLeafFrame.h" #include "nsCoord.h" +#include "nsIStyleContext.h" class nsIView; class nsIPresContext; @@ -255,25 +256,102 @@ protected: //nscoord GetStyleDim(nsIPresContext& aPresContext, nscoord aMaxDim, // nscoord aMaxWidth, const nsStyleCoord& aCoord); +// +// 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. +// + + + /** + * Enumeration of possible mouse states used to detect mouse clicks + */ + enum nsArrowDirection { + eArrowDirection_Left, + eArrowDirection_Right, + eArrowDirection_Up, + eArrowDirection_Down + }; + + /** + * Setup an array of Points + */ + + static void SetupPoints(PRUint32 aNumberOfPoints, nscoord* points, + nsPoint* polygon, nscoord aScaleFactor, nscoord aX, nscoord aY); + /** * Draw a fat line. The line is drawn as a polygon with a specified width. - * Utility used for rendering a form control during printing. - * + * Utility used for rendering a form control during printing. + * * @param aRenderingContext the rendering context * @param aSX starting x in pixels - * @param aSY starting y in pixels - * @param aEX ending x in pixels - * @param aEY ending y in pixels + * @param aSY starting y in pixels + * @param aEX ending x in pixels + * @param aEY ending y in pixels * @param aHorz PR_TRUE if aWidth is added to x coordinates to form polygon. If - * PR_FALSE then aWidth as added to the y coordinates. + * PR_FALSE then aWidth as added to the y coordinates. * @param aOnePixel number of twips in a single pixel. */ - void DrawLine(nsIRenderingContext& aRenderingContext, + static void DrawLine(nsIRenderingContext& aRenderingContext, nscoord aSX, nscoord aSY, nscoord aEX, nscoord aEY, PRBool aHorz, nscoord aWidth, nscoord aOnePixel); + /** + * Draw a arrow glyph + * + * @param aRenderingContext the rendering context + * @param aSX upper left x coordinate pixels + * @param aSY upper left y coordinate pixels + * @param aType @see nsArrowDirection + * @param aOnePixel number of twips in a single pixel. + */ + + static void DrawArrowGlyph(nsIRenderingContext& aRenderingContext, + nscoord aSX, nscoord aSY, nsArrowDirection aArrowDirection, + nscoord aOnePixel); + + /** + * Draw a arrow + * + * @param aRenderingContext the rendering context + * @param aRect location and size of in pixels + * @param aType @see nsArrowDirection + * @param aOnePixel number of twips in a single pixel. + */ + + static void DrawArrow(nsArrowDirection aArrowDirection, + nsIRenderingContext& aRenderingContext, + nsIPresContext& aPresContext, + const nsRect& aDirtyRect, + nsRect& aRect, + nscoord aOnePixel, + const nsStyleColor& aColor, + const nsStyleSpacing& aSpacing, + nsIFrame* aForFrame, + nsRect& aFrameRect); + /** + * Draw a scrollbar + * + * @param aRenderingContext the rendering context + * @param aHorizontal if TRUE a horizontal scrollbar is drawn, if FALSE a vertical scrollbar is drawn + * @param aOnePixel number of twips in a single pixel. + */ + + static void DrawScrollbar(nsIRenderingContext& aRenderingContext, + nsIPresContext& aPresContext, + const nsRect& aDirtyRect, + nsRect& aRect, + PRBool aHorizontal, + nscoord aOnePixel, + nsIStyleContext* aScrollbarStyleContext, + nsIStyleContext* aScrollbarArrowStyleContext, + nsIFrame* aForFrame, + nsRect& aFrameRect); + + nsMouseState mLastMouseState; nsIWidget* mWidget; nsSize mWidgetSize; diff --git a/mozilla/layout/html/forms/src/nsSelectControlFrame.cpp b/mozilla/layout/html/forms/src/nsSelectControlFrame.cpp index c5f9b4c28dc..46c058a535e 100644 --- a/mozilla/layout/html/forms/src/nsSelectControlFrame.cpp +++ b/mozilla/layout/html/forms/src/nsSelectControlFrame.cpp @@ -44,6 +44,8 @@ #include "nsStyleConsts.h" #include "nsStyleUtil.h" #include "nsFont.h" +#include "nsIDeviceContext.h" +#include "nsIFontMetrics.h" static NS_DEFINE_IID(kIDOMHTMLSelectElementIID, NS_IDOMHTMLSELECTELEMENT_IID); static NS_DEFINE_IID(kIDOMHTMLOptionElementIID, NS_IDOMHTMLOPTIONELEMENT_IID); @@ -92,7 +94,24 @@ public: NS_METHOD GetMultiple(PRBool* aResult, nsIDOMHTMLSelectElement* aSelect = nsnull); virtual void Reset(); + // + // XXX: The following paint methods are 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. + // + NS_IMETHOD Paint(nsIPresContext& aPresContext, + nsIRenderingContext& aRenderingContext, + const nsRect& aDirtyRect); + + virtual void PaintSelectControl(nsIPresContext& aPresContext, + nsIRenderingContext& aRenderingContext, + const nsRect& aDirtyRect); + + ///XXX: End o the temporary methods + protected: + PRUint32 mNumRows; + nsIDOMHTMLSelectElement* GetSelect(); nsIDOMHTMLCollection* GetOptions(nsIDOMHTMLSelectElement* aSelect = nsnull); nsIDOMHTMLOptionElement* GetOption(nsIDOMHTMLCollection& aOptions, PRUint32 aIndex); @@ -124,6 +143,7 @@ nsSelectControlFrame::nsSelectControlFrame() { mIsComboBox = PR_FALSE; mOptionsAdded = PR_FALSE; + mNumRows = 0; } nscoord @@ -238,25 +258,46 @@ nsSelectControlFrame::GetDesiredSize(nsIPresContext* aPresContext, nsInputDimensionSpec textSpec(nsnull, PR_FALSE, nsnull, nsnull, maxWidth, PR_TRUE, nsHTMLAtoms::size, 1); // XXX fix CalculateSize to return PRUint32 - PRUint32 numRows = (PRUint32)CalculateSize(aPresContext, this, styleSize, textSpec, - calcSize, widthExplicit, heightExplicit, rowHeight, - aReflowState.rendContext); + mNumRows = (PRUint32)CalculateSize(aPresContext, this, styleSize, textSpec, + calcSize, widthExplicit, heightExplicit, rowHeight, + aReflowState.rendContext); // here it is determined whether we are a combo box PRInt32 sizeAttr; GetSize(&sizeAttr); PRBool multiple; if (!GetMultiple(&multiple) && - ((1 >= sizeAttr) || ((ATTR_NOTSET == sizeAttr) && (1 >= numRows)))) { + ((1 >= sizeAttr) || ((ATTR_NOTSET == sizeAttr) && (1 >= mNumRows)))) { mIsComboBox = PR_TRUE; } - + + float sp2t; float p2t = aPresContext->GetPixelsToTwips(); + aPresContext->GetScaledPixelsToTwips(sp2t); + + nscoord scrollbarWidth = 0; + nscoord scrollbarHeight = 0; + float scale; + nsIDeviceContext* dx = nsnull; + dx = aPresContext->GetDeviceContext(); + if (nsnull != dx) { + float sbWidth; + float sbHeight; + dx->GetCanonicalPixelScale(scale); + dx->GetScrollBarDimensions(sbWidth, sbHeight); + scrollbarWidth = PRInt32(sbWidth * scale); + scrollbarHeight = PRInt32(sbHeight * scale); + NS_RELEASE(dx); + } else { + scrollbarWidth = GetScrollbarWidth(sp2t); + scrollbarHeight = scrollbarWidth; + } + aDesiredLayoutSize.width = calcSize.width; // account for vertical scrollbar, if present - if (!widthExplicit && ((numRows < numOptions) || mIsComboBox)) { - aDesiredLayoutSize.width += GetScrollbarWidth(p2t); + if (!widthExplicit && ((mNumRows < numOptions) || mIsComboBox)) { + aDesiredLayoutSize.width += scrollbarWidth; } // XXX put this in widget library, combo boxes are fixed height (visible part) @@ -269,7 +310,7 @@ nsSelectControlFrame::GetDesiredSize(nsIPresContext* aPresContext, aDesiredWidgetSize.width = aDesiredLayoutSize.width; aDesiredWidgetSize.height = aDesiredLayoutSize.height; if (mIsComboBox) { // add in pull down size - PRInt32 extra = NSIntPixelsToTwips(10, p2t); + PRInt32 extra = NSIntPixelsToTwips(10, p2t*scale); aDesiredWidgetSize.height += (rowHeight * (numOptions > 20 ? 20 : numOptions)) + extra; } @@ -600,3 +641,191 @@ nsSelectControlFrame::GetOptionValue(nsIDOMHTMLCollection& aCollection, PRUint32 return status; } +void +nsSelectControlFrame::PaintSelectControl(nsIPresContext& aPresContext, + nsIRenderingContext& aRenderingContext, + const nsRect& aDirtyRect) +{ +#ifdef XP_PC + aRenderingContext.PushState(); + + + nsFormControlFrame::Paint(aPresContext, aRenderingContext, aDirtyRect); + + /** + * Resolve style for a pseudo frame within the given aParentContent & aParentContext. + * The tag should be uppercase and inclue the colon. + * ie: NS_NewAtom(":FIRST-LINE"); + */ + nsIAtom * sbAtom = NS_NewAtom(":SCROLLBAR-LOOK"); + nsIStyleContext* scrollbarStyle = aPresContext.ResolvePseudoStyleContextFor(mContent, sbAtom, mStyleContext); + NS_RELEASE(sbAtom); + + sbAtom = NS_NewAtom(":SCROLLBAR-ARROW-LOOK"); + nsIStyleContext* arrowStyle = aPresContext.ResolvePseudoStyleContextFor(mContent, sbAtom, mStyleContext); + NS_RELEASE(sbAtom); + + + nsIDOMHTMLCollection* options = GetOptions(); + if (!options) { + return; + } + PRUint32 numOptions; + options->GetLength(&numOptions); + + float scale; + nsIDeviceContext * context; + aRenderingContext.GetDeviceContext(context); + context->GetCanonicalPixelScale(scale); + + const nsStyleSpacing* spacing = + (const nsStyleSpacing*)mStyleContext->GetStyleData(eStyleStruct_Spacing); + nsMargin border; + spacing->CalcBorderFor(this, border); + + float p2t; + aPresContext.GetScaledPixelsToTwips(p2t); + nscoord onePixel = NSIntPixelsToTwips(1, p2t); + + nsRect outside(0, 0, mRect.width, mRect.height); + outside.Deflate(border); + outside.Deflate(onePixel, onePixel); + + nsRect inside(outside); + + aRenderingContext.SetColor(NS_RGB(0,0,0)); + + nsFont font(aPresContext.GetDefaultFixedFont()); + GetFont(&aPresContext, font); + + aRenderingContext.SetFont(font); + + //nscoord textWidth; + nscoord textHeight; + nsString text; + + // Calculate the height of the text + nsIFontMetrics* metrics; + context->GetMetricsFor(font, metrics); + metrics->GetHeight(textHeight); + + // Calculate the width of the scrollbar + PRInt32 scrollbarWidth; + if (numOptions > mNumRows) { + float sbWidth; + float sbHeight; + context->GetCanonicalPixelScale(scale); + context->GetScrollBarDimensions(sbWidth, sbHeight); + scrollbarWidth = PRInt32(sbWidth * scale); + } else { + scrollbarWidth = 0; + } + + // shrink the inside rect's width for the scrollbar + inside.width -= scrollbarWidth; + PRBool clipEmpty; + aRenderingContext.PushState(); + nsRect clipRect(inside); + clipRect.Inflate(onePixel, onePixel); + + aRenderingContext.SetClipRect(clipRect, nsClipCombine_kReplace, clipEmpty); + + nscoord x = inside.x + onePixel; + nscoord y; + if (mIsComboBox) { + y = ((inside.height - textHeight) / 2) + inside.y; + } else { + y = inside.y; + } + + PRUint32 selectedIndex = -1; + // XXX Get Selected index out of Content model + selectedIndex = 1; + + nsIDOMNode* node; + nsIDOMHTMLOptionElement* option; + for (PRUint32 i = 0; i < numOptions; i++) { + options->Item(i, &node); + if (node) { + nsresult result = node->QueryInterface(kIDOMHTMLOptionElementIID, (void**)&option); + if ((NS_OK == result) && option) { + // XXX need to compress whitespace + if (NS_CONTENT_ATTR_HAS_VALUE != option->GetText(text)) { + text = " "; + } + + PRBool selected = PR_FALSE; + option->GetSelected(&selected); + if ((selected && !mIsComboBox) || (mIsComboBox && selectedIndex == i)) { + nsRect rect(inside.x, y-onePixel, mRect.width-onePixel, textHeight+onePixel); + nscolor currentColor; + aRenderingContext.GetColor(currentColor); + aRenderingContext.SetColor(NS_RGB(0,0,0)); + aRenderingContext.FillRect(rect); + aRenderingContext.SetColor(NS_RGB(255,255,255)); + aRenderingContext.DrawString(text, x, y, 0); + aRenderingContext.SetColor(currentColor); + } else { + if (!mIsComboBox || (mIsComboBox && -1 == selectedIndex && 0 == i)) { + aRenderingContext.DrawString(text, x, y, 0); + } + } + + if (!mIsComboBox) { + y += textHeight; + if (i == mNumRows-1) { + i = numOptions; + } + } else if ((-1 == selectedIndex && 0 == i) || (selectedIndex == i)) { + i = numOptions; + } + + NS_RELEASE(option); + } + NS_RELEASE(node); + } + } + + aRenderingContext.PopState(clipEmpty); + // Draw Scrollbars + if (numOptions > mNumRows) { + //const nsStyleColor* myColor = + // (const nsStyleColor*)mStyleContext->GetStyleData(eStyleStruct_Color); + + if (mIsComboBox) { + // Get the Scrollbar's Arrow's Style structs + const nsStyleSpacing* arrowSpacing = (const nsStyleSpacing*)arrowStyle->GetStyleData(eStyleStruct_Spacing); + const nsStyleColor* arrowColor = (const nsStyleColor*)arrowStyle->GetStyleData(eStyleStruct_Color); + + nsRect srect(mRect.width-scrollbarWidth-onePixel, onePixel, scrollbarWidth, mRect.height-(onePixel*2)); + DrawArrow(eArrowDirection_Down, aRenderingContext,aPresContext, + aDirtyRect, srect, onePixel, *arrowColor, *arrowSpacing, this, mRect); + } else { + nsRect srect(mRect.width-scrollbarWidth-onePixel, onePixel, scrollbarWidth, mRect.height-(onePixel*2)); + + DrawScrollbar(aRenderingContext,aPresContext, aDirtyRect, srect, PR_FALSE, onePixel, + scrollbarStyle, arrowStyle, this, mRect); + } + } + + + NS_RELEASE(context); + + NS_RELEASE(options); + aRenderingContext.PopState(clipEmpty); + + NS_RELEASE(scrollbarStyle); + NS_RELEASE(arrowStyle); +#endif +} + +NS_METHOD +nsSelectControlFrame::Paint(nsIPresContext& aPresContext, + nsIRenderingContext& aRenderingContext, + const nsRect& aDirtyRect) +{ +#ifdef XP_PC + PaintSelectControl(aPresContext, aRenderingContext, aDirtyRect); +#endif + return NS_OK; +} diff --git a/mozilla/layout/html/forms/src/nsTextControlFrame.cpp b/mozilla/layout/html/forms/src/nsTextControlFrame.cpp index 12bd5609dfe..51c5d2880fa 100644 --- a/mozilla/layout/html/forms/src/nsTextControlFrame.cpp +++ b/mozilla/layout/html/forms/src/nsTextControlFrame.cpp @@ -210,11 +210,27 @@ nsTextControlFrame::GetDesiredSize(nsIPresContext* aPresContext, } if (NS_FORM_TEXTAREA == type) { - float p2t = aPresContext->GetPixelsToTwips(); - nscoord scrollbarWidth = GetScrollbarWidth(p2t); + nscoord scrollbarWidth = 0; + nscoord scrollbarHeight = 0; + float scale; + float p2t = aPresContext->GetPixelsToTwips(); + nsIDeviceContext* dx = nsnull; + dx = aPresContext->GetDeviceContext(); + if (nsnull != dx) { + float sbWidth; + float sbHeight; + dx->GetCanonicalPixelScale(scale); + dx->GetScrollBarDimensions(sbWidth, sbHeight); + scrollbarWidth = PRInt32(sbWidth * scale); + scrollbarHeight = PRInt32(sbHeight * scale); + NS_RELEASE(dx); + } else { + scrollbarWidth = GetScrollbarWidth(p2t); + scrollbarHeight = scrollbarWidth; + } if (!heightExplicit) { - size.height += scrollbarWidth; + size.height += scrollbarHeight; } if (!widthExplicit) { size.width += scrollbarWidth; @@ -484,14 +500,6 @@ nsTextControlFrame::GetFrameName(nsString& aResult) const return MakeFrameName("TextControl", aResult); } -void nsTextControlFrame::GetCurrentText(nsString & aText) -{ - nsIDOMHTMLInputElement* inputElement; - if (NS_OK == mContent->QueryInterface(kIDOMHTMLInputElementIID, (void**)&inputElement)) { - inputElement->GetValue(aText); - NS_RELEASE(inputElement); - } -} void nsTextControlFrame::PaintTextControl(nsIPresContext& aPresContext, @@ -501,6 +509,7 @@ nsTextControlFrame::PaintTextControl(nsIPresContext& aPresContext, #ifdef XP_PC aRenderingContext.PushState(); + nsFormControlFrame::Paint(aPresContext, aRenderingContext, aDirtyRect); const nsStyleSpacing* spacing = @@ -554,17 +563,97 @@ nsTextControlFrame::PaintTextControl(nsIPresContext& aPresContext, nscoord textWidth; nscoord textHeight; nsString text; - GetCurrentText(text); + + GetText(&text); aRenderingContext.GetWidth(text, textWidth); nsIFontMetrics* metrics; context->GetMetricsFor(font, metrics); metrics->GetHeight(textHeight); - nscoord x = inside.x + onePixel + onePixel; - nscoord y = ((inside.height - textHeight) / 2) + inside.y; + PRInt32 type; + GetType(&type); + if (NS_FORM_INPUT_TEXT == type || NS_FORM_INPUT_PASSWORD == type) { + nscoord x = inside.x + onePixel + onePixel; + nscoord y; + + if (NS_FORM_INPUT_TEXT == type) { + y = ((inside.height - textHeight) / 2) + inside.y; + } else { + metrics->GetMaxAscent(textHeight); + y = ((inside.height - textHeight) / 2) + inside.y; + PRInt32 i; + PRInt32 len = text.Length(); + text.SetLength(0); + for (i=0;iGetCanonicalPixelScale(scale); + context->GetScrollBarDimensions(sbWidth, sbHeight); + PRInt32 scrollbarScaledWidth = PRInt32(sbWidth * scale); + PRInt32 scrollbarScaledHeight = PRInt32(sbWidth * scale); + + inside.width -= scrollbarScaledWidth; + inside.height -= scrollbarScaledHeight; + PRBool clipEmpty; + aRenderingContext.PushState(); + aRenderingContext.SetClipRect(inside, nsClipCombine_kReplace, clipEmpty); + + nscoord x = inside.x + onePixel; + nscoord y = inside.y + onePixel; + + // Draw multi-line text + PRInt32 oldPos = 0; + PRInt32 pos = text.Find('\n', 0); + while (1) { + nsString substr; + if (-1 == pos) { + text.Right(substr, text.Length()-oldPos); + aRenderingContext.DrawString(substr, x, y, 0); + break; + } + text.Left(substr, pos); + aRenderingContext.DrawString(substr, x, y, 0); + y += textHeight; + pos++; + oldPos = pos; + pos = text.Find('\n', pos); + } + + + aRenderingContext.PopState(clipEmpty); + + // Scrollbars + const nsStyleColor* myColor = (const nsStyleColor*)mStyleContext->GetStyleData(eStyleStruct_Color); + nsIAtom * sbAtom = NS_NewAtom(":SCROLLBAR-LOOK"); + nsIStyleContext* scrollbarStyle = aPresContext.ResolvePseudoStyleContextFor(mContent, sbAtom, mStyleContext); + NS_RELEASE(sbAtom); + sbAtom = NS_NewAtom(":SCROLLBAR-ARROW-LOOK"); + nsIStyleContext* arrowStyle = aPresContext.ResolvePseudoStyleContextFor(mContent, sbAtom, mStyleContext); + NS_RELEASE(sbAtom); + + nsRect srect(mRect.width-scrollbarScaledWidth-(2*onePixel), 2*onePixel, scrollbarScaledWidth, mRect.height-(onePixel*4)-scrollbarScaledWidth); + + DrawScrollbar(aRenderingContext,aPresContext, aDirtyRect, srect, PR_FALSE, onePixel, + scrollbarStyle, arrowStyle, this, mRect); + // Horizontal + srect.SetRect(2*onePixel, mRect.height-scrollbarScaledHeight-(2*onePixel), mRect.width-(onePixel*4)-scrollbarScaledHeight, scrollbarScaledHeight); + DrawScrollbar(aRenderingContext,aPresContext, aDirtyRect, srect, PR_TRUE, onePixel, + scrollbarStyle, arrowStyle, this, mRect); + + // Draw the small rect "gap" in the bottom right that the two scrollbars don't cover + const nsStyleColor* sbColor = (const nsStyleColor*)scrollbarStyle->GetStyleData(eStyleStruct_Color); + srect.SetRect(mRect.width-scrollbarScaledWidth-(2*onePixel), mRect.height-scrollbarScaledHeight-(onePixel*2), scrollbarScaledWidth, scrollbarScaledHeight); + nsCSSRendering::PaintBackground(aPresContext, aRenderingContext, this, + aDirtyRect, srect, *sbColor, 0, 0); + } + - aRenderingContext.DrawString(text, x, y, 0); NS_RELEASE(context); PRBool status; diff --git a/mozilla/layout/html/forms/src/nsTextControlFrame.h b/mozilla/layout/html/forms/src/nsTextControlFrame.h index b9105657471..5f24f568eda 100644 --- a/mozilla/layout/html/forms/src/nsTextControlFrame.h +++ b/mozilla/layout/html/forms/src/nsTextControlFrame.h @@ -62,13 +62,11 @@ public: NS_IMETHOD GetCursor(nsIPresContext& aPresContext, nsPoint& aPoint, PRInt32& aCursor); - // + // // XXX: The following paint methods are 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. // - virtual void GetCurrentText(nsString & aText); - NS_IMETHOD Paint(nsIPresContext& aPresContext, nsIRenderingContext& aRenderingContext, const nsRect& aDirtyRect);