added support for Ender GFX-rendered text control

made nsTextControlFrame an abstract base class for nsGfxTextControlFrame and
nsNativeTextControlFrame
This commit is contained in:
buster%netscape.com 1999-06-12 22:29:54 +00:00
parent a2c09e8db1
commit bb7e3f641a
14 changed files with 2776 additions and 1311 deletions

View File

@ -20,6 +20,7 @@
#include "nsFormFrame.h"
#include "nsButtonControlFrame.h"
#include "nsTextControlFrame.h"
#include "nsNativeTextControlFrame.h" // XXX: remove when frame construction is done properly
#include "nsIContent.h"
#include "prtypes.h"
#include "nsIAtom.h"
@ -200,7 +201,10 @@ NS_IMETHODIMP nsFileControlFrame::Reflow(nsIPresContext& aPresContext,
if (disabled) {
text->SetAttribute(kNameSpaceID_HTML, nsHTMLAtoms::disabled, nsAutoString("1"), PR_FALSE); // XXX this should use an "empty" bool value
}
NS_NewTextControlFrame(&childFrame);
// XXX: hard-wired for the native text control frame
// construction of the text control should happen in nsCSSFrameConstruction
NS_NewNativeTextControlFrame(&childFrame);
//XXX: This style should be cached, rather than resolved each time.
// Get pseudo style for the text field

View File

@ -299,12 +299,15 @@ nsFormControlHelper::CalculateSize (nsIPresContext* aPresContext,
nsWidgetRendering mode;
aPresContext->GetWidgetRenderingMode(&mode);
// only add in padding if we are not Gfx
// only add in padding if we are not Gfx, or if we're a Gfx text widget
PRBool requiresWidget = PR_FALSE;
aFrame->RequiresWidget(requiresWidget);
PRInt32 type;
aFrame->GetType(&type);
if (PR_TRUE == requiresWidget || eWidgetRendering_Gfx != mode) {
if (PR_TRUE == requiresWidget || eWidgetRendering_Gfx != mode ||
type==NS_FORM_INPUT_TEXT || type==NS_FORM_TEXTAREA || type==NS_FORM_INPUT_PASSWORD)
{
if (!aWidthExplicit) {
PRInt32 hPadding = (2 * aFrame->GetHorizontalInsidePadding(*aPresContext, p2t, aDesiredSize.width, charWidth));
aDesiredSize.width += hPadding;
@ -340,14 +343,20 @@ nsFormControlHelper::GetFont(nsIFormControlFrame * aFormFrame,
nsWidgetRendering m;
aPresContext->GetWidgetRenderingMode(&m);
// only add in padding if we are not Gfx
// only add in padding if we are not Gfx, excluding the text widgets
PRBool requiresWidget = PR_FALSE;
aFormFrame->RequiresWidget(requiresWidget);
if (PR_TRUE != requiresWidget && eWidgetRendering_Gfx == m) {
aFont = styleFont->mFont;
return;
PRInt32 type;
aFormFrame->GetType(&type);
if (type!=NS_FORM_INPUT_TEXT &&
type!=NS_FORM_TEXTAREA &&
type!=NS_FORM_INPUT_PASSWORD) {
if (PR_TRUE != requiresWidget && eWidgetRendering_Gfx == m) {
aFont = styleFont->mFont;
return;
}
}
nsCompatibility mode;
@ -358,8 +367,6 @@ nsFormControlHelper::GetFont(nsIFormControlFrame * aFormFrame,
return;
}
PRInt32 type;
aFormFrame->GetType(&type);
switch (type) {
case NS_FORM_INPUT_TEXT:
case NS_FORM_TEXTAREA:

View File

@ -66,21 +66,6 @@ static NS_DEFINE_IID(kIDOMHTMLInputElementIID, NS_IDOMHTMLINPUTELEMENT_IID);
static NS_DEFINE_IID(kLookAndFeelCID, NS_LOOKANDFEEL_CID);
static NS_DEFINE_IID(kILookAndFeelIID, NS_ILOOKANDFEEL_IID);
nsresult
NS_NewTextControlFrame(nsIFrame** aNewFrame)
{
NS_PRECONDITION(aNewFrame, "null OUT ptr");
if (nsnull == aNewFrame) {
return NS_ERROR_NULL_POINTER;
}
nsTextControlFrame* it = new nsTextControlFrame;
if (!it) {
return NS_ERROR_OUT_OF_MEMORY;
}
*aNewFrame = it;
return NS_OK;
}
nscoord
nsTextControlFrame::GetVerticalBorderWidth(float aPixToTwip) const
{
@ -209,26 +194,6 @@ nsTextControlFrame::GetCID()
}
}
void
nsTextControlFrame::EnterPressed(nsIPresContext& aPresContext)
{
if (mFormFrame && mFormFrame->CanSubmit(*this)) {
nsIContent *formContent = nsnull;
mFormFrame->GetContent(&formContent);
if (nsnull != formContent) {
nsEvent event;
nsEventStatus status = nsEventStatus_eIgnore;
event.eventStructType = NS_EVENT;
event.message = NS_FORM_SUBMIT;
formContent->HandleDOMEvent(aPresContext, &event, nsnull, NS_EVENT_FLAG_INIT, status);
NS_RELEASE(formContent);
}
mFormFrame->OnSubmit(&aPresContext, this);
}
}
#define DEFAULT_PIXEL_WIDTH 20
void
@ -315,311 +280,12 @@ nsTextControlFrame::GetDesiredSize(nsIPresContext* aPresContext,
}
nsWidgetInitData*
nsTextControlFrame::GetWidgetInitData(nsIPresContext& aPresContext)
{
PRInt32 type;
GetType(&type);
nsTextWidgetInitData* data = nsnull;
PRBool readOnly = nsFormFrame::GetReadonly(this);
if ((NS_FORM_INPUT_PASSWORD == type) || readOnly) {
data = new nsTextWidgetInitData();
data->mIsPassword = PR_FALSE;
data->mIsReadOnly = PR_FALSE;
if (NS_FORM_INPUT_PASSWORD == type) {
data->clipChildren = PR_TRUE;
data->mIsPassword = PR_TRUE;
}
if (readOnly) {
data->mIsReadOnly = PR_TRUE;
}
}
return data;
}
NS_IMETHODIMP
nsTextControlFrame::GetText(nsString* aText, PRBool aInitialValue)
{
nsresult result = NS_CONTENT_ATTR_NOT_THERE;
PRInt32 type;
GetType(&type);
if ((NS_FORM_INPUT_TEXT == type) || (NS_FORM_INPUT_PASSWORD == type)) {
result = nsFormControlHelper::GetInputElementValue(mContent, aText, aInitialValue);
/* XXX REMOVE
nsIDOMHTMLInputElement* textElem = nsnull;
result = mContent->QueryInterface(kIDOMHTMLInputElementIID, (void**)&textElem);
if ((NS_OK == result) && textElem) {
if (PR_TRUE == aInitialValue) {
result = textElem->GetDefaultValue(*aText);
}
else {
result = textElem->GetValue(*aText);
}
NS_RELEASE(textElem);
}
*/
} else {
nsIDOMHTMLTextAreaElement* textArea = nsnull;
result = mContent->QueryInterface(kIDOMHTMLTextAreaElementIID, (void**)&textArea);
if ((NS_OK == result) && textArea) {
if (PR_TRUE == aInitialValue) {
result = textArea->GetDefaultValue(*aText);
}
else {
result = textArea->GetValue(*aText);
}
NS_RELEASE(textArea);
}
}
return result;
}
NS_IMETHODIMP
nsTextControlFrame::AttributeChanged(nsIPresContext* aPresContext,
nsIContent* aChild,
nsIAtom* aAttribute,
PRInt32 aHint)
{
nsresult result = NS_OK;
if (mWidget) {
nsITextWidget* text = nsnull;
result = mWidget->QueryInterface(kITextWidgetIID, (void**)&text);
if ((NS_OK == result) && (nsnull != text)) {
if (nsHTMLAtoms::value == aAttribute) {
nsString value;
/*XXXnsresult rv = */GetText(&value, PR_TRUE);
PRUint32 ignore;
text->SetText(value, ignore);
nsFormFrame::StyleChangeReflow(aPresContext, this);
} else if (nsHTMLAtoms::maxlength == aAttribute) {
PRInt32 maxLength;
nsresult rv = GetMaxLength(&maxLength);
if (NS_CONTENT_ATTR_NOT_THERE != rv) {
text->SetMaxTextLength(maxLength);
}
} else if (nsHTMLAtoms::readonly == aAttribute) {
PRBool oldReadOnly;
text->SetReadOnly(nsFormFrame::GetReadonly(this),oldReadOnly);
}
else if (nsHTMLAtoms::size == aAttribute) {
nsFormFrame::StyleChangeReflow(aPresContext, this);
}
// Allow the base class to handle common attributes supported
// by all form elements...
else {
result = nsFormControlFrame::AttributeChanged(aPresContext, aChild, aAttribute, aHint);
}
NS_RELEASE(text);
}
// XXX Ick, create an common interface that has the functionality of nsTextHelper
else { // We didn't get a Text, is it a TextArea?
nsITextAreaWidget* textArea = nsnull;
result = mWidget->QueryInterface(kITextAreaWidgetIID, (void**)&textArea);
if ((NS_OK == result) && (nsnull != textArea)) {
if (nsHTMLAtoms::value == aAttribute) {
nsString value;
/*XXXnsresult rv = */GetText(&value, PR_TRUE);
PRUint32 ignore;
textArea->SetText(value, ignore);
nsFormFrame::StyleChangeReflow(aPresContext, this);
} else if (nsHTMLAtoms::maxlength == aAttribute) {
PRInt32 maxLength;
nsresult rv = GetMaxLength(&maxLength);
if (NS_CONTENT_ATTR_NOT_THERE != rv) {
textArea->SetMaxTextLength(maxLength);
}
} else if (nsHTMLAtoms::readonly == aAttribute) {
PRBool oldReadOnly;
textArea->SetReadOnly(nsFormFrame::GetReadonly(this),oldReadOnly);
}
else if (nsHTMLAtoms::size == aAttribute) {
nsFormFrame::StyleChangeReflow(aPresContext, this);
}
// Allow the base class to handle common attributes supported
// by all form elements...
else {
result = nsFormControlFrame::AttributeChanged(aPresContext, aChild, aAttribute, aHint);
}
NS_RELEASE(textArea);
}
else { // We didn't get a Text or TextArea. Uh oh...
result = nsFormControlFrame::AttributeChanged(aPresContext, aChild, aAttribute, aHint);
}
}
}
return result;
}
void
nsTextControlFrame::PostCreateWidget(nsIPresContext* aPresContext,
nscoord& aWidth,
nscoord& aHeight)
{
if (!mWidget) {
return;
}
PRInt32 type;
GetType(&type);
nsFont font(aPresContext->GetDefaultFixedFontDeprecated());
GetFont(aPresContext, font);
mWidget->SetFont(font);
SetColors(*aPresContext);
PRUint32 ignore;
nsAutoString value;
nsITextAreaWidget* textArea = nsnull;
nsITextWidget* text = nsnull;
if (NS_OK == mWidget->QueryInterface(kITextWidgetIID,(void**)&text)) {
#ifdef SingleSignon
/* get name of text */
PRBool failed = PR_TRUE;
nsAutoString name;
GetName(&name);
/* get url name */
char *URLName = nsnull;
nsIURL* docURL = nsnull;
nsIDocument* doc = nsnull;
mContent->GetDocument(doc);
if (nsnull != doc) {
docURL = doc->GetDocumentURL();
NS_RELEASE(doc);
if (nsnull != docURL) {
const char* spec;
(void)docURL->GetSpec(&spec);
if (nsnull != spec) {
URLName = (char*)PR_Malloc(PL_strlen(spec)+1);
PL_strcpy(URLName, spec);
}
NS_RELEASE(docURL);
}
}
if (nsnull != URLName) {
/* invoke single-signon to get previously-used value of text */
nsIWalletService *service;
nsresult res = nsServiceManager::GetService(kWalletServiceCID,
kIWalletServiceIID,
(nsISupports **)&service);
if ((NS_OK == res) && (nsnull != service)) {
char* valueString = NULL;
char* nameString = name.ToNewCString();
res = service->SI_RestoreSignonData(URLName, nameString, &valueString);
delete[] nameString;
NS_RELEASE(service);
PR_FREEIF(URLName);
if (valueString && *valueString) {
value = valueString;
failed = PR_FALSE;
}
}
}
if (failed) {
GetText(&value, PR_TRUE);
}
#else
GetText(&value, PR_TRUE);
#endif
text->SetText(value, ignore);
PRInt32 maxLength;
nsresult result = GetMaxLength(&maxLength);
if (NS_CONTENT_ATTR_NOT_THERE != result) {
text->SetMaxTextLength(maxLength);
}
NS_RELEASE(text);
} else if (NS_OK == mWidget->QueryInterface(kITextAreaWidgetIID,(void**)&textArea)) {
GetText(&value, PR_TRUE);
textArea->SetText(value, ignore);
NS_RELEASE(textArea);
}
if (nsFormFrame::GetDisabled(this)) {
mWidget->Enable(PR_FALSE);
}
}
PRInt32
nsTextControlFrame::GetMaxNumValues()
{
return 1;
}
PRBool
nsTextControlFrame::GetNamesValues(PRInt32 aMaxNumValues, PRInt32& aNumValues,
nsString* aValues, nsString* aNames)
{
if (!mWidget) {
return PR_FALSE;
}
nsAutoString name;
nsresult result = GetName(&name);
if ((aMaxNumValues <= 0) || (NS_CONTENT_ATTR_NOT_THERE == result)) {
return PR_FALSE;
}
PRUint32 size;
nsITextWidget* text = nsnull;
nsITextAreaWidget* textArea = nsnull;
aNames[0] = name;
aNumValues = 1;
if (NS_OK == mWidget->QueryInterface(kITextWidgetIID,(void**)&text)) {
text->GetText(aValues[0],0,size); // the last parm is not used
NS_RELEASE(text);
return PR_TRUE;
} else if (NS_OK == mWidget->QueryInterface(kITextAreaWidgetIID,(void**)&textArea)) {
textArea->GetText(aValues[0],0,size); // the last parm is not used
NS_RELEASE(textArea);
return PR_TRUE;
}
return PR_FALSE;
}
void
nsTextControlFrame::Reset()
{
if (!mWidget) {
return;
}
nsITextWidget* text = nsnull;
nsITextAreaWidget* textArea = nsnull;
nsAutoString value;
nsresult valStatus = GetText(&value, PR_TRUE);
PRUint32 size;
if (NS_OK == mWidget->QueryInterface(kITextWidgetIID,(void**)&text)) {
if (NS_CONTENT_ATTR_HAS_VALUE == valStatus) {
text->SetText(value,size);
} else {
text->SetText("",size);
}
NS_RELEASE(text);
} else if (NS_OK == mWidget->QueryInterface(kITextAreaWidgetIID,(void**)&textArea)) {
if (NS_CONTENT_ATTR_HAS_VALUE == valStatus) {
textArea->SetText(value,size);
} else {
textArea->SetText("",size);
}
NS_RELEASE(textArea);
}
}
NS_IMETHODIMP
nsTextControlFrame::GetCursor(nsIPresContext& aPresContext, nsPoint& aPoint, PRInt32& aCursor)
@ -639,261 +305,3 @@ nsTextControlFrame::GetFrameName(nsString& aResult) const
{
return MakeFrameName("TextControl", aResult);
}
void
nsTextControlFrame::PaintTextControlBackground(nsIPresContext& aPresContext,
nsIRenderingContext& aRenderingContext,
const nsRect& aDirtyRect,
nsFramePaintLayer aWhichLayer) {
nsFormControlFrame::Paint(aPresContext, aRenderingContext, aDirtyRect, aWhichLayer);
}
void
nsTextControlFrame::PaintTextControl(nsIPresContext& aPresContext,
nsIRenderingContext& aRenderingContext,
const nsRect& aDirtyRect,
nsString& aText,
nsIStyleContext* aStyleContext, nsRect& aRect)
{
aRenderingContext.PushState();
const nsStyleSpacing* spacing =
(const nsStyleSpacing*)aStyleContext->GetStyleData(eStyleStruct_Spacing);
nsMargin border;
spacing->CalcBorderFor(this, border);
float p2t;
aPresContext.GetScaledPixelsToTwips(&p2t);
nscoord onePixel = NSIntPixelsToTwips(1, p2t);
nsRect outside(aRect.x, aRect.y, aRect.width, aRect.height);
outside.Deflate(border);
outside.Deflate(onePixel, onePixel);
nsRect inside(outside);
inside.Deflate(onePixel, onePixel);
#if 0
if (mGotFocus) {
PaintFocus(aRenderingContext,
aDirtyRect, inside, outside);
}
#endif
float appUnits;
float devUnits;
float scale;
nsIDeviceContext * context;
aRenderingContext.GetDeviceContext(context);
context->GetCanonicalPixelScale(scale);
context->GetAppUnitsToDevUnits(devUnits);
context->GetDevUnitsToAppUnits(appUnits);
aRenderingContext.SetColor(NS_RGB(0,0,0));
nsFont font(aPresContext.GetDefaultFixedFontDeprecated());
GetFont(&aPresContext, font);
aRenderingContext.SetFont(font);
nscoord textWidth;
nscoord textHeight;
aRenderingContext.GetWidth(aText, textWidth);
nsIFontMetrics* metrics;
context->GetMetricsFor(font, metrics);
metrics->GetHeight(textHeight);
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 = aText.Length();
aText.SetLength(0);
for (i=0;i<len;i++) {
aText.Append("*");
}
}
aRenderingContext.DrawString(aText, x, y);
} else {
float sbWidth;
float sbHeight;
context->GetCanonicalPixelScale(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 = aText.Find('\n', 0);
while (1) {
nsString substr;
if (-1 == pos) {
// Single line, no carriage return.
aText.Right(substr, aText.Length()-oldPos);
aRenderingContext.DrawString(substr, x, y);
break;
}
// Strip off substr up to carriage return
aText.Mid(substr, oldPos, ((pos - oldPos) - 1));
aRenderingContext.DrawString(substr, x, y);
y += textHeight;
// Advance to the next carriage return
pos++;
oldPos = pos;
pos = aText.Find('\n', pos);
}
aRenderingContext.PopState(clipEmpty);
// Scrollbars
nsIAtom * sbAtom = NS_NewAtom(":scrollbar-look");
nsIStyleContext* scrollbarStyle;
aPresContext.ResolvePseudoStyleContextFor(mContent, sbAtom, aStyleContext, PR_FALSE, &scrollbarStyle);
NS_RELEASE(sbAtom);
sbAtom = NS_NewAtom(":scrollbar-arrow-look");
nsIStyleContext* arrowStyle;
aPresContext.ResolvePseudoStyleContextFor(mContent, sbAtom, aStyleContext, PR_FALSE, &arrowStyle);
NS_RELEASE(sbAtom);
nsRect srect(aRect.width-scrollbarScaledWidth-(2*onePixel), 2*onePixel, scrollbarScaledWidth, aRect.height-(onePixel*4)-scrollbarScaledWidth);
nsFormControlHelper::PaintScrollbar(aRenderingContext,aPresContext, aDirtyRect, srect, PR_FALSE, onePixel,
scrollbarStyle, arrowStyle, this, aRect);
// Horizontal
srect.SetRect(2*onePixel, aRect.height-scrollbarScaledHeight-(2*onePixel), aRect.width-(onePixel*4)-scrollbarScaledHeight, scrollbarScaledHeight);
nsFormControlHelper::PaintScrollbar(aRenderingContext,aPresContext, aDirtyRect, srect, PR_TRUE, onePixel,
scrollbarStyle, arrowStyle, this, aRect);
// 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(aRect.width-scrollbarScaledWidth-(2*onePixel), aRect.height-scrollbarScaledHeight-(onePixel*2), scrollbarScaledWidth, scrollbarScaledHeight);
nsCSSRendering::PaintBackground(aPresContext, aRenderingContext, this,
aDirtyRect, srect, *sbColor, *spacing, 0, 0);
}
NS_RELEASE(context);
PRBool status;
aRenderingContext.PopState(status);
}
NS_METHOD
nsTextControlFrame::Paint(nsIPresContext& aPresContext,
nsIRenderingContext& aRenderingContext,
const nsRect& aDirtyRect,
nsFramePaintLayer aWhichLayer)
{
PaintTextControlBackground(aPresContext, aRenderingContext, aDirtyRect, aWhichLayer);
if (NS_FRAME_PAINT_LAYER_FOREGROUND == aWhichLayer) {
nsString text;
GetText(&text, PR_FALSE);
nsRect rect(0, 0, mRect.width, mRect.height);
PaintTextControl(aPresContext, aRenderingContext, aDirtyRect, text, mStyleContext, rect);
}
return NS_OK;
}
void nsTextControlFrame::GetTextControlFrameState(nsString& aValue)
{
if (nsnull != mWidget) {
nsITextWidget* text = nsnull;
nsITextAreaWidget* textArea = nsnull;
PRUint32 size = 0;
if (NS_OK == mWidget->QueryInterface(kITextWidgetIID,(void**)&text)) {
text->GetText(aValue,0,size);
NS_RELEASE(text);
}
else if (NS_OK == mWidget->QueryInterface(kITextAreaWidgetIID,
(void**)&textArea)) {
textArea->GetText(aValue,0, size);
NS_RELEASE(textArea);
}
}
else {
//XXX: this should return the a local field for GFX-rendered widgets aValue = "";
}
}
void nsTextControlFrame::SetTextControlFrameState(const nsString& aValue)
{
if (nsnull != mWidget) {
nsITextWidget* text = nsnull;
nsITextAreaWidget* textArea = nsnull;
PRUint32 size = 0;
if (NS_SUCCEEDED(mWidget->QueryInterface(kITextWidgetIID,(void**)&text))) {
text->SetText(aValue,size);
NS_RELEASE(text);
} else if (NS_OK == mWidget->QueryInterface(kITextAreaWidgetIID,
(void**)&textArea)) {
textArea->SetText(aValue,size);
NS_RELEASE(textArea);
}
}
}
NS_IMETHODIMP nsTextControlFrame::SetProperty(nsIAtom* aName, const nsString& aValue)
{
nsresult rv = NS_OK;
if (nsHTMLAtoms::value == aName) {
SetTextControlFrameState(aValue);
} else if (nsHTMLAtoms::select == aName) {
if (nsnull != mWidget) {
nsITextWidget *textWidget;
rv = mWidget->QueryInterface(kITextWidgetIID, (void**)&textWidget);
if (NS_SUCCEEDED(rv)) {
textWidget->SelectAll();
NS_RELEASE(textWidget);
}
nsITextAreaWidget *textAreaWidget;
rv = mWidget->QueryInterface(kITextAreaWidgetIID, (void**)&textAreaWidget);
if (NS_SUCCEEDED(rv)) {
textAreaWidget->SelectAll();
NS_RELEASE(textAreaWidget);
}
}
}
else {
return nsFormControlFrame::SetProperty(aName, aValue);
}
return rv;
}
NS_IMETHODIMP nsTextControlFrame::GetProperty(nsIAtom* aName, nsString& aValue)
{
// Return the value of the property from the widget it is not null.
// If widget is null, assume the widget is GFX-rendered and return a member variable instead.
if (nsHTMLAtoms::value == aName) {
GetTextControlFrameState(aValue);
}
else {
return nsFormControlFrame::GetProperty(aName, aValue);
}
return NS_OK;
}

View File

@ -24,33 +24,15 @@ class nsIContent;
class nsIFrame;
class nsIPresContext;
class nsTextControlFrame : public nsFormControlFrame {
class nsTextControlFrame : public nsFormControlFrame
{
/* ---------- methods implemented by base class ---------- */
public:
// nsIFormControlFrame
NS_IMETHOD SetProperty(nsIAtom* aName, const nsString& aValue);
NS_IMETHOD GetProperty(nsIAtom* aName, nsString& aValue);
virtual nsWidgetInitData* GetWidgetInitData(nsIPresContext& aPresContext);
NS_IMETHOD AttributeChanged(nsIPresContext* aPresContext,
nsIContent* aChild,
nsIAtom* aAttribute,
PRInt32 aHint);
NS_IMETHOD GetFrameName(nsString& aResult) const;
virtual void PostCreateWidget(nsIPresContext* aPresContext,
nscoord& aWidth,
nscoord& aHeight);
virtual const nsIID& GetCID();
virtual const nsIID& GetIID();
NS_IMETHOD GetText(nsString* aValue, PRBool aInitialValue);
virtual void EnterPressed(nsIPresContext& aPresContext) ;
NS_IMETHOD GetFrameName(nsString& aResult) const;
virtual nscoord GetVerticalBorderWidth(float aPixToTwip) const;
virtual nscoord GetHorizontalBorderWidth(float aPixToTwip) const;
virtual nscoord GetVerticalInsidePadding(float aPixToTwip,
@ -60,40 +42,65 @@ public:
nscoord aInnerWidth,
nscoord aCharWidth) const;
virtual PRInt32 GetMaxNumValues();
virtual PRBool GetNamesValues(PRInt32 aMaxNumValues, PRInt32& aNumValues,
nsString* aValues, nsString* aNames);
virtual void Reset();
NS_IMETHOD GetCursor(nsIPresContext& aPresContext, nsPoint& aPoint, PRInt32& aCursor);
NS_IMETHOD Paint(nsIPresContext& aPresContext,
nsIRenderingContext& aRenderingContext,
const nsRect& aDirtyRect,
nsFramePaintLayer aWhichLayer);
virtual void PaintTextControlBackground(nsIPresContext& aPresContext,
nsIRenderingContext& aRenderingContext,
const nsRect& aDirtyRect,
nsFramePaintLayer aWhichLayer);
virtual void PaintTextControl(nsIPresContext& aPresContext,
nsIRenderingContext& aRenderingContext,
const nsRect& aDirtyRect, nsString& aText,
nsIStyleContext* aStyleContext,
nsRect& aRect);
// Utility methods to get and set current widget state
void GetTextControlFrameState(nsString& aValue);
void SetTextControlFrameState(const nsString& aValue);
protected:
virtual void GetDesiredSize(nsIPresContext* aPresContext,
const nsHTMLReflowState& aReflowState,
nsHTMLReflowMetrics& aDesiredLayoutSize,
nsSize& aDesiredWidgetSize);
/* ---------- abstract methods derived class must implement ---------- */
public:
// nsIFormControlFrame
NS_IMETHOD SetProperty(nsIAtom* aName, const nsString& aValue)=0;
NS_IMETHOD GetProperty(nsIAtom* aName, nsString& aValue)=0;
virtual nsWidgetInitData* GetWidgetInitData(nsIPresContext& aPresContext)=0;
NS_IMETHOD AttributeChanged(nsIPresContext* aPresContext,
nsIContent* aChild,
nsIAtom* aAttribute,
PRInt32 aHint)=0;
virtual void PostCreateWidget(nsIPresContext* aPresContext,
nscoord& aWidth,
nscoord& aHeight)=0;
NS_IMETHOD GetText(nsString* aValue, PRBool aInitialValue)=0;
virtual void EnterPressed(nsIPresContext& aPresContext)=0;
virtual PRBool GetNamesValues(PRInt32 aMaxNumValues, PRInt32& aNumValues,
nsString* aValues, nsString* aNames)=0;
virtual void Reset()=0;
NS_IMETHOD Paint(nsIPresContext& aPresContext,
nsIRenderingContext& aRenderingContext,
const nsRect& aDirtyRect,
nsFramePaintLayer aWhichLayer)=0;
virtual void PaintTextControlBackground(nsIPresContext& aPresContext,
nsIRenderingContext& aRenderingContext,
const nsRect& aDirtyRect,
nsFramePaintLayer aWhichLayer)=0;
virtual void PaintTextControl(nsIPresContext& aPresContext,
nsIRenderingContext& aRenderingContext,
const nsRect& aDirtyRect, nsString& aText,
nsIStyleContext* aStyleContext,
nsRect& aRect)=0;
// Utility methods to get and set current widget state
virtual void GetTextControlFrameState(nsString& aValue)=0;
virtual void SetTextControlFrameState(const nsString& aValue)=0;
virtual nsresult RequiresWidget(PRBool &aRequiresWidget)=0;
};
#endif

View File

@ -39,14 +39,16 @@ CPPSRCS = \
nsCheckboxControlFrame.cpp \
nsFileControlFrame.cpp \
nsRadioControlFrame.cpp \
nsTextControlFrame.cpp \
nsTextControlFrame.cpp \
nsNativeTextControlFrame.cpp \
nsGfxTextControlFrame.cpp \
nsSelectControlFrame.cpp \
nsFieldSetFrame.cpp \
nsLegendFrame.cpp \
nsHTMLButtonControlFrame.cpp \
nsLabelFrame.cpp \
nsImageControlFrame.cpp \
nsButtonFrameRenderer.cpp \
nsButtonFrameRenderer.cpp \
$(NULL)
MODULE=layout

View File

@ -33,7 +33,9 @@ CPPSRCS= \
nsCheckboxControlFrame.cpp \
nsFileControlFrame.cpp \
nsRadioControlFrame.cpp \
nsTextControlFrame.cpp \
nsTextControlFrame.cpp \
nsGfxTextControlFrame.cpp \
nsTextControlFrame.cpp \
nsSelectControlFrame.cpp \
nsFieldSetFrame.cpp \
nsLegendFrame.cpp \
@ -53,6 +55,8 @@ CPP_OBJS= \
.\$(OBJDIR)\nsFileControlFrame.obj \
.\$(OBJDIR)\nsRadioControlFrame.obj \
.\$(OBJDIR)\nsTextControlFrame.obj \
.\$(OBJDIR)\nsGfxTextControlFrame.obj \
.\$(OBJDIR)\nsNativeTextControlFrame.obj \
.\$(OBJDIR)\nsSelectControlFrame.obj \
.\$(OBJDIR)\nsFieldSetFrame.obj \
.\$(OBJDIR)\nsLegendFrame.obj \
@ -61,12 +65,23 @@ CPP_OBJS= \
.\$(OBJDIR)\nsButtonFrameRenderer.obj \
.\$(OBJDIR)\nsImageControlFrame.obj
LINCS=-I$(PUBLIC)\xpcom -I$(PUBLIC)\raptor -I$(PUBLIC)\js \
-I$(PUBLIC)\dom -I$(PUBLIC)\netlib \
-I$(PUBLIC)\wallet \
-I..\..\base\src -I..\..\style\src \
-I..\..\..\base\src -I..\..\content\src -I$(PUBLIC)\uconv \
-I$(PUBLIC)\rdf
LINCS= -I$(PUBLIC)\xpcom \
-I$(PUBLIC)\raptor \
-I$(PUBLIC)\js \
-I$(PUBLIC)\dom \
-I$(PUBLIC)\pref \
-I$(PUBLIC)\editor \
-I$(PUBLIC)\netlib \
-I$(PUBLIC)\wallet \
-I$(PUBLIC)\uconv \
-I$(PUBLIC)\rdf \
-I..\..\base\src \
-I..\..\style\src \
-I..\..\..\base\src \
-I..\..\content\src \
-I$(PUBLIC)\uconv
LCFLAGS = \
$(LCFLAGS) \

View File

@ -20,6 +20,7 @@
#include "nsFormFrame.h"
#include "nsButtonControlFrame.h"
#include "nsTextControlFrame.h"
#include "nsNativeTextControlFrame.h" // XXX: remove when frame construction is done properly
#include "nsIContent.h"
#include "prtypes.h"
#include "nsIAtom.h"
@ -200,7 +201,10 @@ NS_IMETHODIMP nsFileControlFrame::Reflow(nsIPresContext& aPresContext,
if (disabled) {
text->SetAttribute(kNameSpaceID_HTML, nsHTMLAtoms::disabled, nsAutoString("1"), PR_FALSE); // XXX this should use an "empty" bool value
}
NS_NewTextControlFrame(&childFrame);
// XXX: hard-wired for the native text control frame
// construction of the text control should happen in nsCSSFrameConstruction
NS_NewNativeTextControlFrame(&childFrame);
//XXX: This style should be cached, rather than resolved each time.
// Get pseudo style for the text field

View File

@ -299,12 +299,15 @@ nsFormControlHelper::CalculateSize (nsIPresContext* aPresContext,
nsWidgetRendering mode;
aPresContext->GetWidgetRenderingMode(&mode);
// only add in padding if we are not Gfx
// only add in padding if we are not Gfx, or if we're a Gfx text widget
PRBool requiresWidget = PR_FALSE;
aFrame->RequiresWidget(requiresWidget);
PRInt32 type;
aFrame->GetType(&type);
if (PR_TRUE == requiresWidget || eWidgetRendering_Gfx != mode) {
if (PR_TRUE == requiresWidget || eWidgetRendering_Gfx != mode ||
type==NS_FORM_INPUT_TEXT || type==NS_FORM_TEXTAREA || type==NS_FORM_INPUT_PASSWORD)
{
if (!aWidthExplicit) {
PRInt32 hPadding = (2 * aFrame->GetHorizontalInsidePadding(*aPresContext, p2t, aDesiredSize.width, charWidth));
aDesiredSize.width += hPadding;
@ -340,14 +343,20 @@ nsFormControlHelper::GetFont(nsIFormControlFrame * aFormFrame,
nsWidgetRendering m;
aPresContext->GetWidgetRenderingMode(&m);
// only add in padding if we are not Gfx
// only add in padding if we are not Gfx, excluding the text widgets
PRBool requiresWidget = PR_FALSE;
aFormFrame->RequiresWidget(requiresWidget);
if (PR_TRUE != requiresWidget && eWidgetRendering_Gfx == m) {
aFont = styleFont->mFont;
return;
PRInt32 type;
aFormFrame->GetType(&type);
if (type!=NS_FORM_INPUT_TEXT &&
type!=NS_FORM_TEXTAREA &&
type!=NS_FORM_INPUT_PASSWORD) {
if (PR_TRUE != requiresWidget && eWidgetRendering_Gfx == m) {
aFont = styleFont->mFont;
return;
}
}
nsCompatibility mode;
@ -358,8 +367,6 @@ nsFormControlHelper::GetFont(nsIFormControlFrame * aFormFrame,
return;
}
PRInt32 type;
aFormFrame->GetType(&type);
switch (type) {
case NS_FORM_INPUT_TEXT:
case NS_FORM_TEXTAREA:

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,297 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#ifndef nsGfxTextControlFrame_h___
#define nsGfxTextControlFrame_h___
#include "nsFormControlFrame.h"
#include "nsTextControlFrame.h"
#include "nsIStreamObserver.h"
#include "nsITextEditor.h"
#include "nsIDocumentObserver.h"
#include "nsIDOMKeyListener.h"
class nsIContent;
class nsIFrame;
class nsIPresContext;
class nsIWebShell;
class nsGfxTextControlFrame;
/*******************************************************************************
* EnderTempObserver XXX temporary until doc manager/loader is in place
******************************************************************************/
class EnderTempObserver : public nsIStreamObserver
{
public:
EnderTempObserver()
{
NS_INIT_REFCNT();
mFirstCall = PR_TRUE;
}
NS_IMETHOD SetFrame(nsGfxTextControlFrame *aFrame);
virtual ~EnderTempObserver() {};
// nsISupports
NS_DECL_ISUPPORTS
// nsIStreamObserver
NS_IMETHOD OnStartBinding(nsIURL* aURL, const char *aContentType);
NS_IMETHOD OnProgress(nsIURL* aURL, PRUint32 aProgress, PRUint32 aProgressMax);
NS_IMETHOD OnStatus(nsIURL* aURL, const PRUnichar* aMsg);
NS_IMETHOD OnStopBinding(nsIURL* aURL, nsresult status, const PRUnichar* aMsg);
protected:
nsString mURL;
nsString mOverURL;
nsString mOverTarget;
nsGfxTextControlFrame *mFrame; // not ref counted
PRBool mFirstCall;
};
/*******************************************************************************
* nsEnderDocumentObserver
* This class responds to document changes
******************************************************************************/
class nsEnderDocumentObserver : public nsIDocumentObserver
{
public:
nsEnderDocumentObserver() { NS_INIT_REFCNT(); }
NS_IMETHOD SetFrame(nsGfxTextControlFrame *aFrame);
virtual ~nsEnderDocumentObserver() {};
// nsISupports
NS_DECL_ISUPPORTS
NS_IMETHOD BeginUpdate(nsIDocument *aDocument);
NS_IMETHOD EndUpdate(nsIDocument *aDocument);
NS_IMETHOD BeginLoad(nsIDocument *aDocument);
NS_IMETHOD EndLoad(nsIDocument *aDocument);
NS_IMETHOD BeginReflow(nsIDocument *aDocument, nsIPresShell* aShell);
NS_IMETHOD EndReflow(nsIDocument *aDocument, nsIPresShell* aShell);
NS_IMETHOD ContentChanged(nsIDocument *aDocument,
nsIContent* aContent,
nsISupports* aSubContent);
NS_IMETHOD ContentStatesChanged(nsIDocument* aDocument,
nsIContent* aContent1,
nsIContent* aContent2);
NS_IMETHOD AttributeChanged(nsIDocument *aDocument,
nsIContent* aContent,
nsIAtom* aAttribute,
PRInt32 aHint);
NS_IMETHOD ContentAppended(nsIDocument *aDocument,
nsIContent* aContainer,
PRInt32 aNewIndexInContainer);
NS_IMETHOD ContentInserted(nsIDocument *aDocument,
nsIContent* aContainer,
nsIContent* aChild,
PRInt32 aIndexInContainer);
NS_IMETHOD ContentReplaced(nsIDocument *aDocument,
nsIContent* aContainer,
nsIContent* aOldChild,
nsIContent* aNewChild,
PRInt32 aIndexInContainer);
NS_IMETHOD ContentRemoved(nsIDocument *aDocument,
nsIContent* aContainer,
nsIContent* aChild,
PRInt32 aIndexInContainer);
NS_IMETHOD StyleSheetAdded(nsIDocument *aDocument,
nsIStyleSheet* aStyleSheet);
NS_IMETHOD StyleSheetRemoved(nsIDocument *aDocument,
nsIStyleSheet* aStyleSheet);
NS_IMETHOD StyleSheetDisabledStateChanged(nsIDocument *aDocument,
nsIStyleSheet* aStyleSheet,
PRBool aDisabled);
NS_IMETHOD StyleRuleChanged(nsIDocument *aDocument,
nsIStyleSheet* aStyleSheet,
nsIStyleRule* aStyleRule,
PRInt32 aHint);
NS_IMETHOD StyleRuleAdded(nsIDocument *aDocument,
nsIStyleSheet* aStyleSheet,
nsIStyleRule* aStyleRule);
NS_IMETHOD StyleRuleRemoved(nsIDocument *aDocument,
nsIStyleSheet* aStyleSheet,
nsIStyleRule* aStyleRule);
NS_IMETHOD DocumentWillBeDestroyed(nsIDocument *aDocument);
protected:
nsGfxTextControlFrame *mFrame; // not ref counted
};
/******************************************************************************
* nsEnderKeyListener
******************************************************************************/
class nsEnderKeyListener; // forward declaration for factory
/* factory for ender key listener */
nsresult NS_NewEnderKeyListener(nsEnderKeyListener ** aInstancePtrResult);
class nsEnderKeyListener : public nsIDOMKeyListener
{
public:
/** the default destructor */
virtual ~nsEnderKeyListener() {};
/** SetFrame sets the frame we send event messages to, when necessary
* @param aEditor the frame, can be null, not ref counted (guaranteed to outlive us!)
*/
void SetFrame(nsGfxTextControlFrame *aFrame) {mFrame = aFrame;}
/*interfaces for addref and release and queryinterface*/
NS_DECL_ISUPPORTS
/* nsIDOMKeyListener interfaces */
virtual nsresult HandleEvent(nsIDOMEvent* aEvent);
virtual nsresult KeyDown(nsIDOMEvent* aKeyEvent);
virtual nsresult KeyUp(nsIDOMEvent* aKeyEvent);
virtual nsresult KeyPress(nsIDOMEvent* aKeyEvent);
/*END interfaces from nsIDOMKeyListener*/
friend nsresult NS_NewEnderKeyListener(nsEnderKeyListener ** aInstancePtrResult);
protected:
/** the default constructor. Protected, use the factory to create an instance.
* @see NS_NewEnderKeyListener
*/
nsEnderKeyListener() {NS_INIT_REFCNT();};
protected:
nsGfxTextControlFrame *mFrame; // not ref counted
};
/******************************************************************************
* nsGfxTextControlFrame
******************************************************************************/
// XXX code related to the dummy native text control frame is marked with DUMMY
// and should be removed asap
#include "nsNativeTextControlFrame.h" // DUMMY
class nsGfxTextControlFrame : public nsTextControlFrame
{
public:
nsGfxTextControlFrame();
virtual ~nsGfxTextControlFrame();
NS_IMETHOD InitTextControl();
// nsIFormControlFrame
NS_IMETHOD SetProperty(nsIAtom* aName, const nsString& aValue);
NS_IMETHOD GetProperty(nsIAtom* aName, nsString& aValue);
virtual nsWidgetInitData* GetWidgetInitData(nsIPresContext& aPresContext);
NS_IMETHOD AttributeChanged(nsIPresContext* aPresContext,
nsIContent* aChild,
nsIAtom* aAttribute,
PRInt32 aHint);
virtual void PostCreateWidget(nsIPresContext* aPresContext,
nscoord& aWidth,
nscoord& aHeight);
NS_IMETHOD GetText(nsString* aValue, PRBool aInitialValue);
virtual void EnterPressed(nsIPresContext& aPresContext) ;
virtual PRBool GetNamesValues(PRInt32 aMaxNumValues, PRInt32& aNumValues,
nsString* aValues, nsString* aNames);
virtual void Reset();
// override to interact with webshell
NS_IMETHOD Reflow(nsIPresContext& aPresContext,
nsHTMLReflowMetrics& aDesiredSize,
const nsHTMLReflowState& aReflowState,
nsReflowStatus& aStatus);
NS_IMETHOD Paint(nsIPresContext& aPresContext,
nsIRenderingContext& aRenderingContext,
const nsRect& aDirtyRect,
nsFramePaintLayer aWhichLayer);
virtual void PaintTextControlBackground(nsIPresContext& aPresContext,
nsIRenderingContext& aRenderingContext,
const nsRect& aDirtyRect,
nsFramePaintLayer aWhichLayer);
virtual void PaintTextControl(nsIPresContext& aPresContext,
nsIRenderingContext& aRenderingContext,
const nsRect& aDirtyRect, nsString& aText,
nsIStyleContext* aStyleContext,
nsRect& aRect);
// Utility methods to get and set current widget state
void GetTextControlFrameState(nsString& aValue);
void SetTextControlFrameState(const nsString& aValue);
NS_IMETHOD InstallEditor();
virtual nsresult RequiresWidget(PRBool &aRequiresWidget);
NS_IMETHOD ContentChanged();
void RemoveNewlines(nsString &aString);
protected:
NS_IMETHOD CreateWebShell(nsIPresContext& aPresContext,
const nsSize& aSize);
NS_IMETHOD InitializeTextControl(nsIPresShell *aPresShell, nsIDOMDocument *aDoc);
NS_IMETHOD GetPresShellFor(nsIWebShell* aWebShell, nsIPresShell** aPresShell);
NS_IMETHOD GetFirstNodeOfType(const nsString& aTag, nsIDOMDocument *aDOMDoc, nsIDOMNode **aBodyNode);
NS_IMETHOD GetFirstFrameForType(const nsString& aTag, nsIPresShell *aPresShell, nsIDOMDocument *aDOMDoc, nsIFrame **aResult);
NS_IMETHOD SelectAllTextContent(nsIDOMNode *aBodyNode, nsIDOMSelection *aSelection);
PRBool IsSingleLineTextControl() const;
PRBool IsPlainTextControl() const;
PRBool IsPasswordTextControl() const;
PRBool IsInitialized() const;
protected:
nsIWebShell* mWebShell;
PRBool mCreatingViewer;
EnderTempObserver* mTempObserver;
nsEnderDocumentObserver *mDocObserver;
nsCOMPtr<nsEnderKeyListener> mKeyListener;
nsCOMPtr<nsITextEditor>mEditor;
nsNativeTextControlFrame *mDummyFrame; //DUMMY
PRBool mNeedsStyleInit;
PRBool mDummyInitialized; //DUMMY
};
#endif

View File

@ -0,0 +1,652 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#include "nsCOMPtr.h"
#include "nsNativeTextControlFrame.h"
#include "nsIContent.h"
#include "prtypes.h"
#include "nsIFrame.h"
#include "nsISupports.h"
#include "nsIAtom.h"
#include "nsIPresContext.h"
#include "nsIHTMLContent.h"
#include "nsHTMLIIDs.h"
#include "nsITextWidget.h"
#include "nsITextAreaWidget.h"
#include "nsWidgetsCID.h"
#include "nsSize.h"
#include "nsString.h"
#include "nsHTMLAtoms.h"
#include "nsIStyleContext.h"
#include "nsFont.h"
#include "nsDOMEvent.h"
#include "nsIFormControl.h"
#include "nsFormFrame.h"
#include "nsIContent.h"
#include "nsIDOMHTMLInputElement.h"
#include "nsIDOMHTMLTextAreaElement.h"
#include "nsCSSRendering.h"
#include "nsIDeviceContext.h"
#include "nsIFontMetrics.h"
#include "nsILookAndFeel.h"
#include "nsIComponentManager.h"
#ifdef SingleSignon
#include "nsIDocument.h"
#include "prmem.h"
#include "nsIURL.h"
#include "nsIWalletService.h"
#include "nsIServiceManager.h"
static NS_DEFINE_IID(kIWalletServiceIID, NS_IWALLETSERVICE_IID);
static NS_DEFINE_IID(kWalletServiceCID, NS_WALLETSERVICE_CID);
#endif
static NS_DEFINE_IID(kIFormControlIID, NS_IFORMCONTROL_IID);
static NS_DEFINE_IID(kTextCID, NS_TEXTFIELD_CID);
static NS_DEFINE_IID(kTextAreaCID, NS_TEXTAREA_CID);
static NS_DEFINE_IID(kITextWidgetIID, NS_ITEXTWIDGET_IID);
static NS_DEFINE_IID(kITextAreaWidgetIID, NS_ITEXTAREAWIDGET_IID);
static NS_DEFINE_IID(kIDOMHTMLTextAreaElementIID, NS_IDOMHTMLTEXTAREAELEMENT_IID);
static NS_DEFINE_IID(kIDOMHTMLInputElementIID, NS_IDOMHTMLINPUTELEMENT_IID);
static NS_DEFINE_IID(kLookAndFeelCID, NS_LOOKANDFEEL_CID);
static NS_DEFINE_IID(kILookAndFeelIID, NS_ILOOKANDFEEL_IID);
nsresult
NS_NewNativeTextControlFrame(nsIFrame** aNewFrame)
{
NS_PRECONDITION(aNewFrame, "null OUT ptr");
if (nsnull == aNewFrame) {
return NS_ERROR_NULL_POINTER;
}
nsNativeTextControlFrame* it = new nsNativeTextControlFrame;
if (!it) {
return NS_ERROR_OUT_OF_MEMORY;
}
*aNewFrame = it;
return NS_OK;
}
void
nsNativeTextControlFrame::EnterPressed(nsIPresContext& aPresContext)
{
if (mFormFrame && mFormFrame->CanSubmit(*this)) {
nsIContent *formContent = nsnull;
mFormFrame->GetContent(&formContent);
if (nsnull != formContent) {
nsEvent event;
nsEventStatus status = nsEventStatus_eIgnore;
event.eventStructType = NS_EVENT;
event.message = NS_FORM_SUBMIT;
formContent->HandleDOMEvent(aPresContext, &event, nsnull, NS_EVENT_FLAG_INIT, status);
NS_RELEASE(formContent);
}
mFormFrame->OnSubmit(&aPresContext, this);
}
}
nsWidgetInitData*
nsNativeTextControlFrame::GetWidgetInitData(nsIPresContext& aPresContext)
{
PRInt32 type;
GetType(&type);
nsTextWidgetInitData* data = nsnull;
PRBool readOnly = nsFormFrame::GetReadonly(this);
if ((NS_FORM_INPUT_PASSWORD == type) || readOnly) {
data = new nsTextWidgetInitData();
data->mIsPassword = PR_FALSE;
data->mIsReadOnly = PR_FALSE;
if (NS_FORM_INPUT_PASSWORD == type) {
data->clipChildren = PR_TRUE;
data->mIsPassword = PR_TRUE;
}
if (readOnly) {
data->mIsReadOnly = PR_TRUE;
}
}
return data;
}
NS_IMETHODIMP
nsNativeTextControlFrame::GetText(nsString* aText, PRBool aInitialValue)
{
nsresult result = NS_CONTENT_ATTR_NOT_THERE;
PRInt32 type;
GetType(&type);
if ((NS_FORM_INPUT_TEXT == type) || (NS_FORM_INPUT_PASSWORD == type)) {
result = nsFormControlHelper::GetInputElementValue(mContent, aText, aInitialValue);
} else {
nsIDOMHTMLTextAreaElement* textArea = nsnull;
result = mContent->QueryInterface(kIDOMHTMLTextAreaElementIID, (void**)&textArea);
if ((NS_OK == result) && textArea) {
if (PR_TRUE == aInitialValue) {
result = textArea->GetDefaultValue(*aText);
}
else {
result = textArea->GetValue(*aText);
}
NS_RELEASE(textArea);
}
}
return result;
}
NS_IMETHODIMP
nsNativeTextControlFrame::AttributeChanged(nsIPresContext* aPresContext,
nsIContent* aChild,
nsIAtom* aAttribute,
PRInt32 aHint)
{
nsresult result = NS_OK;
if (mWidget) {
nsITextWidget* text = nsnull;
result = mWidget->QueryInterface(kITextWidgetIID, (void**)&text);
if ((NS_OK == result) && (nsnull != text)) {
if (nsHTMLAtoms::value == aAttribute) {
nsString value;
/*XXXnsresult rv = */GetText(&value, PR_TRUE);
PRUint32 ignore;
text->SetText(value, ignore);
nsFormFrame::StyleChangeReflow(aPresContext, this);
} else if (nsHTMLAtoms::maxlength == aAttribute) {
PRInt32 maxLength;
nsresult rv = GetMaxLength(&maxLength);
if (NS_CONTENT_ATTR_NOT_THERE != rv) {
text->SetMaxTextLength(maxLength);
}
} else if (nsHTMLAtoms::readonly == aAttribute) {
PRBool oldReadOnly;
text->SetReadOnly(nsFormFrame::GetReadonly(this),oldReadOnly);
}
else if (nsHTMLAtoms::size == aAttribute) {
nsFormFrame::StyleChangeReflow(aPresContext, this);
}
// Allow the base class to handle common attributes supported
// by all form elements...
else {
result = nsFormControlFrame::AttributeChanged(aPresContext, aChild, aAttribute, aHint);
}
NS_RELEASE(text);
}
// XXX Ick, create an common interface that has the functionality of nsTextHelper
else { // We didn't get a Text, is it a TextArea?
nsITextAreaWidget* textArea = nsnull;
result = mWidget->QueryInterface(kITextAreaWidgetIID, (void**)&textArea);
if ((NS_OK == result) && (nsnull != textArea)) {
if (nsHTMLAtoms::value == aAttribute) {
nsString value;
/*XXXnsresult rv = */GetText(&value, PR_TRUE);
PRUint32 ignore;
textArea->SetText(value, ignore);
nsFormFrame::StyleChangeReflow(aPresContext, this);
} else if (nsHTMLAtoms::maxlength == aAttribute) {
PRInt32 maxLength;
nsresult rv = GetMaxLength(&maxLength);
if (NS_CONTENT_ATTR_NOT_THERE != rv) {
textArea->SetMaxTextLength(maxLength);
}
} else if (nsHTMLAtoms::readonly == aAttribute) {
PRBool oldReadOnly;
textArea->SetReadOnly(nsFormFrame::GetReadonly(this),oldReadOnly);
}
else if (nsHTMLAtoms::size == aAttribute) {
nsFormFrame::StyleChangeReflow(aPresContext, this);
}
// Allow the base class to handle common attributes supported
// by all form elements...
else {
result = nsFormControlFrame::AttributeChanged(aPresContext, aChild, aAttribute, aHint);
}
NS_RELEASE(textArea);
}
else { // We didn't get a Text or TextArea. Uh oh...
result = nsFormControlFrame::AttributeChanged(aPresContext, aChild, aAttribute, aHint);
}
}
}
return result;
}
void
nsNativeTextControlFrame::PostCreateWidget(nsIPresContext* aPresContext,
nscoord& aWidth,
nscoord& aHeight)
{
if (!mWidget) {
return;
}
PRInt32 type;
GetType(&type);
nsFont font(aPresContext->GetDefaultFixedFontDeprecated());
GetFont(aPresContext, font);
mWidget->SetFont(font);
SetColors(*aPresContext);
PRUint32 ignore;
nsAutoString value;
nsITextAreaWidget* textArea = nsnull;
nsITextWidget* text = nsnull;
if (NS_OK == mWidget->QueryInterface(kITextWidgetIID,(void**)&text)) {
#ifdef SingleSignon
/* get name of text */
PRBool failed = PR_TRUE;
nsAutoString name;
GetName(&name);
/* get url name */
char *URLName = nsnull;
nsIURL* docURL = nsnull;
nsIDocument* doc = nsnull;
mContent->GetDocument(doc);
if (nsnull != doc) {
docURL = doc->GetDocumentURL();
NS_RELEASE(doc);
if (nsnull != docURL) {
const char* spec;
(void)docURL->GetSpec(&spec);
if (nsnull != spec) {
URLName = (char*)PR_Malloc(PL_strlen(spec)+1);
PL_strcpy(URLName, spec);
}
NS_RELEASE(docURL);
}
}
if (nsnull != URLName) {
/* invoke single-signon to get previously-used value of text */
nsIWalletService *service;
nsresult res = nsServiceManager::GetService(kWalletServiceCID,
kIWalletServiceIID,
(nsISupports **)&service);
if ((NS_OK == res) && (nsnull != service)) {
char* valueString = NULL;
char* nameString = name.ToNewCString();
res = service->SI_RestoreSignonData(URLName, nameString, &valueString);
delete[] nameString;
NS_RELEASE(service);
PR_FREEIF(URLName);
if (valueString && *valueString) {
value = valueString;
failed = PR_FALSE;
}
}
}
if (failed) {
GetText(&value, PR_TRUE);
}
#else
GetText(&value, PR_TRUE);
#endif
text->SetText(value, ignore);
PRInt32 maxLength;
nsresult result = GetMaxLength(&maxLength);
if (NS_CONTENT_ATTR_NOT_THERE != result) {
text->SetMaxTextLength(maxLength);
}
NS_RELEASE(text);
} else if (NS_OK == mWidget->QueryInterface(kITextAreaWidgetIID,(void**)&textArea)) {
GetText(&value, PR_TRUE);
textArea->SetText(value, ignore);
NS_RELEASE(textArea);
}
if (nsFormFrame::GetDisabled(this)) {
mWidget->Enable(PR_FALSE);
}
}
PRBool
nsNativeTextControlFrame::GetNamesValues(PRInt32 aMaxNumValues, PRInt32& aNumValues,
nsString* aValues, nsString* aNames)
{
if (!mWidget) {
return PR_FALSE;
}
nsAutoString name;
nsresult result = GetName(&name);
if ((aMaxNumValues <= 0) || (NS_CONTENT_ATTR_NOT_THERE == result)) {
return PR_FALSE;
}
PRUint32 size;
nsITextWidget* text = nsnull;
nsITextAreaWidget* textArea = nsnull;
aNames[0] = name;
aNumValues = 1;
if (NS_OK == mWidget->QueryInterface(kITextWidgetIID,(void**)&text)) {
text->GetText(aValues[0],0,size); // the last parm is not used
NS_RELEASE(text);
return PR_TRUE;
} else if (NS_OK == mWidget->QueryInterface(kITextAreaWidgetIID,(void**)&textArea)) {
textArea->GetText(aValues[0],0,size); // the last parm is not used
NS_RELEASE(textArea);
return PR_TRUE;
}
return PR_FALSE;
}
void
nsNativeTextControlFrame::Reset()
{
if (!mWidget) {
return;
}
nsITextWidget* text = nsnull;
nsITextAreaWidget* textArea = nsnull;
nsAutoString value;
nsresult valStatus = GetText(&value, PR_TRUE);
PRUint32 size;
if (NS_OK == mWidget->QueryInterface(kITextWidgetIID,(void**)&text)) {
if (NS_CONTENT_ATTR_HAS_VALUE == valStatus) {
text->SetText(value,size);
} else {
text->SetText("",size);
}
NS_RELEASE(text);
} else if (NS_OK == mWidget->QueryInterface(kITextAreaWidgetIID,(void**)&textArea)) {
if (NS_CONTENT_ATTR_HAS_VALUE == valStatus) {
textArea->SetText(value,size);
} else {
textArea->SetText("",size);
}
NS_RELEASE(textArea);
}
}
void
nsNativeTextControlFrame::PaintTextControlBackground(nsIPresContext& aPresContext,
nsIRenderingContext& aRenderingContext,
const nsRect& aDirtyRect,
nsFramePaintLayer aWhichLayer) {
nsFormControlFrame::Paint(aPresContext, aRenderingContext, aDirtyRect, aWhichLayer);
}
void
nsNativeTextControlFrame::PaintTextControl(nsIPresContext& aPresContext,
nsIRenderingContext& aRenderingContext,
const nsRect& aDirtyRect,
nsString& aText,
nsIStyleContext* aStyleContext, nsRect& aRect)
{
aRenderingContext.PushState();
const nsStyleSpacing* spacing =
(const nsStyleSpacing*)aStyleContext->GetStyleData(eStyleStruct_Spacing);
nsMargin border;
spacing->CalcBorderFor(this, border);
float p2t;
aPresContext.GetScaledPixelsToTwips(&p2t);
nscoord onePixel = NSIntPixelsToTwips(1, p2t);
nsRect outside(aRect.x, aRect.y, aRect.width, aRect.height);
outside.Deflate(border);
outside.Deflate(onePixel, onePixel);
nsRect inside(outside);
inside.Deflate(onePixel, onePixel);
#if 0
if (mGotFocus) {
PaintFocus(aRenderingContext,
aDirtyRect, inside, outside);
}
#endif
float appUnits;
float devUnits;
float scale;
nsIDeviceContext * context;
aRenderingContext.GetDeviceContext(context);
context->GetCanonicalPixelScale(scale);
context->GetAppUnitsToDevUnits(devUnits);
context->GetDevUnitsToAppUnits(appUnits);
aRenderingContext.SetColor(NS_RGB(0,0,0));
nsFont font(aPresContext.GetDefaultFixedFontDeprecated());
GetFont(&aPresContext, font);
aRenderingContext.SetFont(font);
nscoord textWidth;
nscoord textHeight;
aRenderingContext.GetWidth(aText, textWidth);
nsIFontMetrics* metrics;
context->GetMetricsFor(font, metrics);
metrics->GetHeight(textHeight);
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 = aText.Length();
aText.SetLength(0);
for (i=0;i<len;i++) {
aText.Append("*");
}
}
aRenderingContext.DrawString(aText, x, y);
} else {
float sbWidth;
float sbHeight;
context->GetCanonicalPixelScale(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 = aText.Find('\n', 0);
while (1) {
nsString substr;
if (-1 == pos) {
// Single line, no carriage return.
aText.Right(substr, aText.Length()-oldPos);
aRenderingContext.DrawString(substr, x, y);
break;
}
// Strip off substr up to carriage return
aText.Mid(substr, oldPos, ((pos - oldPos) - 1));
aRenderingContext.DrawString(substr, x, y);
y += textHeight;
// Advance to the next carriage return
pos++;
oldPos = pos;
pos = aText.Find('\n', pos);
}
aRenderingContext.PopState(clipEmpty);
// Scrollbars
nsIAtom * sbAtom = NS_NewAtom(":scrollbar-look");
nsIStyleContext* scrollbarStyle;
aPresContext.ResolvePseudoStyleContextFor(mContent, sbAtom, aStyleContext, PR_FALSE, &scrollbarStyle);
NS_RELEASE(sbAtom);
sbAtom = NS_NewAtom(":scrollbar-arrow-look");
nsIStyleContext* arrowStyle;
aPresContext.ResolvePseudoStyleContextFor(mContent, sbAtom, aStyleContext, PR_FALSE, &arrowStyle);
NS_RELEASE(sbAtom);
nsRect srect(aRect.width-scrollbarScaledWidth-(2*onePixel), 2*onePixel, scrollbarScaledWidth, aRect.height-(onePixel*4)-scrollbarScaledWidth);
nsFormControlHelper::PaintScrollbar(aRenderingContext,aPresContext, aDirtyRect, srect, PR_FALSE, onePixel,
scrollbarStyle, arrowStyle, this, aRect);
// Horizontal
srect.SetRect(2*onePixel, aRect.height-scrollbarScaledHeight-(2*onePixel), aRect.width-(onePixel*4)-scrollbarScaledHeight, scrollbarScaledHeight);
nsFormControlHelper::PaintScrollbar(aRenderingContext,aPresContext, aDirtyRect, srect, PR_TRUE, onePixel,
scrollbarStyle, arrowStyle, this, aRect);
// 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(aRect.width-scrollbarScaledWidth-(2*onePixel), aRect.height-scrollbarScaledHeight-(onePixel*2), scrollbarScaledWidth, scrollbarScaledHeight);
nsCSSRendering::PaintBackground(aPresContext, aRenderingContext, this,
aDirtyRect, srect, *sbColor, *spacing, 0, 0);
}
NS_RELEASE(context);
PRBool status;
aRenderingContext.PopState(status);
}
NS_METHOD
nsNativeTextControlFrame::Paint(nsIPresContext& aPresContext,
nsIRenderingContext& aRenderingContext,
const nsRect& aDirtyRect,
nsFramePaintLayer aWhichLayer)
{
PaintTextControlBackground(aPresContext, aRenderingContext, aDirtyRect, aWhichLayer);
if (NS_FRAME_PAINT_LAYER_FOREGROUND == aWhichLayer) {
nsString text;
GetText(&text, PR_FALSE);
nsRect rect(0, 0, mRect.width, mRect.height);
PaintTextControl(aPresContext, aRenderingContext, aDirtyRect, text, mStyleContext, rect);
}
return NS_OK;
}
void nsNativeTextControlFrame::GetTextControlFrameState(nsString& aValue)
{
if (nsnull != mWidget) {
nsITextWidget* text = nsnull;
nsITextAreaWidget* textArea = nsnull;
PRUint32 size = 0;
if (NS_OK == mWidget->QueryInterface(kITextWidgetIID,(void**)&text)) {
text->GetText(aValue,0,size);
NS_RELEASE(text);
}
else if (NS_OK == mWidget->QueryInterface(kITextAreaWidgetIID,
(void**)&textArea)) {
textArea->GetText(aValue,0, size);
NS_RELEASE(textArea);
}
}
else {
//XXX: this should return the a local field for GFX-rendered widgets aValue = "";
}
}
void nsNativeTextControlFrame::SetTextControlFrameState(const nsString& aValue)
{
if (nsnull != mWidget) {
nsITextWidget* text = nsnull;
nsITextAreaWidget* textArea = nsnull;
PRUint32 size = 0;
if (NS_SUCCEEDED(mWidget->QueryInterface(kITextWidgetIID,(void**)&text))) {
text->SetText(aValue,size);
NS_RELEASE(text);
} else if (NS_OK == mWidget->QueryInterface(kITextAreaWidgetIID,
(void**)&textArea)) {
textArea->SetText(aValue,size);
NS_RELEASE(textArea);
}
}
}
NS_IMETHODIMP nsNativeTextControlFrame::SetProperty(nsIAtom* aName, const nsString& aValue)
{
nsresult rv = NS_OK;
if (nsHTMLAtoms::value == aName) {
SetTextControlFrameState(aValue);
} else if (nsHTMLAtoms::select == aName) {
if (nsnull != mWidget) {
nsITextWidget *textWidget;
rv = mWidget->QueryInterface(kITextWidgetIID, (void**)&textWidget);
if (NS_SUCCEEDED(rv)) {
textWidget->SelectAll();
NS_RELEASE(textWidget);
}
nsITextAreaWidget *textAreaWidget;
rv = mWidget->QueryInterface(kITextAreaWidgetIID, (void**)&textAreaWidget);
if (NS_SUCCEEDED(rv)) {
textAreaWidget->SelectAll();
NS_RELEASE(textAreaWidget);
}
}
}
else {
return nsFormControlFrame::SetProperty(aName, aValue);
}
return rv;
}
NS_IMETHODIMP nsNativeTextControlFrame::GetProperty(nsIAtom* aName, nsString& aValue)
{
// Return the value of the property from the widget it is not null.
// If widget is null, assume the widget is GFX-rendered and return a member variable instead.
if (nsHTMLAtoms::value == aName) {
GetTextControlFrameState(aValue);
}
else {
return nsFormControlFrame::GetProperty(aName, aValue);
}
return NS_OK;
}
nsresult nsNativeTextControlFrame::RequiresWidget(PRBool &aRequiresWidget)
{
aRequiresWidget = PR_TRUE;
return NS_OK;
}

View File

@ -0,0 +1,77 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#ifndef nsNativeTextControlFrame_h___
#define nsNativeTextControlFrame_h___
#include "nsTextControlFrame.h"
class nsIContent;
class nsIFrame;
class nsIPresContext;
class nsNativeTextControlFrame : public nsTextControlFrame
{
public:
// nsIFormControlFrame
NS_IMETHOD SetProperty(nsIAtom* aName, const nsString& aValue);
NS_IMETHOD GetProperty(nsIAtom* aName, nsString& aValue);
virtual nsWidgetInitData* GetWidgetInitData(nsIPresContext& aPresContext);
NS_IMETHOD AttributeChanged(nsIPresContext* aPresContext,
nsIContent* aChild,
nsIAtom* aAttribute,
PRInt32 aHint);
virtual void PostCreateWidget(nsIPresContext* aPresContext,
nscoord& aWidth,
nscoord& aHeight);
NS_IMETHOD GetText(nsString* aValue, PRBool aInitialValue);
virtual void EnterPressed(nsIPresContext& aPresContext) ;
virtual PRBool GetNamesValues(PRInt32 aMaxNumValues, PRInt32& aNumValues,
nsString* aValues, nsString* aNames);
virtual void Reset();
NS_IMETHOD Paint(nsIPresContext& aPresContext,
nsIRenderingContext& aRenderingContext,
const nsRect& aDirtyRect,
nsFramePaintLayer aWhichLayer);
virtual void PaintTextControlBackground(nsIPresContext& aPresContext,
nsIRenderingContext& aRenderingContext,
const nsRect& aDirtyRect,
nsFramePaintLayer aWhichLayer);
virtual void PaintTextControl(nsIPresContext& aPresContext,
nsIRenderingContext& aRenderingContext,
const nsRect& aDirtyRect, nsString& aText,
nsIStyleContext* aStyleContext,
nsRect& aRect);
// Utility methods to get and set current widget state
void GetTextControlFrameState(nsString& aValue);
void SetTextControlFrameState(const nsString& aValue);
virtual nsresult RequiresWidget(PRBool &aRequiresWidget);
};
#endif

View File

@ -66,21 +66,6 @@ static NS_DEFINE_IID(kIDOMHTMLInputElementIID, NS_IDOMHTMLINPUTELEMENT_IID);
static NS_DEFINE_IID(kLookAndFeelCID, NS_LOOKANDFEEL_CID);
static NS_DEFINE_IID(kILookAndFeelIID, NS_ILOOKANDFEEL_IID);
nsresult
NS_NewTextControlFrame(nsIFrame** aNewFrame)
{
NS_PRECONDITION(aNewFrame, "null OUT ptr");
if (nsnull == aNewFrame) {
return NS_ERROR_NULL_POINTER;
}
nsTextControlFrame* it = new nsTextControlFrame;
if (!it) {
return NS_ERROR_OUT_OF_MEMORY;
}
*aNewFrame = it;
return NS_OK;
}
nscoord
nsTextControlFrame::GetVerticalBorderWidth(float aPixToTwip) const
{
@ -209,26 +194,6 @@ nsTextControlFrame::GetCID()
}
}
void
nsTextControlFrame::EnterPressed(nsIPresContext& aPresContext)
{
if (mFormFrame && mFormFrame->CanSubmit(*this)) {
nsIContent *formContent = nsnull;
mFormFrame->GetContent(&formContent);
if (nsnull != formContent) {
nsEvent event;
nsEventStatus status = nsEventStatus_eIgnore;
event.eventStructType = NS_EVENT;
event.message = NS_FORM_SUBMIT;
formContent->HandleDOMEvent(aPresContext, &event, nsnull, NS_EVENT_FLAG_INIT, status);
NS_RELEASE(formContent);
}
mFormFrame->OnSubmit(&aPresContext, this);
}
}
#define DEFAULT_PIXEL_WIDTH 20
void
@ -315,311 +280,12 @@ nsTextControlFrame::GetDesiredSize(nsIPresContext* aPresContext,
}
nsWidgetInitData*
nsTextControlFrame::GetWidgetInitData(nsIPresContext& aPresContext)
{
PRInt32 type;
GetType(&type);
nsTextWidgetInitData* data = nsnull;
PRBool readOnly = nsFormFrame::GetReadonly(this);
if ((NS_FORM_INPUT_PASSWORD == type) || readOnly) {
data = new nsTextWidgetInitData();
data->mIsPassword = PR_FALSE;
data->mIsReadOnly = PR_FALSE;
if (NS_FORM_INPUT_PASSWORD == type) {
data->clipChildren = PR_TRUE;
data->mIsPassword = PR_TRUE;
}
if (readOnly) {
data->mIsReadOnly = PR_TRUE;
}
}
return data;
}
NS_IMETHODIMP
nsTextControlFrame::GetText(nsString* aText, PRBool aInitialValue)
{
nsresult result = NS_CONTENT_ATTR_NOT_THERE;
PRInt32 type;
GetType(&type);
if ((NS_FORM_INPUT_TEXT == type) || (NS_FORM_INPUT_PASSWORD == type)) {
result = nsFormControlHelper::GetInputElementValue(mContent, aText, aInitialValue);
/* XXX REMOVE
nsIDOMHTMLInputElement* textElem = nsnull;
result = mContent->QueryInterface(kIDOMHTMLInputElementIID, (void**)&textElem);
if ((NS_OK == result) && textElem) {
if (PR_TRUE == aInitialValue) {
result = textElem->GetDefaultValue(*aText);
}
else {
result = textElem->GetValue(*aText);
}
NS_RELEASE(textElem);
}
*/
} else {
nsIDOMHTMLTextAreaElement* textArea = nsnull;
result = mContent->QueryInterface(kIDOMHTMLTextAreaElementIID, (void**)&textArea);
if ((NS_OK == result) && textArea) {
if (PR_TRUE == aInitialValue) {
result = textArea->GetDefaultValue(*aText);
}
else {
result = textArea->GetValue(*aText);
}
NS_RELEASE(textArea);
}
}
return result;
}
NS_IMETHODIMP
nsTextControlFrame::AttributeChanged(nsIPresContext* aPresContext,
nsIContent* aChild,
nsIAtom* aAttribute,
PRInt32 aHint)
{
nsresult result = NS_OK;
if (mWidget) {
nsITextWidget* text = nsnull;
result = mWidget->QueryInterface(kITextWidgetIID, (void**)&text);
if ((NS_OK == result) && (nsnull != text)) {
if (nsHTMLAtoms::value == aAttribute) {
nsString value;
/*XXXnsresult rv = */GetText(&value, PR_TRUE);
PRUint32 ignore;
text->SetText(value, ignore);
nsFormFrame::StyleChangeReflow(aPresContext, this);
} else if (nsHTMLAtoms::maxlength == aAttribute) {
PRInt32 maxLength;
nsresult rv = GetMaxLength(&maxLength);
if (NS_CONTENT_ATTR_NOT_THERE != rv) {
text->SetMaxTextLength(maxLength);
}
} else if (nsHTMLAtoms::readonly == aAttribute) {
PRBool oldReadOnly;
text->SetReadOnly(nsFormFrame::GetReadonly(this),oldReadOnly);
}
else if (nsHTMLAtoms::size == aAttribute) {
nsFormFrame::StyleChangeReflow(aPresContext, this);
}
// Allow the base class to handle common attributes supported
// by all form elements...
else {
result = nsFormControlFrame::AttributeChanged(aPresContext, aChild, aAttribute, aHint);
}
NS_RELEASE(text);
}
// XXX Ick, create an common interface that has the functionality of nsTextHelper
else { // We didn't get a Text, is it a TextArea?
nsITextAreaWidget* textArea = nsnull;
result = mWidget->QueryInterface(kITextAreaWidgetIID, (void**)&textArea);
if ((NS_OK == result) && (nsnull != textArea)) {
if (nsHTMLAtoms::value == aAttribute) {
nsString value;
/*XXXnsresult rv = */GetText(&value, PR_TRUE);
PRUint32 ignore;
textArea->SetText(value, ignore);
nsFormFrame::StyleChangeReflow(aPresContext, this);
} else if (nsHTMLAtoms::maxlength == aAttribute) {
PRInt32 maxLength;
nsresult rv = GetMaxLength(&maxLength);
if (NS_CONTENT_ATTR_NOT_THERE != rv) {
textArea->SetMaxTextLength(maxLength);
}
} else if (nsHTMLAtoms::readonly == aAttribute) {
PRBool oldReadOnly;
textArea->SetReadOnly(nsFormFrame::GetReadonly(this),oldReadOnly);
}
else if (nsHTMLAtoms::size == aAttribute) {
nsFormFrame::StyleChangeReflow(aPresContext, this);
}
// Allow the base class to handle common attributes supported
// by all form elements...
else {
result = nsFormControlFrame::AttributeChanged(aPresContext, aChild, aAttribute, aHint);
}
NS_RELEASE(textArea);
}
else { // We didn't get a Text or TextArea. Uh oh...
result = nsFormControlFrame::AttributeChanged(aPresContext, aChild, aAttribute, aHint);
}
}
}
return result;
}
void
nsTextControlFrame::PostCreateWidget(nsIPresContext* aPresContext,
nscoord& aWidth,
nscoord& aHeight)
{
if (!mWidget) {
return;
}
PRInt32 type;
GetType(&type);
nsFont font(aPresContext->GetDefaultFixedFontDeprecated());
GetFont(aPresContext, font);
mWidget->SetFont(font);
SetColors(*aPresContext);
PRUint32 ignore;
nsAutoString value;
nsITextAreaWidget* textArea = nsnull;
nsITextWidget* text = nsnull;
if (NS_OK == mWidget->QueryInterface(kITextWidgetIID,(void**)&text)) {
#ifdef SingleSignon
/* get name of text */
PRBool failed = PR_TRUE;
nsAutoString name;
GetName(&name);
/* get url name */
char *URLName = nsnull;
nsIURL* docURL = nsnull;
nsIDocument* doc = nsnull;
mContent->GetDocument(doc);
if (nsnull != doc) {
docURL = doc->GetDocumentURL();
NS_RELEASE(doc);
if (nsnull != docURL) {
const char* spec;
(void)docURL->GetSpec(&spec);
if (nsnull != spec) {
URLName = (char*)PR_Malloc(PL_strlen(spec)+1);
PL_strcpy(URLName, spec);
}
NS_RELEASE(docURL);
}
}
if (nsnull != URLName) {
/* invoke single-signon to get previously-used value of text */
nsIWalletService *service;
nsresult res = nsServiceManager::GetService(kWalletServiceCID,
kIWalletServiceIID,
(nsISupports **)&service);
if ((NS_OK == res) && (nsnull != service)) {
char* valueString = NULL;
char* nameString = name.ToNewCString();
res = service->SI_RestoreSignonData(URLName, nameString, &valueString);
delete[] nameString;
NS_RELEASE(service);
PR_FREEIF(URLName);
if (valueString && *valueString) {
value = valueString;
failed = PR_FALSE;
}
}
}
if (failed) {
GetText(&value, PR_TRUE);
}
#else
GetText(&value, PR_TRUE);
#endif
text->SetText(value, ignore);
PRInt32 maxLength;
nsresult result = GetMaxLength(&maxLength);
if (NS_CONTENT_ATTR_NOT_THERE != result) {
text->SetMaxTextLength(maxLength);
}
NS_RELEASE(text);
} else if (NS_OK == mWidget->QueryInterface(kITextAreaWidgetIID,(void**)&textArea)) {
GetText(&value, PR_TRUE);
textArea->SetText(value, ignore);
NS_RELEASE(textArea);
}
if (nsFormFrame::GetDisabled(this)) {
mWidget->Enable(PR_FALSE);
}
}
PRInt32
nsTextControlFrame::GetMaxNumValues()
{
return 1;
}
PRBool
nsTextControlFrame::GetNamesValues(PRInt32 aMaxNumValues, PRInt32& aNumValues,
nsString* aValues, nsString* aNames)
{
if (!mWidget) {
return PR_FALSE;
}
nsAutoString name;
nsresult result = GetName(&name);
if ((aMaxNumValues <= 0) || (NS_CONTENT_ATTR_NOT_THERE == result)) {
return PR_FALSE;
}
PRUint32 size;
nsITextWidget* text = nsnull;
nsITextAreaWidget* textArea = nsnull;
aNames[0] = name;
aNumValues = 1;
if (NS_OK == mWidget->QueryInterface(kITextWidgetIID,(void**)&text)) {
text->GetText(aValues[0],0,size); // the last parm is not used
NS_RELEASE(text);
return PR_TRUE;
} else if (NS_OK == mWidget->QueryInterface(kITextAreaWidgetIID,(void**)&textArea)) {
textArea->GetText(aValues[0],0,size); // the last parm is not used
NS_RELEASE(textArea);
return PR_TRUE;
}
return PR_FALSE;
}
void
nsTextControlFrame::Reset()
{
if (!mWidget) {
return;
}
nsITextWidget* text = nsnull;
nsITextAreaWidget* textArea = nsnull;
nsAutoString value;
nsresult valStatus = GetText(&value, PR_TRUE);
PRUint32 size;
if (NS_OK == mWidget->QueryInterface(kITextWidgetIID,(void**)&text)) {
if (NS_CONTENT_ATTR_HAS_VALUE == valStatus) {
text->SetText(value,size);
} else {
text->SetText("",size);
}
NS_RELEASE(text);
} else if (NS_OK == mWidget->QueryInterface(kITextAreaWidgetIID,(void**)&textArea)) {
if (NS_CONTENT_ATTR_HAS_VALUE == valStatus) {
textArea->SetText(value,size);
} else {
textArea->SetText("",size);
}
NS_RELEASE(textArea);
}
}
NS_IMETHODIMP
nsTextControlFrame::GetCursor(nsIPresContext& aPresContext, nsPoint& aPoint, PRInt32& aCursor)
@ -639,261 +305,3 @@ nsTextControlFrame::GetFrameName(nsString& aResult) const
{
return MakeFrameName("TextControl", aResult);
}
void
nsTextControlFrame::PaintTextControlBackground(nsIPresContext& aPresContext,
nsIRenderingContext& aRenderingContext,
const nsRect& aDirtyRect,
nsFramePaintLayer aWhichLayer) {
nsFormControlFrame::Paint(aPresContext, aRenderingContext, aDirtyRect, aWhichLayer);
}
void
nsTextControlFrame::PaintTextControl(nsIPresContext& aPresContext,
nsIRenderingContext& aRenderingContext,
const nsRect& aDirtyRect,
nsString& aText,
nsIStyleContext* aStyleContext, nsRect& aRect)
{
aRenderingContext.PushState();
const nsStyleSpacing* spacing =
(const nsStyleSpacing*)aStyleContext->GetStyleData(eStyleStruct_Spacing);
nsMargin border;
spacing->CalcBorderFor(this, border);
float p2t;
aPresContext.GetScaledPixelsToTwips(&p2t);
nscoord onePixel = NSIntPixelsToTwips(1, p2t);
nsRect outside(aRect.x, aRect.y, aRect.width, aRect.height);
outside.Deflate(border);
outside.Deflate(onePixel, onePixel);
nsRect inside(outside);
inside.Deflate(onePixel, onePixel);
#if 0
if (mGotFocus) {
PaintFocus(aRenderingContext,
aDirtyRect, inside, outside);
}
#endif
float appUnits;
float devUnits;
float scale;
nsIDeviceContext * context;
aRenderingContext.GetDeviceContext(context);
context->GetCanonicalPixelScale(scale);
context->GetAppUnitsToDevUnits(devUnits);
context->GetDevUnitsToAppUnits(appUnits);
aRenderingContext.SetColor(NS_RGB(0,0,0));
nsFont font(aPresContext.GetDefaultFixedFontDeprecated());
GetFont(&aPresContext, font);
aRenderingContext.SetFont(font);
nscoord textWidth;
nscoord textHeight;
aRenderingContext.GetWidth(aText, textWidth);
nsIFontMetrics* metrics;
context->GetMetricsFor(font, metrics);
metrics->GetHeight(textHeight);
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 = aText.Length();
aText.SetLength(0);
for (i=0;i<len;i++) {
aText.Append("*");
}
}
aRenderingContext.DrawString(aText, x, y);
} else {
float sbWidth;
float sbHeight;
context->GetCanonicalPixelScale(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 = aText.Find('\n', 0);
while (1) {
nsString substr;
if (-1 == pos) {
// Single line, no carriage return.
aText.Right(substr, aText.Length()-oldPos);
aRenderingContext.DrawString(substr, x, y);
break;
}
// Strip off substr up to carriage return
aText.Mid(substr, oldPos, ((pos - oldPos) - 1));
aRenderingContext.DrawString(substr, x, y);
y += textHeight;
// Advance to the next carriage return
pos++;
oldPos = pos;
pos = aText.Find('\n', pos);
}
aRenderingContext.PopState(clipEmpty);
// Scrollbars
nsIAtom * sbAtom = NS_NewAtom(":scrollbar-look");
nsIStyleContext* scrollbarStyle;
aPresContext.ResolvePseudoStyleContextFor(mContent, sbAtom, aStyleContext, PR_FALSE, &scrollbarStyle);
NS_RELEASE(sbAtom);
sbAtom = NS_NewAtom(":scrollbar-arrow-look");
nsIStyleContext* arrowStyle;
aPresContext.ResolvePseudoStyleContextFor(mContent, sbAtom, aStyleContext, PR_FALSE, &arrowStyle);
NS_RELEASE(sbAtom);
nsRect srect(aRect.width-scrollbarScaledWidth-(2*onePixel), 2*onePixel, scrollbarScaledWidth, aRect.height-(onePixel*4)-scrollbarScaledWidth);
nsFormControlHelper::PaintScrollbar(aRenderingContext,aPresContext, aDirtyRect, srect, PR_FALSE, onePixel,
scrollbarStyle, arrowStyle, this, aRect);
// Horizontal
srect.SetRect(2*onePixel, aRect.height-scrollbarScaledHeight-(2*onePixel), aRect.width-(onePixel*4)-scrollbarScaledHeight, scrollbarScaledHeight);
nsFormControlHelper::PaintScrollbar(aRenderingContext,aPresContext, aDirtyRect, srect, PR_TRUE, onePixel,
scrollbarStyle, arrowStyle, this, aRect);
// 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(aRect.width-scrollbarScaledWidth-(2*onePixel), aRect.height-scrollbarScaledHeight-(onePixel*2), scrollbarScaledWidth, scrollbarScaledHeight);
nsCSSRendering::PaintBackground(aPresContext, aRenderingContext, this,
aDirtyRect, srect, *sbColor, *spacing, 0, 0);
}
NS_RELEASE(context);
PRBool status;
aRenderingContext.PopState(status);
}
NS_METHOD
nsTextControlFrame::Paint(nsIPresContext& aPresContext,
nsIRenderingContext& aRenderingContext,
const nsRect& aDirtyRect,
nsFramePaintLayer aWhichLayer)
{
PaintTextControlBackground(aPresContext, aRenderingContext, aDirtyRect, aWhichLayer);
if (NS_FRAME_PAINT_LAYER_FOREGROUND == aWhichLayer) {
nsString text;
GetText(&text, PR_FALSE);
nsRect rect(0, 0, mRect.width, mRect.height);
PaintTextControl(aPresContext, aRenderingContext, aDirtyRect, text, mStyleContext, rect);
}
return NS_OK;
}
void nsTextControlFrame::GetTextControlFrameState(nsString& aValue)
{
if (nsnull != mWidget) {
nsITextWidget* text = nsnull;
nsITextAreaWidget* textArea = nsnull;
PRUint32 size = 0;
if (NS_OK == mWidget->QueryInterface(kITextWidgetIID,(void**)&text)) {
text->GetText(aValue,0,size);
NS_RELEASE(text);
}
else if (NS_OK == mWidget->QueryInterface(kITextAreaWidgetIID,
(void**)&textArea)) {
textArea->GetText(aValue,0, size);
NS_RELEASE(textArea);
}
}
else {
//XXX: this should return the a local field for GFX-rendered widgets aValue = "";
}
}
void nsTextControlFrame::SetTextControlFrameState(const nsString& aValue)
{
if (nsnull != mWidget) {
nsITextWidget* text = nsnull;
nsITextAreaWidget* textArea = nsnull;
PRUint32 size = 0;
if (NS_SUCCEEDED(mWidget->QueryInterface(kITextWidgetIID,(void**)&text))) {
text->SetText(aValue,size);
NS_RELEASE(text);
} else if (NS_OK == mWidget->QueryInterface(kITextAreaWidgetIID,
(void**)&textArea)) {
textArea->SetText(aValue,size);
NS_RELEASE(textArea);
}
}
}
NS_IMETHODIMP nsTextControlFrame::SetProperty(nsIAtom* aName, const nsString& aValue)
{
nsresult rv = NS_OK;
if (nsHTMLAtoms::value == aName) {
SetTextControlFrameState(aValue);
} else if (nsHTMLAtoms::select == aName) {
if (nsnull != mWidget) {
nsITextWidget *textWidget;
rv = mWidget->QueryInterface(kITextWidgetIID, (void**)&textWidget);
if (NS_SUCCEEDED(rv)) {
textWidget->SelectAll();
NS_RELEASE(textWidget);
}
nsITextAreaWidget *textAreaWidget;
rv = mWidget->QueryInterface(kITextAreaWidgetIID, (void**)&textAreaWidget);
if (NS_SUCCEEDED(rv)) {
textAreaWidget->SelectAll();
NS_RELEASE(textAreaWidget);
}
}
}
else {
return nsFormControlFrame::SetProperty(aName, aValue);
}
return rv;
}
NS_IMETHODIMP nsTextControlFrame::GetProperty(nsIAtom* aName, nsString& aValue)
{
// Return the value of the property from the widget it is not null.
// If widget is null, assume the widget is GFX-rendered and return a member variable instead.
if (nsHTMLAtoms::value == aName) {
GetTextControlFrameState(aValue);
}
else {
return nsFormControlFrame::GetProperty(aName, aValue);
}
return NS_OK;
}

View File

@ -24,33 +24,15 @@ class nsIContent;
class nsIFrame;
class nsIPresContext;
class nsTextControlFrame : public nsFormControlFrame {
class nsTextControlFrame : public nsFormControlFrame
{
/* ---------- methods implemented by base class ---------- */
public:
// nsIFormControlFrame
NS_IMETHOD SetProperty(nsIAtom* aName, const nsString& aValue);
NS_IMETHOD GetProperty(nsIAtom* aName, nsString& aValue);
virtual nsWidgetInitData* GetWidgetInitData(nsIPresContext& aPresContext);
NS_IMETHOD AttributeChanged(nsIPresContext* aPresContext,
nsIContent* aChild,
nsIAtom* aAttribute,
PRInt32 aHint);
NS_IMETHOD GetFrameName(nsString& aResult) const;
virtual void PostCreateWidget(nsIPresContext* aPresContext,
nscoord& aWidth,
nscoord& aHeight);
virtual const nsIID& GetCID();
virtual const nsIID& GetIID();
NS_IMETHOD GetText(nsString* aValue, PRBool aInitialValue);
virtual void EnterPressed(nsIPresContext& aPresContext) ;
NS_IMETHOD GetFrameName(nsString& aResult) const;
virtual nscoord GetVerticalBorderWidth(float aPixToTwip) const;
virtual nscoord GetHorizontalBorderWidth(float aPixToTwip) const;
virtual nscoord GetVerticalInsidePadding(float aPixToTwip,
@ -60,40 +42,65 @@ public:
nscoord aInnerWidth,
nscoord aCharWidth) const;
virtual PRInt32 GetMaxNumValues();
virtual PRBool GetNamesValues(PRInt32 aMaxNumValues, PRInt32& aNumValues,
nsString* aValues, nsString* aNames);
virtual void Reset();
NS_IMETHOD GetCursor(nsIPresContext& aPresContext, nsPoint& aPoint, PRInt32& aCursor);
NS_IMETHOD Paint(nsIPresContext& aPresContext,
nsIRenderingContext& aRenderingContext,
const nsRect& aDirtyRect,
nsFramePaintLayer aWhichLayer);
virtual void PaintTextControlBackground(nsIPresContext& aPresContext,
nsIRenderingContext& aRenderingContext,
const nsRect& aDirtyRect,
nsFramePaintLayer aWhichLayer);
virtual void PaintTextControl(nsIPresContext& aPresContext,
nsIRenderingContext& aRenderingContext,
const nsRect& aDirtyRect, nsString& aText,
nsIStyleContext* aStyleContext,
nsRect& aRect);
// Utility methods to get and set current widget state
void GetTextControlFrameState(nsString& aValue);
void SetTextControlFrameState(const nsString& aValue);
protected:
virtual void GetDesiredSize(nsIPresContext* aPresContext,
const nsHTMLReflowState& aReflowState,
nsHTMLReflowMetrics& aDesiredLayoutSize,
nsSize& aDesiredWidgetSize);
/* ---------- abstract methods derived class must implement ---------- */
public:
// nsIFormControlFrame
NS_IMETHOD SetProperty(nsIAtom* aName, const nsString& aValue)=0;
NS_IMETHOD GetProperty(nsIAtom* aName, nsString& aValue)=0;
virtual nsWidgetInitData* GetWidgetInitData(nsIPresContext& aPresContext)=0;
NS_IMETHOD AttributeChanged(nsIPresContext* aPresContext,
nsIContent* aChild,
nsIAtom* aAttribute,
PRInt32 aHint)=0;
virtual void PostCreateWidget(nsIPresContext* aPresContext,
nscoord& aWidth,
nscoord& aHeight)=0;
NS_IMETHOD GetText(nsString* aValue, PRBool aInitialValue)=0;
virtual void EnterPressed(nsIPresContext& aPresContext)=0;
virtual PRBool GetNamesValues(PRInt32 aMaxNumValues, PRInt32& aNumValues,
nsString* aValues, nsString* aNames)=0;
virtual void Reset()=0;
NS_IMETHOD Paint(nsIPresContext& aPresContext,
nsIRenderingContext& aRenderingContext,
const nsRect& aDirtyRect,
nsFramePaintLayer aWhichLayer)=0;
virtual void PaintTextControlBackground(nsIPresContext& aPresContext,
nsIRenderingContext& aRenderingContext,
const nsRect& aDirtyRect,
nsFramePaintLayer aWhichLayer)=0;
virtual void PaintTextControl(nsIPresContext& aPresContext,
nsIRenderingContext& aRenderingContext,
const nsRect& aDirtyRect, nsString& aText,
nsIStyleContext* aStyleContext,
nsRect& aRect)=0;
// Utility methods to get and set current widget state
virtual void GetTextControlFrameState(nsString& aValue)=0;
virtual void SetTextControlFrameState(const nsString& aValue)=0;
virtual nsresult RequiresWidget(PRBool &aRequiresWidget)=0;
};
#endif