Rewrote nsButtonControlFrame. It is now based on nsHTMLButtonControlFrame.

Added style rules to set submit, reset, and browse buttons default labels.
This commit is contained in:
kmcclusk%netscape.com 1999-08-10 19:13:57 +00:00
Родитель 2fb04397c8
Коммит 4951b16db4
13 изменённых файлов: 554 добавлений и 398 удалений

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

@ -40,6 +40,8 @@ CSS_ATOM(afterPseudo, ":after")
CSS_ATOM(beforePseudo, ":before") CSS_ATOM(beforePseudo, ":before")
CSS_ATOM(buttonLabelPseudo, ":-moz-buttonlabel")
CSS_ATOM(checkedPseudo, ":checked") CSS_ATOM(checkedPseudo, ":checked")
CSS_ATOM(disabledPseudo, ":disabled") CSS_ATOM(disabledPseudo, ":disabled")

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

@ -40,6 +40,8 @@ CSS_ATOM(afterPseudo, ":after")
CSS_ATOM(beforePseudo, ":before") CSS_ATOM(beforePseudo, ":before")
CSS_ATOM(buttonLabelPseudo, ":-moz-buttonlabel")
CSS_ATOM(checkedPseudo, ":checked") CSS_ATOM(checkedPseudo, ":checked")
CSS_ATOM(disabledPseudo, ":disabled") CSS_ATOM(disabledPseudo, ":disabled")

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

@ -2458,6 +2458,40 @@ nsCSSFrameConstructor::ConstructCheckboxControlFrame(nsIPresContext* aPres
return rv; return rv;
} }
nsresult
nsCSSFrameConstructor::ConstructButtonLabelFrame(nsIPresContext *aPresContext,
nsIContent *aContent,
nsIFrame *&aFrame,
nsFrameConstructorState& aState,
nsFrameItems& aFrameItems)
{
// Construct a button label using generated content specified
// through style. A style rule of following form must be
// present in ua.css or other style sheet
// input[type=button][value]:-moz-buttonlabel {
// content:attr(value);
// }
// The default for the label is specified with a rule similar to
// the following:
// input[type=reset]:-moz-buttonlabel {
// content:"Reset";
// }
nsresult rv = NS_OK;
nsIStyleContext* styleContext = nsnull;
nsIFrame* generatedFrame = nsnull;
// Probe for generated content before
aFrame->GetStyleContext(&styleContext);
if (CreateGeneratedContentFrame(aPresContext, aState, aFrame, aContent,
styleContext, nsCSSAtoms::buttonLabelPseudo,
PR_FALSE, PR_FALSE, &generatedFrame)) {
// Add the generated frame to the child list
aFrameItems.AddChild(generatedFrame);
}
return rv;
}
nsresult nsresult
nsCSSFrameConstructor::ConstructButtonControlFrame(nsIPresContext* aPresContext, nsCSSFrameConstructor::ConstructButtonControlFrame(nsIPresContext* aPresContext,
nsIFrame*& aNewFrame) nsIFrame*& aNewFrame)
@ -2814,6 +2848,10 @@ nsCSSFrameConstructor::ConstructFrameByTag(nsIPresContext* aPresContext
PR_TRUE, childItems); PR_TRUE, childItems);
} }
if (nsHTMLAtoms::input == aTag) {
// Construct button label frame using generated content
ConstructButtonLabelFrame(aPresContext, aContent, newFrame, aState, childItems);
}
// if there are any anonymous children create frames for them // if there are any anonymous children create frames for them
CreateAnonymousFrames(aPresContext, aTag, aState, aContent, newFrame, CreateAnonymousFrames(aPresContext, aTag, aState, aContent, newFrame,

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

@ -417,6 +417,12 @@ protected:
nsresult ConstructCheckboxControlFrame(nsIPresContext* aPresContext, nsresult ConstructCheckboxControlFrame(nsIPresContext* aPresContext,
nsIFrame*& aNewFrame); nsIFrame*& aNewFrame);
nsresult ConstructButtonLabelFrame(nsIPresContext *aPresContext,
nsIContent *aContent,
nsIFrame *&aFrame,
nsFrameConstructorState& aState,
nsFrameItems& aFrameItems);
nsresult ConstructButtonControlFrame(nsIPresContext* aPresContext, nsresult ConstructButtonControlFrame(nsIPresContext* aPresContext,
nsIFrame*& aNewFrame); nsIFrame*& aNewFrame);

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

@ -17,16 +17,71 @@
*/ */
#include "nsGfxButtonControlFrame.h" #include "nsGfxButtonControlFrame.h"
#include "nsHTMLAtoms.h"
#include "nsFormFrame.h"
#include "nsIFormControl.h"
#include "nsIContent.h"
#include "nsIButton.h" #include "nsIButton.h"
#include "nsINameSpaceManager.h" #include "nsWidgetsCID.h"
static NS_DEFINE_IID(kIFormControlIID, NS_IFORMCONTROL_IID);
static NS_DEFINE_IID(kIButtonIID, NS_IBUTTON_IID); static NS_DEFINE_IID(kIButtonIID, NS_IBUTTON_IID);
const nscoord kSuggestedNotSet = -1;
nsGfxButtonControlFrame::nsGfxButtonControlFrame()
{
mRenderer.SetNameSpace(kNameSpaceID_None);
mSuggestedWidth = kSuggestedNotSet;
mSuggestedHeight = kSuggestedNotSet;
}
PRBool
nsGfxButtonControlFrame::IsSuccessful(nsIFormControlFrame* aSubmitter)
{
PRInt32 type;
GetType(&type);
if ((NS_FORM_INPUT_HIDDEN == type) || (this == aSubmitter)) {
return nsHTMLButtonControlFrame::IsSuccessful(aSubmitter);
} else {
return PR_FALSE;
}
}
PRInt32
nsGfxButtonControlFrame::GetMaxNumValues()
{
PRInt32 type;
GetType(&type);
if ((NS_FORM_INPUT_SUBMIT == type) || (NS_FORM_INPUT_HIDDEN == type)) {
return 1;
} else {
return 0;
}
}
PRBool
nsGfxButtonControlFrame::GetNamesValues(PRInt32 aMaxNumValues, PRInt32& aNumValues,
nsString* aValues, nsString* aNames)
{
nsAutoString name;
nsresult result = GetName(&name);
if ((aMaxNumValues <= 0) || (NS_CONTENT_ATTR_HAS_VALUE != result)) {
return PR_FALSE;
}
PRInt32 type;
GetType(&type);
if (NS_FORM_INPUT_RESET == type) {
aNumValues = 0;
return PR_FALSE;
} else {
nsAutoString value;
GetValue(&value);
aValues[0] = value;
aNames[0] = name;
aNumValues = 1;
return PR_TRUE;
}
}
nsresult nsresult
NS_NewGfxButtonControlFrame(nsIFrame** aNewFrame) NS_NewGfxButtonControlFrame(nsIFrame** aNewFrame)
{ {
@ -41,193 +96,128 @@ NS_NewGfxButtonControlFrame(nsIFrame** aNewFrame)
*aNewFrame = it; *aNewFrame = it;
return NS_OK; return NS_OK;
} }
void
nsGfxButtonControlFrame::nsGfxButtonControlFrame() nsGfxButtonControlFrame::MouseClicked(nsIPresContext* aPresContext)
{ {
mRenderer.SetNameSpace(kNameSpaceID_None); PRInt32 type;
} GetType(&type);
NS_IMETHODIMP if ((nsnull != mFormFrame) && !nsFormFrame::GetDisabled(this)) {
nsGfxButtonControlFrame::Init(nsIPresContext& aPresContext, nsEventStatus status = nsEventStatus_eIgnore;
nsIContent* aContent, nsEvent event;
nsIFrame* aParent, event.eventStructType = NS_EVENT;
nsIStyleContext* aContext, nsIContent *formContent = nsnull;
nsIFrame* aPrevInFlow) mFormFrame->GetContent(&formContent);
{
nsresult rv = Inherited::Init(aPresContext, aContent, aParent, aContext, aPrevInFlow);
mRenderer.SetFrame(this,aPresContext);
return rv;
}
switch(type) {
// case NS_FORM_INPUT_RESET:
// ReResolveStyleContext event.message = NS_FORM_RESET;
// if (nsnull != formContent) {
// When the style context changes, make sure that all of our styles are still up to date. formContent->HandleDOMEvent(*aPresContext, &event, nsnull, NS_EVENT_FLAG_INIT, status);
// }
NS_IMETHODIMP if (nsEventStatus_eConsumeNoDefault != status) {
nsGfxButtonControlFrame::ReResolveStyleContext ( nsIPresContext* aPresContext, nsIStyleContext* aParentContext, mFormFrame->OnReset();
PRInt32 aParentChange, }
nsStyleChangeList* aChangeList, PRInt32* aLocalChange) break;
{ case NS_FORM_INPUT_SUBMIT:
// this re-resolves |mStyleContext|, so it may change event.message = NS_FORM_SUBMIT;
nsresult rv = Inherited::ReResolveStyleContext(aPresContext, aParentContext, if (nsnull != formContent) {
aParentChange, aChangeList, aLocalChange); formContent->HandleDOMEvent(*aPresContext, &event, nsnull, NS_EVENT_FLAG_INIT, status);
if (NS_FAILED(rv)) { }
return rv; if (nsEventStatus_eConsumeNoDefault != status) {
} mFormFrame->OnSubmit(aPresContext, this);
}
if (NS_COMFALSE != rv) { // frame style changed
if (aLocalChange) {
aParentChange = *aLocalChange; // tell children about or change
} }
} NS_IF_RELEASE(formContent);
mRenderer.ReResolveStyles(*aPresContext, aParentChange, aChangeList, aLocalChange); }
}
return rv;
} // ReResolveStyleContext
const nsIID&
nsGfxButtonControlFrame::GetIID()
NS_METHOD
nsGfxButtonControlFrame::Paint(nsIPresContext& aPresContext,
nsIRenderingContext& aRenderingContext,
const nsRect& aDirtyRect,
nsFramePaintLayer aWhichLayer)
{ {
const nsStyleDisplay* disp = (const nsStyleDisplay*) static NS_DEFINE_IID(kButtonIID, NS_IBUTTON_IID);
mStyleContext->GetStyleData(eStyleStruct_Display); return kButtonIID;
if (!disp->mVisible) }
return NS_OK;
nsRect rect(0, 0, mRect.width, mRect.height);
mRenderer.PaintButton(aPresContext, aRenderingContext, aDirtyRect, aWhichLayer, rect);
if (NS_FRAME_PAINT_LAYER_FOREGROUND == aWhichLayer) {
nsString label;
nsresult result = GetValue(&label);
if (NS_CONTENT_ATTR_HAS_VALUE != result) {
GetDefaultLabel(label);
}
nsRect content; const nsIID&
mRenderer.GetButtonContentRect(rect,content); nsGfxButtonControlFrame::GetCID()
{
// paint the title static NS_DEFINE_IID(kButtonCID, NS_BUTTON_CID);
const nsStyleFont* fontStyle = (const nsStyleFont*)mStyleContext->GetStyleData(eStyleStruct_Font); return kButtonCID;
const nsStyleColor* colorStyle = (const nsStyleColor*)mStyleContext->GetStyleData(eStyleStruct_Color);
aRenderingContext.SetFont(fontStyle->mFont);
PRBool clipState;
aRenderingContext.PushState();
aRenderingContext.SetClipRect(rect, nsClipCombine_kIntersect, clipState);
// if disabled paint
if (PR_TRUE == mRenderer.isDisabled())
{
float p2t;
aPresContext.GetScaledPixelsToTwips(&p2t);
nscoord pixel = NSIntPixelsToTwips(1, p2t);
aRenderingContext.SetColor(NS_RGB(255,255,255));
aRenderingContext.DrawString(label, content.x + pixel, content.y+ pixel);
}
aRenderingContext.SetColor(colorStyle->mColor);
aRenderingContext.DrawString(label, content.x, content.y);
aRenderingContext.PopState(clipState);
}
return NS_OK;
} }
NS_IMETHODIMP NS_IMETHODIMP
nsGfxButtonControlFrame::AttributeChanged(nsIPresContext* aPresContext, nsGfxButtonControlFrame::GetFrameName(nsString& aResult) const
nsIContent* aChild,
nsIAtom* aAttribute,
PRInt32 aHint)
{ {
if (nsHTMLAtoms::value == aAttribute) { return MakeFrameName("ButtonControl", aResult);
// redraw button with the changed value
Invalidate(mRect, PR_FALSE);
}
return NS_OK;
} }
NS_METHOD
nsGfxButtonControlFrame::Reflow(nsIPresContext& aPresContext,
NS_IMETHODIMP
nsGfxButtonControlFrame::Reflow(nsIPresContext& aPresContext,
nsHTMLReflowMetrics& aDesiredSize, nsHTMLReflowMetrics& aDesiredSize,
const nsHTMLReflowState& aReflowState, const nsHTMLReflowState& aReflowState,
nsReflowStatus& aStatus) nsReflowStatus& aStatus)
{ {
// add ourself as an nsIFormControlFrame
if (!mFormFrame && (eReflowReason_Initial == aReflowState.reason)) { if (!mFormFrame && (eReflowReason_Initial == aReflowState.reason)) {
nsFormFrame::AddFormControlFrame(aPresContext, *this); nsFormFrame::AddFormControlFrame(aPresContext, *this);
} }
if ((NS_FORMSIZE_NOTSET != mSuggestedWidth) && ( if ((kSuggestedNotSet != mSuggestedWidth) ||
NS_FORMSIZE_NOTSET != mSuggestedHeight)) (kSuggestedNotSet != mSuggestedHeight))
{ {
aDesiredSize.width = mSuggestedWidth; nsHTMLReflowState suggestedReflowState(aReflowState);
aDesiredSize.height = mSuggestedHeight;
aDesiredSize.ascent = mSuggestedHeight; // Honor the suggested width and/or height.
aDesiredSize.descent = 0; if (kSuggestedNotSet != mSuggestedWidth) {
if (aDesiredSize.maxElementSize) { suggestedReflowState.mComputedWidth = mSuggestedWidth;
aDesiredSize.maxElementSize->width = mSuggestedWidth; }
aDesiredSize.maxElementSize->height = mSuggestedWidth;
}
if (nsnull != aDesiredSize.maxElementSize) { if (kSuggestedNotSet != mSuggestedHeight) {
aDesiredSize.maxElementSize->width = aDesiredSize.width; suggestedReflowState.mComputedHeight = mSuggestedHeight;
aDesiredSize.maxElementSize->height = aDesiredSize.height; }
}
aStatus = NS_FRAME_COMPLETE; return nsHTMLButtonControlFrame::Reflow(aPresContext, aDesiredSize, suggestedReflowState, aStatus);
return NS_OK;
} } else {
// Normal reflow.
nsSize ignore; return nsHTMLButtonControlFrame::Reflow(aPresContext, aDesiredSize, aReflowState, aStatus);
GetDesiredSize(&aPresContext, aReflowState, aDesiredSize, ignore); }
// if our size is intrinsic. Then we need to return the size we really need
// so include our inner borders we use for focus.
nsMargin added = mRenderer.GetAddedButtonBorderAndPadding();
if (aReflowState.mComputedWidth == NS_INTRINSICSIZE)
aDesiredSize.width += added.left + added.right;
if (aReflowState.mComputedHeight == NS_INTRINSICSIZE)
aDesiredSize.height += added.top + added.bottom;
nsMargin bp(0,0,0,0);
AddBordersAndPadding(&aPresContext, aReflowState, aDesiredSize, bp);
if (nsnull != aDesiredSize.maxElementSize) {
aDesiredSize.AddBorderPaddingToMaxElementSize(bp);
aDesiredSize.maxElementSize->width += added.left + added.right;
aDesiredSize.maxElementSize->height += added.top + added.bottom;
}
aStatus = NS_FRAME_COMPLETE;
return NS_OK;
} }
NS_IMETHODIMP
nsGfxButtonControlFrame::SetSuggestedSize(nscoord aWidth, nscoord aHeight)
{
mSuggestedWidth = aWidth;
mSuggestedHeight = aHeight;
return NS_OK;
}
NS_IMETHODIMP NS_IMETHODIMP
nsGfxButtonControlFrame::HandleEvent(nsIPresContext& aPresContext, nsGfxButtonControlFrame::HandleEvent(nsIPresContext& aPresContext,
nsGUIEvent* aEvent, nsGUIEvent* aEvent,
nsEventStatus& aEventStatus) nsEventStatus& aEventStatus)
{ {
// Override the HandleEvent to prevent the nsFrame::HandleEvent
// from being called. The nsFrame::HandleEvent causes the button label
// to be selected (Drawn with an XOR rectangle over the label)
// if disabled do nothing // if disabled do nothing
if (mRenderer.isDisabled()) { if (mRenderer.isDisabled()) {
return NS_OK; return NS_OK;
} }
return Inherited::HandleEvent(aPresContext, aEvent, aEventStatus); // lets see if the button was clicked
switch (aEvent->message) {
case NS_MOUSE_LEFT_CLICK:
MouseClicked(&aPresContext);
break;
}
return NS_OK;
} }

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

@ -19,52 +19,46 @@
#ifndef nsGfxButtonControlFrame_h___ #ifndef nsGfxButtonControlFrame_h___
#define nsGfxButtonControlFrame_h___ #define nsGfxButtonControlFrame_h___
#include "nsNativeFormControlFrame.h" #include "nsFormControlFrame.h"
#include "nsButtonControlFrame.h" #include "nsHTMLButtonControlFrame.h"
#include "nsButtonFrameRenderer.h"
class nsGfxButtonControlFrame : public nsButtonControlFrame { // Class which implements the input[type=button, reset, submit] and
private: // browse button for input[type=file].
typedef nsButtonControlFrame Inherited; // The label for button is specified through generated content
// in the ua.css file.
class nsGfxButtonControlFrame : public nsHTMLButtonControlFrame {
public: public:
nsGfxButtonControlFrame(); nsGfxButtonControlFrame();
NS_IMETHOD Init(nsIPresContext& aPresContext, //nsIFrame
nsIContent* aContent, NS_IMETHOD Reflow(nsIPresContext& aCX,
nsIFrame* aParent,
nsIStyleContext* aContext,
nsIFrame* asPrevInFlow);
NS_IMETHOD ReResolveStyleContext ( nsIPresContext* aPresContext,
nsIStyleContext* aParentContext,
PRInt32 aParentChange,
nsStyleChangeList* aChangeList,
PRInt32* aLocalChange) ;
NS_IMETHOD Paint(nsIPresContext& aPresContext,
nsIRenderingContext& aRenderingContext,
const nsRect& aDirtyRect,
nsFramePaintLayer aWhichLayer);
NS_IMETHOD Reflow(nsIPresContext& aPresContext,
nsHTMLReflowMetrics& aDesiredSize, nsHTMLReflowMetrics& aDesiredSize,
const nsHTMLReflowState& aReflowState, const nsHTMLReflowState& aReflowState,
nsReflowStatus& aStatus); nsReflowStatus& aStatus);
virtual const nsIID& GetCID();
virtual const nsIID& GetIID();
NS_IMETHOD AttributeChanged(nsIPresContext* aPresContext, NS_IMETHOD HandleEvent(nsIPresContext& aPresContext,
nsIContent* aChild,
nsIAtom* aAttribute,
PRInt32 aHint);
NS_IMETHOD HandleEvent(nsIPresContext& aPresContext,
nsGUIEvent* aEvent, nsGUIEvent* aEvent,
nsEventStatus& aEventStatus); nsEventStatus& aEventStatus);
protected:
//GFX-rendered state variables // nsFormControlFrame
nsButtonFrameRenderer mRenderer; NS_IMETHOD SetSuggestedSize(nscoord aWidth, nscoord aHeight);
NS_IMETHOD GetFrameName(nsString& aResult) const;
PRBool IsSuccessful(nsIFormControlFrame* aSubmitter);
virtual PRInt32 GetMaxNumValues();
virtual PRBool GetNamesValues(PRInt32 aMaxNumValues, PRInt32& aNumValues,
nsString* aValues, nsString* aNames);
virtual void MouseClicked(nsIPresContext* aPresContext);
private:
NS_IMETHOD_(nsrefcnt) AddRef() { return NS_OK; }
NS_IMETHOD_(nsrefcnt) Release() { return NS_OK; }
nscoord mSuggestedWidth;
nscoord mSuggestedHeight;
}; };

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

@ -421,6 +421,49 @@ form {
display: block; display: block;
margin: 1em 0; margin: 1em 0;
} }
/* button */
input[type=button]:-moz-buttonlabel {
content:" ";
font-family: sans-serif;
font-size: small;
background-color:inherit;
}
input[type=button][value]:-moz-buttonlabel {
content:attr(value);
font-family: sans-serif;
font-size: small;
background-color:inherit;
}
/* submit */
input[type=submit]:-moz-buttonlabel {
content:"submit";
font-family: sans-serif;
font-size: small;
}
input[type=submit][value]:-moz-buttonlabel {
content:attr(value);
font-family: sans-serif;
font-size: small;
}
/* reset */
input[type=reset]:-moz-buttonlabel {
content:"reset";
font-family: sans-serif;
font-size: small;
}
input[type=reset][value]:-moz-buttonlabel {
content:attr(value);
font-family: sans-serif;
font-size: small;
}
input { input {
vertical-align: bottom; vertical-align: bottom;
border: 2px inset rgb(204, 204, 204); border: 2px inset rgb(204, 204, 204);
@ -443,6 +486,12 @@ input[type=file] input[type=button] {
height:inherit; height:inherit;
} }
input[type=file] input[type=button]:-moz-buttonlabel {
content:"Browse...";
font-family: sans-serif;
}
input[type=radio] { input[type=radio] {
/* these margins are for NavQuirks, we need a Standard ua.css */ /* these margins are for NavQuirks, we need a Standard ua.css */
margin-left: 3px; margin-left: 3px;
@ -606,13 +655,11 @@ input[type="button"] {
border: 2px outset rgb(156, 154, 156); border: 2px outset rgb(156, 154, 156);
background-color: rgb(206, 207, 206); background-color: rgb(206, 207, 206);
color:black; color:black;
padding: 1px; padding: 1px;
} }
input[type="button"]:active { input[type="button"]:active {
border-style: inset; border-style: inset;
padding-left: 2px; padding-left: 2px;
padding-right: 0px; padding-right: 0px;
padding-top: 2px; padding-top: 2px;
@ -648,7 +695,6 @@ input[type="button"]:focus:-moz-focus-inner {
padding-right : 1px; padding-right : 1px;
padding-top : 0px; padding-top : 0px;
padding-bottom: 0px; padding-bottom: 0px;
margin: 0px; margin: 0px;
border : 1px dotted black; border : 1px dotted black;
} }
@ -873,6 +919,7 @@ optgroup:before {
content:attr(label); content:attr(label);
} }
textarea { textarea {
vertical-align: bottom; vertical-align: bottom;
border: 2px inset #c0c0c0; border: 2px inset #c0c0c0;

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

@ -17,16 +17,71 @@
*/ */
#include "nsGfxButtonControlFrame.h" #include "nsGfxButtonControlFrame.h"
#include "nsHTMLAtoms.h"
#include "nsFormFrame.h"
#include "nsIFormControl.h"
#include "nsIContent.h"
#include "nsIButton.h" #include "nsIButton.h"
#include "nsINameSpaceManager.h" #include "nsWidgetsCID.h"
static NS_DEFINE_IID(kIFormControlIID, NS_IFORMCONTROL_IID);
static NS_DEFINE_IID(kIButtonIID, NS_IBUTTON_IID); static NS_DEFINE_IID(kIButtonIID, NS_IBUTTON_IID);
const nscoord kSuggestedNotSet = -1;
nsGfxButtonControlFrame::nsGfxButtonControlFrame()
{
mRenderer.SetNameSpace(kNameSpaceID_None);
mSuggestedWidth = kSuggestedNotSet;
mSuggestedHeight = kSuggestedNotSet;
}
PRBool
nsGfxButtonControlFrame::IsSuccessful(nsIFormControlFrame* aSubmitter)
{
PRInt32 type;
GetType(&type);
if ((NS_FORM_INPUT_HIDDEN == type) || (this == aSubmitter)) {
return nsHTMLButtonControlFrame::IsSuccessful(aSubmitter);
} else {
return PR_FALSE;
}
}
PRInt32
nsGfxButtonControlFrame::GetMaxNumValues()
{
PRInt32 type;
GetType(&type);
if ((NS_FORM_INPUT_SUBMIT == type) || (NS_FORM_INPUT_HIDDEN == type)) {
return 1;
} else {
return 0;
}
}
PRBool
nsGfxButtonControlFrame::GetNamesValues(PRInt32 aMaxNumValues, PRInt32& aNumValues,
nsString* aValues, nsString* aNames)
{
nsAutoString name;
nsresult result = GetName(&name);
if ((aMaxNumValues <= 0) || (NS_CONTENT_ATTR_HAS_VALUE != result)) {
return PR_FALSE;
}
PRInt32 type;
GetType(&type);
if (NS_FORM_INPUT_RESET == type) {
aNumValues = 0;
return PR_FALSE;
} else {
nsAutoString value;
GetValue(&value);
aValues[0] = value;
aNames[0] = name;
aNumValues = 1;
return PR_TRUE;
}
}
nsresult nsresult
NS_NewGfxButtonControlFrame(nsIFrame** aNewFrame) NS_NewGfxButtonControlFrame(nsIFrame** aNewFrame)
{ {
@ -41,193 +96,128 @@ NS_NewGfxButtonControlFrame(nsIFrame** aNewFrame)
*aNewFrame = it; *aNewFrame = it;
return NS_OK; return NS_OK;
} }
void
nsGfxButtonControlFrame::nsGfxButtonControlFrame() nsGfxButtonControlFrame::MouseClicked(nsIPresContext* aPresContext)
{ {
mRenderer.SetNameSpace(kNameSpaceID_None); PRInt32 type;
} GetType(&type);
NS_IMETHODIMP if ((nsnull != mFormFrame) && !nsFormFrame::GetDisabled(this)) {
nsGfxButtonControlFrame::Init(nsIPresContext& aPresContext, nsEventStatus status = nsEventStatus_eIgnore;
nsIContent* aContent, nsEvent event;
nsIFrame* aParent, event.eventStructType = NS_EVENT;
nsIStyleContext* aContext, nsIContent *formContent = nsnull;
nsIFrame* aPrevInFlow) mFormFrame->GetContent(&formContent);
{
nsresult rv = Inherited::Init(aPresContext, aContent, aParent, aContext, aPrevInFlow);
mRenderer.SetFrame(this,aPresContext);
return rv;
}
switch(type) {
// case NS_FORM_INPUT_RESET:
// ReResolveStyleContext event.message = NS_FORM_RESET;
// if (nsnull != formContent) {
// When the style context changes, make sure that all of our styles are still up to date. formContent->HandleDOMEvent(*aPresContext, &event, nsnull, NS_EVENT_FLAG_INIT, status);
// }
NS_IMETHODIMP if (nsEventStatus_eConsumeNoDefault != status) {
nsGfxButtonControlFrame::ReResolveStyleContext ( nsIPresContext* aPresContext, nsIStyleContext* aParentContext, mFormFrame->OnReset();
PRInt32 aParentChange, }
nsStyleChangeList* aChangeList, PRInt32* aLocalChange) break;
{ case NS_FORM_INPUT_SUBMIT:
// this re-resolves |mStyleContext|, so it may change event.message = NS_FORM_SUBMIT;
nsresult rv = Inherited::ReResolveStyleContext(aPresContext, aParentContext, if (nsnull != formContent) {
aParentChange, aChangeList, aLocalChange); formContent->HandleDOMEvent(*aPresContext, &event, nsnull, NS_EVENT_FLAG_INIT, status);
if (NS_FAILED(rv)) { }
return rv; if (nsEventStatus_eConsumeNoDefault != status) {
} mFormFrame->OnSubmit(aPresContext, this);
}
if (NS_COMFALSE != rv) { // frame style changed
if (aLocalChange) {
aParentChange = *aLocalChange; // tell children about or change
} }
} NS_IF_RELEASE(formContent);
mRenderer.ReResolveStyles(*aPresContext, aParentChange, aChangeList, aLocalChange); }
}
return rv;
} // ReResolveStyleContext
const nsIID&
nsGfxButtonControlFrame::GetIID()
NS_METHOD
nsGfxButtonControlFrame::Paint(nsIPresContext& aPresContext,
nsIRenderingContext& aRenderingContext,
const nsRect& aDirtyRect,
nsFramePaintLayer aWhichLayer)
{ {
const nsStyleDisplay* disp = (const nsStyleDisplay*) static NS_DEFINE_IID(kButtonIID, NS_IBUTTON_IID);
mStyleContext->GetStyleData(eStyleStruct_Display); return kButtonIID;
if (!disp->mVisible) }
return NS_OK;
nsRect rect(0, 0, mRect.width, mRect.height);
mRenderer.PaintButton(aPresContext, aRenderingContext, aDirtyRect, aWhichLayer, rect);
if (NS_FRAME_PAINT_LAYER_FOREGROUND == aWhichLayer) {
nsString label;
nsresult result = GetValue(&label);
if (NS_CONTENT_ATTR_HAS_VALUE != result) {
GetDefaultLabel(label);
}
nsRect content; const nsIID&
mRenderer.GetButtonContentRect(rect,content); nsGfxButtonControlFrame::GetCID()
{
// paint the title static NS_DEFINE_IID(kButtonCID, NS_BUTTON_CID);
const nsStyleFont* fontStyle = (const nsStyleFont*)mStyleContext->GetStyleData(eStyleStruct_Font); return kButtonCID;
const nsStyleColor* colorStyle = (const nsStyleColor*)mStyleContext->GetStyleData(eStyleStruct_Color);
aRenderingContext.SetFont(fontStyle->mFont);
PRBool clipState;
aRenderingContext.PushState();
aRenderingContext.SetClipRect(rect, nsClipCombine_kIntersect, clipState);
// if disabled paint
if (PR_TRUE == mRenderer.isDisabled())
{
float p2t;
aPresContext.GetScaledPixelsToTwips(&p2t);
nscoord pixel = NSIntPixelsToTwips(1, p2t);
aRenderingContext.SetColor(NS_RGB(255,255,255));
aRenderingContext.DrawString(label, content.x + pixel, content.y+ pixel);
}
aRenderingContext.SetColor(colorStyle->mColor);
aRenderingContext.DrawString(label, content.x, content.y);
aRenderingContext.PopState(clipState);
}
return NS_OK;
} }
NS_IMETHODIMP NS_IMETHODIMP
nsGfxButtonControlFrame::AttributeChanged(nsIPresContext* aPresContext, nsGfxButtonControlFrame::GetFrameName(nsString& aResult) const
nsIContent* aChild,
nsIAtom* aAttribute,
PRInt32 aHint)
{ {
if (nsHTMLAtoms::value == aAttribute) { return MakeFrameName("ButtonControl", aResult);
// redraw button with the changed value
Invalidate(mRect, PR_FALSE);
}
return NS_OK;
} }
NS_METHOD
nsGfxButtonControlFrame::Reflow(nsIPresContext& aPresContext,
NS_IMETHODIMP
nsGfxButtonControlFrame::Reflow(nsIPresContext& aPresContext,
nsHTMLReflowMetrics& aDesiredSize, nsHTMLReflowMetrics& aDesiredSize,
const nsHTMLReflowState& aReflowState, const nsHTMLReflowState& aReflowState,
nsReflowStatus& aStatus) nsReflowStatus& aStatus)
{ {
// add ourself as an nsIFormControlFrame
if (!mFormFrame && (eReflowReason_Initial == aReflowState.reason)) { if (!mFormFrame && (eReflowReason_Initial == aReflowState.reason)) {
nsFormFrame::AddFormControlFrame(aPresContext, *this); nsFormFrame::AddFormControlFrame(aPresContext, *this);
} }
if ((NS_FORMSIZE_NOTSET != mSuggestedWidth) && ( if ((kSuggestedNotSet != mSuggestedWidth) ||
NS_FORMSIZE_NOTSET != mSuggestedHeight)) (kSuggestedNotSet != mSuggestedHeight))
{ {
aDesiredSize.width = mSuggestedWidth; nsHTMLReflowState suggestedReflowState(aReflowState);
aDesiredSize.height = mSuggestedHeight;
aDesiredSize.ascent = mSuggestedHeight; // Honor the suggested width and/or height.
aDesiredSize.descent = 0; if (kSuggestedNotSet != mSuggestedWidth) {
if (aDesiredSize.maxElementSize) { suggestedReflowState.mComputedWidth = mSuggestedWidth;
aDesiredSize.maxElementSize->width = mSuggestedWidth; }
aDesiredSize.maxElementSize->height = mSuggestedWidth;
}
if (nsnull != aDesiredSize.maxElementSize) { if (kSuggestedNotSet != mSuggestedHeight) {
aDesiredSize.maxElementSize->width = aDesiredSize.width; suggestedReflowState.mComputedHeight = mSuggestedHeight;
aDesiredSize.maxElementSize->height = aDesiredSize.height; }
}
aStatus = NS_FRAME_COMPLETE; return nsHTMLButtonControlFrame::Reflow(aPresContext, aDesiredSize, suggestedReflowState, aStatus);
return NS_OK;
} } else {
// Normal reflow.
nsSize ignore; return nsHTMLButtonControlFrame::Reflow(aPresContext, aDesiredSize, aReflowState, aStatus);
GetDesiredSize(&aPresContext, aReflowState, aDesiredSize, ignore); }
// if our size is intrinsic. Then we need to return the size we really need
// so include our inner borders we use for focus.
nsMargin added = mRenderer.GetAddedButtonBorderAndPadding();
if (aReflowState.mComputedWidth == NS_INTRINSICSIZE)
aDesiredSize.width += added.left + added.right;
if (aReflowState.mComputedHeight == NS_INTRINSICSIZE)
aDesiredSize.height += added.top + added.bottom;
nsMargin bp(0,0,0,0);
AddBordersAndPadding(&aPresContext, aReflowState, aDesiredSize, bp);
if (nsnull != aDesiredSize.maxElementSize) {
aDesiredSize.AddBorderPaddingToMaxElementSize(bp);
aDesiredSize.maxElementSize->width += added.left + added.right;
aDesiredSize.maxElementSize->height += added.top + added.bottom;
}
aStatus = NS_FRAME_COMPLETE;
return NS_OK;
} }
NS_IMETHODIMP
nsGfxButtonControlFrame::SetSuggestedSize(nscoord aWidth, nscoord aHeight)
{
mSuggestedWidth = aWidth;
mSuggestedHeight = aHeight;
return NS_OK;
}
NS_IMETHODIMP NS_IMETHODIMP
nsGfxButtonControlFrame::HandleEvent(nsIPresContext& aPresContext, nsGfxButtonControlFrame::HandleEvent(nsIPresContext& aPresContext,
nsGUIEvent* aEvent, nsGUIEvent* aEvent,
nsEventStatus& aEventStatus) nsEventStatus& aEventStatus)
{ {
// Override the HandleEvent to prevent the nsFrame::HandleEvent
// from being called. The nsFrame::HandleEvent causes the button label
// to be selected (Drawn with an XOR rectangle over the label)
// if disabled do nothing // if disabled do nothing
if (mRenderer.isDisabled()) { if (mRenderer.isDisabled()) {
return NS_OK; return NS_OK;
} }
return Inherited::HandleEvent(aPresContext, aEvent, aEventStatus); // lets see if the button was clicked
switch (aEvent->message) {
case NS_MOUSE_LEFT_CLICK:
MouseClicked(&aPresContext);
break;
}
return NS_OK;
} }

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

@ -19,52 +19,46 @@
#ifndef nsGfxButtonControlFrame_h___ #ifndef nsGfxButtonControlFrame_h___
#define nsGfxButtonControlFrame_h___ #define nsGfxButtonControlFrame_h___
#include "nsNativeFormControlFrame.h" #include "nsFormControlFrame.h"
#include "nsButtonControlFrame.h" #include "nsHTMLButtonControlFrame.h"
#include "nsButtonFrameRenderer.h"
class nsGfxButtonControlFrame : public nsButtonControlFrame { // Class which implements the input[type=button, reset, submit] and
private: // browse button for input[type=file].
typedef nsButtonControlFrame Inherited; // The label for button is specified through generated content
// in the ua.css file.
class nsGfxButtonControlFrame : public nsHTMLButtonControlFrame {
public: public:
nsGfxButtonControlFrame(); nsGfxButtonControlFrame();
NS_IMETHOD Init(nsIPresContext& aPresContext, //nsIFrame
nsIContent* aContent, NS_IMETHOD Reflow(nsIPresContext& aCX,
nsIFrame* aParent,
nsIStyleContext* aContext,
nsIFrame* asPrevInFlow);
NS_IMETHOD ReResolveStyleContext ( nsIPresContext* aPresContext,
nsIStyleContext* aParentContext,
PRInt32 aParentChange,
nsStyleChangeList* aChangeList,
PRInt32* aLocalChange) ;
NS_IMETHOD Paint(nsIPresContext& aPresContext,
nsIRenderingContext& aRenderingContext,
const nsRect& aDirtyRect,
nsFramePaintLayer aWhichLayer);
NS_IMETHOD Reflow(nsIPresContext& aPresContext,
nsHTMLReflowMetrics& aDesiredSize, nsHTMLReflowMetrics& aDesiredSize,
const nsHTMLReflowState& aReflowState, const nsHTMLReflowState& aReflowState,
nsReflowStatus& aStatus); nsReflowStatus& aStatus);
virtual const nsIID& GetCID();
virtual const nsIID& GetIID();
NS_IMETHOD AttributeChanged(nsIPresContext* aPresContext, NS_IMETHOD HandleEvent(nsIPresContext& aPresContext,
nsIContent* aChild,
nsIAtom* aAttribute,
PRInt32 aHint);
NS_IMETHOD HandleEvent(nsIPresContext& aPresContext,
nsGUIEvent* aEvent, nsGUIEvent* aEvent,
nsEventStatus& aEventStatus); nsEventStatus& aEventStatus);
protected:
//GFX-rendered state variables // nsFormControlFrame
nsButtonFrameRenderer mRenderer; NS_IMETHOD SetSuggestedSize(nscoord aWidth, nscoord aHeight);
NS_IMETHOD GetFrameName(nsString& aResult) const;
PRBool IsSuccessful(nsIFormControlFrame* aSubmitter);
virtual PRInt32 GetMaxNumValues();
virtual PRBool GetNamesValues(PRInt32 aMaxNumValues, PRInt32& aNumValues,
nsString* aValues, nsString* aNames);
virtual void MouseClicked(nsIPresContext* aPresContext);
private:
NS_IMETHOD_(nsrefcnt) AddRef() { return NS_OK; }
NS_IMETHOD_(nsrefcnt) Release() { return NS_OK; }
nscoord mSuggestedWidth;
nscoord mSuggestedHeight;
}; };

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

@ -40,6 +40,8 @@ CSS_ATOM(afterPseudo, ":after")
CSS_ATOM(beforePseudo, ":before") CSS_ATOM(beforePseudo, ":before")
CSS_ATOM(buttonLabelPseudo, ":-moz-buttonlabel")
CSS_ATOM(checkedPseudo, ":checked") CSS_ATOM(checkedPseudo, ":checked")
CSS_ATOM(disabledPseudo, ":disabled") CSS_ATOM(disabledPseudo, ":disabled")

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

@ -2458,6 +2458,40 @@ nsCSSFrameConstructor::ConstructCheckboxControlFrame(nsIPresContext* aPres
return rv; return rv;
} }
nsresult
nsCSSFrameConstructor::ConstructButtonLabelFrame(nsIPresContext *aPresContext,
nsIContent *aContent,
nsIFrame *&aFrame,
nsFrameConstructorState& aState,
nsFrameItems& aFrameItems)
{
// Construct a button label using generated content specified
// through style. A style rule of following form must be
// present in ua.css or other style sheet
// input[type=button][value]:-moz-buttonlabel {
// content:attr(value);
// }
// The default for the label is specified with a rule similar to
// the following:
// input[type=reset]:-moz-buttonlabel {
// content:"Reset";
// }
nsresult rv = NS_OK;
nsIStyleContext* styleContext = nsnull;
nsIFrame* generatedFrame = nsnull;
// Probe for generated content before
aFrame->GetStyleContext(&styleContext);
if (CreateGeneratedContentFrame(aPresContext, aState, aFrame, aContent,
styleContext, nsCSSAtoms::buttonLabelPseudo,
PR_FALSE, PR_FALSE, &generatedFrame)) {
// Add the generated frame to the child list
aFrameItems.AddChild(generatedFrame);
}
return rv;
}
nsresult nsresult
nsCSSFrameConstructor::ConstructButtonControlFrame(nsIPresContext* aPresContext, nsCSSFrameConstructor::ConstructButtonControlFrame(nsIPresContext* aPresContext,
nsIFrame*& aNewFrame) nsIFrame*& aNewFrame)
@ -2814,6 +2848,10 @@ nsCSSFrameConstructor::ConstructFrameByTag(nsIPresContext* aPresContext
PR_TRUE, childItems); PR_TRUE, childItems);
} }
if (nsHTMLAtoms::input == aTag) {
// Construct button label frame using generated content
ConstructButtonLabelFrame(aPresContext, aContent, newFrame, aState, childItems);
}
// if there are any anonymous children create frames for them // if there are any anonymous children create frames for them
CreateAnonymousFrames(aPresContext, aTag, aState, aContent, newFrame, CreateAnonymousFrames(aPresContext, aTag, aState, aContent, newFrame,

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

@ -417,6 +417,12 @@ protected:
nsresult ConstructCheckboxControlFrame(nsIPresContext* aPresContext, nsresult ConstructCheckboxControlFrame(nsIPresContext* aPresContext,
nsIFrame*& aNewFrame); nsIFrame*& aNewFrame);
nsresult ConstructButtonLabelFrame(nsIPresContext *aPresContext,
nsIContent *aContent,
nsIFrame *&aFrame,
nsFrameConstructorState& aState,
nsFrameItems& aFrameItems);
nsresult ConstructButtonControlFrame(nsIPresContext* aPresContext, nsresult ConstructButtonControlFrame(nsIPresContext* aPresContext,
nsIFrame*& aNewFrame); nsIFrame*& aNewFrame);

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

@ -421,6 +421,49 @@ form {
display: block; display: block;
margin: 1em 0; margin: 1em 0;
} }
/* button */
input[type=button]:-moz-buttonlabel {
content:" ";
font-family: sans-serif;
font-size: small;
background-color:inherit;
}
input[type=button][value]:-moz-buttonlabel {
content:attr(value);
font-family: sans-serif;
font-size: small;
background-color:inherit;
}
/* submit */
input[type=submit]:-moz-buttonlabel {
content:"submit";
font-family: sans-serif;
font-size: small;
}
input[type=submit][value]:-moz-buttonlabel {
content:attr(value);
font-family: sans-serif;
font-size: small;
}
/* reset */
input[type=reset]:-moz-buttonlabel {
content:"reset";
font-family: sans-serif;
font-size: small;
}
input[type=reset][value]:-moz-buttonlabel {
content:attr(value);
font-family: sans-serif;
font-size: small;
}
input { input {
vertical-align: bottom; vertical-align: bottom;
border: 2px inset rgb(204, 204, 204); border: 2px inset rgb(204, 204, 204);
@ -443,6 +486,12 @@ input[type=file] input[type=button] {
height:inherit; height:inherit;
} }
input[type=file] input[type=button]:-moz-buttonlabel {
content:"Browse...";
font-family: sans-serif;
}
input[type=radio] { input[type=radio] {
/* these margins are for NavQuirks, we need a Standard ua.css */ /* these margins are for NavQuirks, we need a Standard ua.css */
margin-left: 3px; margin-left: 3px;
@ -606,13 +655,11 @@ input[type="button"] {
border: 2px outset rgb(156, 154, 156); border: 2px outset rgb(156, 154, 156);
background-color: rgb(206, 207, 206); background-color: rgb(206, 207, 206);
color:black; color:black;
padding: 1px; padding: 1px;
} }
input[type="button"]:active { input[type="button"]:active {
border-style: inset; border-style: inset;
padding-left: 2px; padding-left: 2px;
padding-right: 0px; padding-right: 0px;
padding-top: 2px; padding-top: 2px;
@ -648,7 +695,6 @@ input[type="button"]:focus:-moz-focus-inner {
padding-right : 1px; padding-right : 1px;
padding-top : 0px; padding-top : 0px;
padding-bottom: 0px; padding-bottom: 0px;
margin: 0px; margin: 0px;
border : 1px dotted black; border : 1px dotted black;
} }
@ -873,6 +919,7 @@ optgroup:before {
content:attr(label); content:attr(label);
} }
textarea { textarea {
vertical-align: bottom; vertical-align: bottom;
border: 2px inset #c0c0c0; border: 2px inset #c0c0c0;