removing unneeded native frames and unneeded frame classes that these derived from

fixing checkbox and radiobutton state restore
fixing right btn click on dropdown
adding in initial work for accesskey
bug 17027,26296,27063,7559; carpool a=leaf; r=kmcclusk
This commit is contained in:
rods%netscape.com 2000-02-09 19:34:39 +00:00
parent 691c453135
commit 1539b1b9c3
52 changed files with 2113 additions and 262 deletions

View File

@ -132,6 +132,8 @@ nsComboboxControlFrame::~nsComboboxControlFrame()
NS_IF_RELEASE(mPresContext);
NS_IF_RELEASE(mDisplayContent);
NS_IF_RELEASE(mButtonContent);
nsFormControlFrame::RegUnRegAccessKey(mPresContext, NS_STATIC_CAST(nsIFrame*, this), PR_FALSE);
}
//--------------------------------------------------------------
@ -265,9 +267,7 @@ nsComboboxControlFrame::Reset(nsIPresContext* aPresContext)
}
void
nsComboboxControlFrame::PostCreateWidget(nsIPresContext* aPresContext,
nscoord& aWidth,
nscoord& aHeight)
nsComboboxControlFrame::InitializeControl(nsIPresContext* aPresContext)
{
Reset(aPresContext);
}
@ -724,6 +724,7 @@ nsComboboxControlFrame::Reflow(nsIPresContext* aPresContext,
if (!mFormFrame && (eReflowReason_Initial == aReflowState.reason)) {
nsFormControlFrame::RegUnRegAccessKey(aPresContext, NS_STATIC_CAST(nsIFrame*, this), PR_TRUE);
nsFormFrame::AddFormControlFrame(aPresContext, *NS_STATIC_CAST(nsIFrame*,this));
}
@ -912,6 +913,7 @@ nsComboboxControlFrame::Reflow(nsIPresContext* aPresContext,
#else // DO_OLD_REFLOW
#ifdef DEBUG_rods
nsComboboxControlFrame * pCB = nsnull;
static int myCounter = 0;
#endif
@ -922,7 +924,8 @@ nsComboboxControlFrame::Reflow(nsIPresContext* aPresContext,
nsReflowStatus& aStatus)
{
#ifdef DEBUG_rods
printf("****** nsComboboxControlFrame::Reflow %d Reason: ", myCounter++);
//if (pCB) {
printf("%p ****** nsComboboxControlFrame::Reflow %d Reason: ", this, myCounter++);
switch (aReflowState.reason) {
case eReflowReason_Initial:
printf("eReflowReason_Initial\n");break;
@ -933,6 +936,7 @@ nsComboboxControlFrame::Reflow(nsIPresContext* aPresContext,
break;
case eReflowReason_StyleChange:printf("eReflowReason_StyleChange\n");break;
}
//}
#endif
#if 0
@ -993,7 +997,9 @@ nsComboboxControlFrame::Reflow(nsIPresContext* aPresContext,
// but it does seems to go into this code.
} else {
if (targetFrame != dropdownFrame) {
#ifdef DEBUG_rods
printf("+++++++++++++++++++++++\n");
#endif
rv = nsAreaFrame::Reflow(aPresContext, aDesiredSize, aReflowState, aStatus);
displayFrame->GetRect(displayRect);
buttonFrame->GetRect(buttonRect);
@ -1001,14 +1007,34 @@ nsComboboxControlFrame::Reflow(nsIPresContext* aPresContext,
buttonRect.height = displayRect.height;
buttonFrame->SetRect(aPresContext, buttonRect);
aStatus = NS_FRAME_COMPLETE;
#ifdef DEBUG_rods
printf("--> W: %d H: %d\n", aDesiredSize.width, aDesiredSize.height);
#endif
return rv;
} else {
#if 0
nsRect dropdownRect;
dropdownFrame->GetRect(dropdownRect);
nsHTMLReflowMetrics dropdownDesiredSize(aDesiredSize);
ReflowComboChildFrame(dropdownFrame, aPresContext, dropdownDesiredSize, firstPassState,
aStatus, firstPassState.availableWidth, firstPassState.availableHeight);
return NS_OK;
aStatus, dropdownRect.width, dropdownRect.height);
nsCOMPtr<nsIStyleContext> context;
targetFrame->GetStyleContext(getter_AddRefs(context));
const nsStyleDisplay* disp = (const nsStyleDisplay*)context->GetStyleData(eStyleStruct_Display);
printf("IsVisible %s\n", disp->mVisible == NS_STYLE_VISIBILITY_VISIBLE?"yes":"No");
//if (disp->mVisible == NS_STYLE_VISIBILITY_VISIBLE) {
nsRect rect;
GetRect(rect);
aDesiredSize.width = rect.width;// + borderPadding.left + borderPadding.right;
aDesiredSize.height = rect.height;// + borderPadding.top + borderPadding.bottom;
aDesiredSize.ascent = aDesiredSize.height;
aDesiredSize.descent = 0;
dropdownRect.width = rect.width;
dropdownFrame->SetRect(aPresContext, dropdownRect);
printf("Skipping out..........................");
aStatus = NS_FRAME_COMPLETE;
return NS_OK;
//}
#endif
}
}
@ -1035,10 +1061,15 @@ nsComboboxControlFrame::Reflow(nsIPresContext* aPresContext,
dx->GetCanonicalPixelScale(scale);
scrollbarWidth = NSIntPixelsToTwips(info.mSize, p2t*scale);
}
#ifdef DEBUG_rods
printf("UNC %d AV %d \n", firstPassState.mComputedWidth,firstPassState.availableWidth);
#endif
//Set the desired size for the button and display frame
if (NS_UNCONSTRAINEDSIZE == firstPassState.mComputedWidth) {
#ifdef DEBUG_rods
printf("=====================================\n");
#endif
// A width has not been specified for the select so size the display area to
// match the width of the longest item in the drop-down list. The dropdown
// list has already been reflowed and sized to shrink around its contents above.
@ -1077,7 +1108,9 @@ nsComboboxControlFrame::Reflow(nsIPresContext* aPresContext,
dspBorderPadding.SizeTo(0, 0, 0, 0);
dspSpacing->CalcBorderPaddingFor(displayFrame, dspBorderPadding);
#ifdef DEBUG_rods
printf("W: %d\n", dropdownRect.width-size.width+dspBorderPadding.left+dspBorderPadding.right);
#endif
// Set width of display to match width of the drop down
SetChildFrameSize(displayFrame, dropdownRect.width-size.width+dspBorderPadding.left+dspBorderPadding.right,
size.height+dspBorderPadding.top+dspBorderPadding.bottom);
@ -1103,7 +1136,9 @@ nsComboboxControlFrame::Reflow(nsIPresContext* aPresContext,
}
} else {
#ifdef DEBUG_rods
printf("*************************************\n");
#endif
// for debug -------
PRInt32 length = 0;
mListControlFrame->GetNumberOfOptions(&length);
@ -1129,7 +1164,9 @@ nsComboboxControlFrame::Reflow(nsIPresContext* aPresContext,
// nsAreaFrame::Reflow adds in the border and padding so we need to remove it
//displayWidth -= borderPadding.left + borderPadding.right;
#ifdef DEBUG_rods
printf("WW: %d\n", displayWidth);
#endif
// Set the displayFrame to match the displayWidth computed above
if (displayWidth >= 0) {
SetChildFrameSize(displayFrame, displayWidth, size.height);
@ -1146,7 +1183,9 @@ nsComboboxControlFrame::Reflow(nsIPresContext* aPresContext,
buttonRect.height = displayRect.height;
buttonFrame->SetRect(aPresContext, buttonRect);
displayFrame->SetRect(aPresContext, displayRect);
#ifdef DEBUG_rods
printf("DW: %d\n", aDesiredSize.width);
#endif
// nsAreaFrame::Reflow adds in the border and padding so we need to remove it
// XXX rods - this hould not be subtracted in
//aDesiredSize.width += borderPadding.left + borderPadding.right;
@ -1156,6 +1195,8 @@ nsComboboxControlFrame::Reflow(nsIPresContext* aPresContext,
}
aDesiredSize.width = firstPassState.mComputedWidth + borderPadding.left + borderPadding.right;
aDesiredSize.height = firstPassState.mComputedHeight + borderPadding.top + borderPadding.bottom;
aDesiredSize.ascent = aDesiredSize.height;
aDesiredSize.descent = 0;
}
// Set the max element size to be the same as the desired element size.
@ -1164,18 +1205,15 @@ nsComboboxControlFrame::Reflow(nsIPresContext* aPresContext,
aDesiredSize.maxElementSize->height = aDesiredSize.height;
}
nsRect absoluteTwips;
nsRect absolutePixels;
GetAbsoluteFramePosition(aPresContext, this, absoluteTwips, absolutePixels);
PositionDropdown(aPresContext, aDesiredSize.height, absoluteTwips, absolutePixels);
aStatus = NS_FRAME_COMPLETE;
#if 0
COMPARE_QUIRK_SIZE("nsComboboxControlFrame", 127, 22)
#endif
nsFormControlFrame::SetupCachedSizes(mCacheSize, mCachedMaxElementSize, aDesiredSize);
#ifdef DEBUG_rods
printf("--> W: %d H: %d\n", aDesiredSize.width, aDesiredSize.height);
#endif
return rv;
}
@ -1422,6 +1460,7 @@ nsComboboxControlFrame::SelectionChanged()
}
if (shouldSetValue) {
rv = htmlContent->SetHTMLAttribute(nsHTMLAtoms::value, mTextStr, PR_TRUE);
#if 1
if (NS_SUCCEEDED(rv)) {
nsIFrame* displayFrame = GetDisplayFrame(mPresContext);
@ -1439,6 +1478,15 @@ nsComboboxControlFrame::SelectionChanged()
NS_RELEASE(cmd);
}
}
#else
if (mParent) {
nsCOMPtr<nsIPresShell> shell;
rv = mPresContext->GetShell(getter_AddRefs(shell));
mState |= NS_FRAME_IS_DIRTY;
mParent->ReflowDirtyChild(shell, (nsIFrame*) this);
}
#endif
}
}
}
@ -1467,12 +1515,19 @@ nsComboboxControlFrame::DoneAddingContent(PRBool aIsDone)
NS_IMETHODIMP
nsComboboxControlFrame::AddOption(nsIPresContext* aPresContext, PRInt32 aIndex)
{
#ifdef DEBUG_rodsXXX
if (!pCB) pCB = this;
#endif
nsISelectControlFrame* listFrame = nsnull;
nsIFrame* dropdownFrame = GetDropdownFrame();
nsresult rv = dropdownFrame->QueryInterface(NS_GET_IID(nsISelectControlFrame),
(void**)&listFrame);
if (NS_SUCCEEDED(rv) && listFrame) {
rv = listFrame->AddOption(aPresContext, aIndex);
PRInt32 index;
mListControlFrame->GetSelectedIndex(&index);
UpdateSelection(PR_FALSE, PR_TRUE, index);
NS_RELEASE(listFrame);
}
// If we added the first option, we might need to select it.

View File

@ -35,8 +35,6 @@
#include "nsIRollupListener.h"
#include "nsIPresState.h"
class nsButtonControlFrame;
class nsTextControlFrame;
class nsFormFrame;
class nsIView;
class nsStyleContext;
@ -109,9 +107,7 @@ public:
NS_IMETHOD GetProperty(nsIAtom* aName, nsString& aValue);
void SetFocus(PRBool aOn, PRBool aRepaint);
void ScrollIntoView(nsIPresContext* aPresContext);
virtual void PostCreateWidget(nsIPresContext* aPresContext,
nscoord& aWidth,
nscoord& aHeight);
virtual void InitializeControl(nsIPresContext* aPresContext);
virtual PRBool IsSuccessful(nsIFormControlFrame* aSubmitter);
virtual void SetFormFrame(nsFormFrame* aFormFrame) { mFormFrame = aFormFrame; }
virtual void Reset(nsIPresContext* aPresContext);

View File

@ -22,9 +22,7 @@
#include "nsFileControlFrame.h"
#include "nsFormFrame.h"
#include "nsButtonControlFrame.h"
#include "nsTextControlFrame.h"
#include "nsNativeTextControlFrame.h" // XXX: remove when frame construction is done properly
#include "nsGfxTextControlFrame.h"
#include "nsIContent.h"
#include "prtypes.h"
#include "nsIAtom.h"
@ -312,7 +310,7 @@ nsFileControlFrame::SetInitialChildList(nsIPresContext* aPresContext,
* frame constuctor create the frame and its implementation. So we are given the text
* node from the constructor and we find it in our tree.
*/
nsTextControlFrame*
nsGfxTextControlFrame*
nsFileControlFrame::GetTextControlFrame(nsIPresContext* aPresContext, nsIFrame* aStart)
{
// find the text control frame.
@ -331,13 +329,13 @@ nsFileControlFrame::GetTextControlFrame(nsIPresContext* aPresContext, nsIFrame*
value.ToUpperCase();
nsString txt("TEXT");
if (value == txt) {
return (nsTextControlFrame*)childFrame;
return (nsGfxTextControlFrame*)childFrame;
}
}
}
// if not continue looking
nsTextControlFrame* frame = GetTextControlFrame(aPresContext, childFrame);
nsGfxTextControlFrame* frame = GetTextControlFrame(aPresContext, childFrame);
if (frame)
return frame;

View File

@ -30,8 +30,7 @@
#include "nsIStatefulFrame.h"
class nsIPresState;
class nsButtonControlFrame;
class nsTextControlFrame;
class nsGfxTextControlFrame;
class nsFormFrame;
class nsISupportsArray;
class nsIHTMLContent;
@ -176,7 +175,7 @@ protected:
virtual PRIntn GetSkipSides() const;
nsTextControlFrame* mTextFrame;
nsGfxTextControlFrame* mTextFrame;
nsFormFrame* mFormFrame;
nsIHTMLContent* mTextContent;
nsString* mCachedState;
@ -184,7 +183,7 @@ protected:
nsIPresContext* mPresContext; // weak reference
private:
nsTextControlFrame* GetTextControlFrame(nsIPresContext* aPresContext,
nsGfxTextControlFrame* GetTextControlFrame(nsIPresContext* aPresContext,
nsIFrame* aStart);
NS_IMETHOD_(nsrefcnt) AddRef() { return NS_OK; }

View File

@ -54,6 +54,11 @@
#include "nsStyleUtil.h"
#include "nsINameSpaceManager.h"
#include "nsIDOMHTMLInputElement.h"
#include "nsIDOMHTMLLabelElement.h"
#include "nsIDOMHTMLTextAreaElement.h"
#include "nsIDOMHTMLLegendElement.h"
#include "nsIDOMHTMLButtonElement.h"
#include "nsIEventStateManager.h"
static NS_DEFINE_IID(kIWidgetIID, NS_IWIDGET_IID);
@ -87,6 +92,7 @@ nsFormControlFrame::~nsFormControlFrame()
mFormFrame->RemoveRadioControlFrame(this);
mFormFrame = nsnull;
}
RegUnRegAccessKey(mPresContext, NS_STATIC_CAST(nsIFrame*, this), PR_FALSE);
}
// Frames are not refcounted, no need to AddRef
@ -302,42 +308,29 @@ nsFormControlFrame::Reflow(nsIPresContext* aPresContext,
const nsHTMLReflowState& aReflowState,
nsReflowStatus& aStatus)
{
if (!mDidInit) {
mPresContext = aPresContext;
InitializeControl(aPresContext);
mDidInit = PR_TRUE;
}
// add ourself as an nsIFormControlFrame
if (!mFormFrame && (eReflowReason_Initial == aReflowState.reason)) {
nsFormFrame::AddFormControlFrame(aPresContext, *NS_STATIC_CAST(nsIFrame*, this));
}
nsresult skiprv = SkipResizeReflow(mCacheSize, mCachedMaxElementSize, aPresContext,
aDesiredSize, aReflowState, aStatus);
if (NS_SUCCEEDED(skiprv)) {
return skiprv;
}
nsWidgetRendering mode;
aPresContext->GetWidgetRenderingMode(&mode);
if (eWidgetRendering_Native == mode) {
GetDesiredSize(aPresContext, aReflowState, aDesiredSize, mWidgetSize);
if (!mDidInit) {
PostCreateWidget(aPresContext, aDesiredSize.width, aDesiredSize.height);
mDidInit = PR_TRUE;
}
aDesiredSize.ascent = aDesiredSize.height;
aDesiredSize.descent = 0;
} else {
nsresult rv = nsLeafFrame::Reflow(aPresContext, aDesiredSize, aReflowState, aStatus);
if (!mDidInit) {
//GetDesiredSize(aPresContext, aReflowState, aDesiredSize);
PostCreateWidget(aPresContext, aDesiredSize.width, aDesiredSize.height);
mDidInit = PR_TRUE;
}
return rv;
}
nsresult rv = nsLeafFrame::Reflow(aPresContext, aDesiredSize, aReflowState, aStatus);
aStatus = NS_FRAME_COMPLETE;
SetupCachedSizes(mCacheSize, mCachedMaxElementSize, aDesiredSize);
return NS_OK;
return rv;
}
@ -347,9 +340,72 @@ nsFormControlFrame::GetWidgetInitData(nsIPresContext* aPresContext)
return nsnull;
}
void
nsFormControlFrame::PostCreateWidget(nsIPresContext* aPresContext, nscoord& aWidth, nscoord& aHeight)
nsresult
nsFormControlFrame::RegUnRegAccessKey(nsIPresContext* aPresContext, nsIFrame * aFrame, PRBool aDoReg)
{
#if 0
NS_ASSERTION(aPresContext, "aPresContext is NULL in RegUnRegAccessKey!");
NS_ASSERTION(aFrame, "aFrame is NULL in RegUnRegAccessKey!");
nsresult rv = NS_ERROR_FAILURE;
nsAutoString accessKey;
if (aFrame != nsnull) {
nsCOMPtr<nsIContent> content;
if (NS_SUCCEEDED(aFrame->GetContent(getter_AddRefs(content)))) {
#if 1
PRInt32 nameSpaceID;
content->GetNameSpaceID(nameSpaceID);
nsAutoString resultValue;
rv = content->GetAttribute(nameSpaceID, nsHTMLAtoms::accesskey, accessKey);
#else
nsCOMPtr<nsIDOMHTMLInputElement> inputElement(do_QueryInterface(content));
if (inputElement) {
rv = inputElement->GetAccessKey(accessKey);
} else {
nsCOMPtr<nsIDOMHTMLTextAreaElement> textarea(do_QueryInterface(content));
if (textarea) {
rv = textarea->GetAccessKey(accessKey);
} else {
nsCOMPtr<nsIDOMHTMLLabelElement> label(do_QueryInterface(content));
if (label) {
rv = label->GetAccessKey(accessKey);
} else {
nsCOMPtr<nsIDOMHTMLLegendElement> legend(do_QueryInterface(content));
if (legend) {
rv = legend->GetAccessKey(accessKey);
} else {
nsCOMPtr<nsIDOMHTMLButtonElement> btn(do_QueryInterface(content));
if (btn) {
rv = btn->GetAccessKey(accessKey);
}
}
}
}
}
#endif
}
}
if (NS_CONTENT_ATTR_NOT_THERE != rv) {
nsCOMPtr<nsIEventStateManager> stateManager;
if (NS_SUCCEEDED(aPresContext->GetEventStateManager(getter_AddRefs(stateManager)))) {
if (aDoReg) {
return stateManager->RegisterAccessKey(aFrame, (PRUint32)accessKey.First());
} else {
return stateManager->UnregisterAccessKey(aFrame);
}
}
}
#endif
return NS_ERROR_FAILURE;
}
void
nsFormControlFrame::InitializeControl(nsIPresContext* aPresContext)
{
RegUnRegAccessKey(aPresContext, NS_STATIC_CAST(nsIFrame*, this), PR_TRUE);
}
void

View File

@ -31,11 +31,14 @@
#include "nsLeafFrame.h"
#include "nsCoord.h"
#include "nsIStyleContext.h"
#include "nsIPresContext.h"
#include "nsCOMPtr.h"
class nsIView;
class nsIPresContext;
class nsStyleCoord;
class nsFormFrame;
class nsIFocusableContent;
#define CSS_NOTSET -1
#define ATTR_NOTSET -1
@ -152,11 +155,9 @@ public:
virtual void ControlChanged(nsIPresContext* aPresContext) {}
/**
* Perform opertations after the widget associated with this frame has been
* created.
* Chance to Initialize to a defualt value
*/
virtual void PostCreateWidget(nsIPresContext* aPresContext,
nscoord& aWidth, nscoord& aHeight);
virtual void InitializeControl(nsIPresContext* aPresContext);
virtual void SetFocus(PRBool aOn = PR_TRUE, PRBool aRepaint = PR_FALSE);
virtual void ScrollIntoView(nsIPresContext* aPresContext);
@ -221,6 +222,8 @@ public:
nsHTMLReflowMetrics& aDesiredSize,
const nsHTMLReflowState& aReflowState,
nsReflowStatus& aStatus);
// AccessKey Helper function
static nsresult RegUnRegAccessKey(nsIPresContext* aPresContext, nsIFrame * aFrame, PRBool aDoReg);
protected:
@ -301,6 +304,8 @@ protected:
nscoord mSuggestedWidth;
nscoord mSuggestedHeight;
nsCOMPtr<nsIPresContext> mPresContext;
// Reflow Optimization
nsSize mCacheSize;
nsSize mCachedMaxElementSize;

View File

@ -453,7 +453,7 @@ nsFormControlHelper::CalculateSize (nsIPresContext* aPresContext,
// need to set charWidth and aDesiredSize.height
charWidth = GetTextSize(aPresContext, aFrame, 1, aDesiredSize, aRendContext);
col = (col <= 0) ? 15 : col; // XXX why a default of 15 pixels, why hide it
// XXX this conflicts with a default of 20 found in nsTextControlFrame.
// XXX this conflicts with a default of 20 found in nsGfxTextControlFrame.
aDesiredSize.width = NSIntPixelsToTwips(col, p2t);
} else {
col = (col <= 0) ? 1 : col; // XXX why a default of 1 char, why hide it

View File

@ -332,7 +332,7 @@ nsGfxButtonControlFrame::Reflow(nsIPresContext* aPresContext,
nsFormFrame::AddFormControlFrame(aPresContext, *NS_STATIC_CAST(nsIFrame*, this));
}
#if 1
#if 0
nsresult skiprv = nsFormControlFrame::SkipResizeReflow(mCacheSize, mCachedMaxElementSize, aPresContext,
aDesiredSize, aReflowState, aStatus);
@ -362,6 +362,12 @@ nsGfxButtonControlFrame::Reflow(nsIPresContext* aPresContext,
aPresContext->GetCompatibilityMode(&mode);
if (mode == eCompatibility_NavQuirks) {
// nsHTMLButtonControlFrame::Reflow registers it for Standard Mode
// and sets up mPresContext
if (eReflowReason_Initial == aReflowState.reason) {
mPresContext = aPresContext;
nsFormControlFrame::RegUnRegAccessKey(aPresContext, NS_STATIC_CAST(nsIFrame*, this), PR_TRUE);
}
// Do NavQuirks Sizing and layout
rv = DoNavQuirksReflow(aPresContext, aDesiredSize, aReflowState, aStatus);
} else {

View File

@ -27,9 +27,12 @@
#include "nsFormFrame.h"
#include "nsIFormControl.h"
#include "nsIContent.h"
#include "nsWidgetsCID.h"
#include "nsIComponentManager.h"
#include "nsHTMLAtoms.h"
#include "nsINameSpaceManager.h"
#include "nsIPresState.h"
//------------------------------------------------------------
nsresult
NS_NewGfxCheckboxControlFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame)
{
@ -46,18 +49,156 @@ NS_NewGfxCheckboxControlFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame)
}
//------------------------------------------------------------
// Initialize GFX-rendered state
nsGfxCheckboxControlFrame::nsGfxCheckboxControlFrame()
: mChecked(eOff)
{
}
//----------------------------------------------------------------------
// nsISupports
//----------------------------------------------------------------------
// Frames are not refcounted, no need to AddRef
NS_IMETHODIMP
nsGfxCheckboxControlFrame::QueryInterface(const nsIID& aIID, void** aInstancePtr)
{
NS_ASSERTION(aInstancePtr, "QueryInterface requires a non-NULL destination!");
if ( !aInstancePtr )
return NS_ERROR_NULL_POINTER;
if (aIID.Equals(NS_GET_IID(nsIStatefulFrame))) {
*aInstancePtr = (void*)(nsIStatefulFrame*) this;
return NS_OK;
}
return nsFormControlFrame::QueryInterface(aIID, aInstancePtr);
}
//------------------------------------------------------------
//
// Init
//
// We need to override this in order to see if we're a tristate checkbox.
//
NS_IMETHODIMP
nsGfxCheckboxControlFrame::Init(nsIPresContext* aPresContext,
nsIContent* aContent,
nsIFrame* aParent,
nsIStyleContext* aContext,
nsIFrame* aPrevInFlow)
{
nsFormControlFrame::Init ( aPresContext, aContent, aParent, aContext, aPrevInFlow );
// figure out if we're a tristate at the start. This may change later on once
// we've been running for a while, so more code is in AttributeChanged() to pick
// that up. Regardless, we need this check when initializing.
nsAutoString value;
nsresult res = mContent->GetAttribute ( kNameSpaceID_None, GetTristateAtom(), value );
if ( res == NS_CONTENT_ATTR_HAS_VALUE )
mIsTristate = PR_TRUE;
// give the attribute a default value so it's always present, if we're a tristate
if ( IsTristateCheckbox() )
mContent->SetAttribute ( kNameSpaceID_None, GetTristateValueAtom(), "0", PR_FALSE );
return NS_OK;
}
//------------------------------------------------------------
//
// GetTristateAtom [static]
//
// Use a lazily instantiated static initialization scheme to create an atom that
// represents the attribute set when this should be a tri-state checkbox.
//
// Does NOT addref!
//
nsIAtom*
nsGfxCheckboxControlFrame :: GetTristateAtom ( )
{
return nsHTMLAtoms::moz_tristate;
}
//------------------------------------------------------------
//
// GetTristateValueAtom [static]
//
// Use a lazily instantiated static initialization scheme to create an atom that
// represents the attribute that holds the value when the button is a tri-state (since
// we can't use "checked").
//
// Does NOT addref!
//
nsIAtom*
nsGfxCheckboxControlFrame :: GetTristateValueAtom ( )
{
return nsHTMLAtoms::moz_tristatevalue;
}
//------------------------------------------------------------
//
// AttributeChanged
//
// Override to check for the attribute that determines if we're a normal or a
// tristate checkbox. If we notice a switch from one to the other, we need
// to adjust the proper attributes in the content model accordingly.
//
// Also, since the value of a tri-state is kept in a separate attribute (we
// can't use "checked" because it's a boolean), we have to notice it changing
// here.
//
NS_IMETHODIMP
nsGfxCheckboxControlFrame::AttributeChanged(nsIPresContext* aPresContext,
nsIContent* aChild,
PRInt32 aNameSpaceID,
nsIAtom* aAttribute,
PRInt32 aHint)
{
if ( aAttribute == GetTristateAtom() ) {
nsAutoString value;
nsresult res = mContent->GetAttribute ( kNameSpaceID_None, GetTristateAtom(), value );
PRBool isNowTristate = (res == NS_CONTENT_ATTR_HAS_VALUE);
if ( isNowTristate != mIsTristate )
SwitchModesWithEmergencyBrake(aPresContext, isNowTristate);
}
else if ( aAttribute == GetTristateValueAtom() ) {
// ignore this change if we're not a tri-state checkbox
if ( IsTristateCheckbox() ) {
nsAutoString value;
nsresult res = mContent->GetAttribute ( kNameSpaceID_None, GetTristateValueAtom(), value );
if ( res == NS_CONTENT_ATTR_HAS_VALUE )
SetCheckboxControlFrameState(aPresContext, value);
}
}
else
return nsFormControlFrame::AttributeChanged(aPresContext, aChild, aNameSpaceID, aAttribute, aHint);
return NS_OK;
}
//------------------------------------------------------------
//
// InitializeControl
//
// Set the default checked state of the checkbox.
//
void
nsGfxCheckboxControlFrame::InitializeControl(nsIPresContext* aPresContext)
{
nsFormControlFrame::InitializeControl(aPresContext);
PRBool checked = PR_FALSE;
nsresult result = GetDefaultCheckState(&checked);
if (NS_CONTENT_ATTR_HAS_VALUE == result) {
SetCheckboxState (aPresContext, checked ? eOn : eOff );
}
}
//------------------------------------------------------------
void
nsGfxCheckboxControlFrame::PaintCheckBox(nsIPresContext* aPresContext,
nsIRenderingContext& aRenderingContext,
const nsRect& aDirtyRect,
nsFramePaintLayer aWhichLayer)
nsIRenderingContext& aRenderingContext,
const nsRect& aDirtyRect,
nsFramePaintLayer aWhichLayer)
{
aRenderingContext.PushState();
@ -111,6 +252,7 @@ nsGfxCheckboxControlFrame::PaintCheckBox(nsIPresContext* aPresContext,
}
//------------------------------------------------------------
//
// PaintMixedMark
//
@ -155,6 +297,7 @@ nsGfxCheckboxControlFrame::PaintMixedMark ( nsIRenderingContext& aRenderingConte
} // PaintMixedMark
//------------------------------------------------------------
NS_METHOD
nsGfxCheckboxControlFrame::Paint(nsIPresContext* aPresContext,
nsIRenderingContext& aRenderingContext,
@ -167,7 +310,7 @@ nsGfxCheckboxControlFrame::Paint(nsIPresContext* aPresContext,
return NS_OK;
// Paint the background
Inherited::Paint(aPresContext, aRenderingContext, aDirtyRect, aWhichLayer);
nsFormControlFrame::Paint(aPresContext, aRenderingContext, aDirtyRect, aWhichLayer);
if (NS_FRAME_PAINT_LAYER_FOREGROUND == aWhichLayer) {
// Paint the checkmark
PaintCheckBox(aPresContext, aRenderingContext, aDirtyRect, aWhichLayer);
@ -176,20 +319,232 @@ nsGfxCheckboxControlFrame::Paint(nsIPresContext* aPresContext,
}
nsCheckboxControlFrame::CheckState
nsGfxCheckboxControlFrame :: GetCheckboxState ( )
//------------------------------------------------------------
nsGfxCheckboxControlFrame::CheckState
nsGfxCheckboxControlFrame::GetCheckboxState ( )
{
return mChecked;
}
//------------------------------------------------------------
void
nsGfxCheckboxControlFrame :: SetCheckboxState (nsIPresContext* aPresContext,
nsCheckboxControlFrame::CheckState aValue )
nsGfxCheckboxControlFrame::SetCheckboxState (nsIPresContext* aPresContext,
nsGfxCheckboxControlFrame::CheckState aValue )
{
mChecked = aValue;
nsFormControlHelper::ForceDrawFrame(aPresContext, this);
}
//------------------------------------------------------------
void nsGfxCheckboxControlFrame::GetCheckboxControlFrameState(nsString& aValue)
{
CheckStateToString(GetCheckboxState(), aValue);
}
//------------------------------------------------------------
void nsGfxCheckboxControlFrame::SetCheckboxControlFrameState(nsIPresContext* aPresContext,
const nsString& aValue)
{
CheckState state = StringToCheckState(aValue);
SetCheckboxState(aPresContext, state);
}
//------------------------------------------------------------
NS_IMETHODIMP nsGfxCheckboxControlFrame::SetProperty(nsIPresContext* aPresContext,
nsIAtom* aName,
const nsString& aValue)
{
if (nsHTMLAtoms::checked == aName)
SetCheckboxControlFrameState(aPresContext, aValue);
else
return nsFormControlFrame::SetProperty(aPresContext, aName, aValue);
return NS_OK;
}
//------------------------------------------------------------
NS_IMETHODIMP nsGfxCheckboxControlFrame::GetProperty(nsIAtom* aName, nsString& aValue)
{
if (nsHTMLAtoms::checked == aName)
GetCheckboxControlFrameState(aValue);
else
return nsFormControlFrame::GetProperty(aName, aValue);
return NS_OK;
}
//------------------------------------------------------------
PRInt32
nsGfxCheckboxControlFrame::GetMaxNumValues()
{
return 1;
}
//------------------------------------------------------------
PRBool
nsGfxCheckboxControlFrame::GetNamesValues(PRInt32 aMaxNumValues, PRInt32& aNumValues,
nsString* aValues, nsString* aNames)
{
nsAutoString name;
nsresult nameResult = GetName(&name);
if ((aMaxNumValues <= 0) || (NS_CONTENT_ATTR_HAS_VALUE != nameResult)) {
return PR_FALSE;
}
PRBool result = PR_TRUE;
CheckState state = GetCheckboxState();
nsAutoString value;
nsresult valueResult = GetValue(&value);
if (eOn != state) {
result = PR_FALSE;
} else {
if (NS_CONTENT_ATTR_HAS_VALUE != valueResult) {
aValues[0] = "on";
} else {
aValues[0] = value;
}
aNames[0] = name;
aNumValues = 1;
}
return result;
}
//------------------------------------------------------------
void
nsGfxCheckboxControlFrame::Reset(nsIPresContext* aPresContext)
{
PRBool checked;
GetDefaultCheckState(&checked);
SetCheckboxState (aPresContext, checked ? eOn : eOff );
}
//------------------------------------------------------------
//
// CheckStateToString
//
// Converts from a CheckState to a string
//
void
nsGfxCheckboxControlFrame::CheckStateToString ( CheckState inState, nsString& outStateAsString )
{
switch ( inState ) {
case eOn:
outStateAsString = NS_STRING_TRUE;
break;
case eOff:
outStateAsString = NS_STRING_FALSE;
break;
case eMixed:
outStateAsString = "2";
break;
}
} // CheckStateToString
//------------------------------------------------------------
//
// StringToCheckState
//
// Converts from a string to a CheckState enum
//
nsGfxCheckboxControlFrame::CheckState
nsGfxCheckboxControlFrame::StringToCheckState ( const nsString & aStateAsString )
{
if ( aStateAsString == NS_STRING_TRUE )
return eOn;
else if ( aStateAsString == NS_STRING_FALSE )
return eOff;
// not true and not false means mixed
return eMixed;
} // StringToCheckState
//------------------------------------------------------------
//
// SwitchModesWithEmergencyBrake
//
// Since we use an attribute to decide if we're a tristate box or not, this can change
// at any time. Since we have to use separate attributes to store the values depending
// on the mode, we have to convert from one to the other.
//
void
nsGfxCheckboxControlFrame::SwitchModesWithEmergencyBrake ( nsIPresContext* aPresContext,
PRBool inIsNowTristate )
{
if ( inIsNowTristate ) {
// we were a normal checkbox, and now we're a tristate. That means that the
// state of the checkbox was in "checked" and needs to be copied over into
// our parallel attribute.
nsAutoString value;
CheckStateToString ( GetCheckboxState(), value );
mContent->SetAttribute ( kNameSpaceID_None, GetTristateValueAtom(), value, PR_FALSE );
}
else {
// we were a tri-state checkbox, and now we're a normal checkbox. The current
// state is already up to date (because it's always up to date). We just have
// to make sure it's not mixed. If it is, just set it to checked. Remove our
// parallel attribute so that we're nice and HTML4 compliant.
if ( GetCheckboxState() == eMixed )
SetCheckboxState(aPresContext, eOn);
mContent->UnsetAttribute ( kNameSpaceID_None, GetTristateValueAtom(), PR_FALSE );
}
// switch!
mIsTristate = inIsNowTristate;
} // SwitchModesWithEmergencyBrake
//----------------------------------------------------------------------
// nsIStatefulFrame
//----------------------------------------------------------------------
NS_IMETHODIMP nsGfxCheckboxControlFrame::GetStateType(nsIPresContext* aPresContext,
nsIStatefulFrame::StateType* aStateType)
{
*aStateType=nsIStatefulFrame::eCheckboxType;
return NS_OK;
}
NS_IMETHODIMP nsGfxCheckboxControlFrame::SaveState(nsIPresContext* aPresContext,
nsIPresState** aState)
{
// Construct a pres state.
NS_NewPresState(aState); // The addref happens here.
// This string will hold a single item, whether or not we're checked.
nsAutoString stateString;
GetCheckboxControlFrameState(stateString);
(*aState)->SetStateProperty("checked", stateString);
return NS_OK;
}
NS_IMETHODIMP nsGfxCheckboxControlFrame::RestoreState(nsIPresContext* aPresContext,
nsIPresState* aState)
{
if (!mDidInit) {
mPresContext = aPresContext;
InitializeControl(aPresContext);
mDidInit = PR_TRUE;
}
nsAutoString string;
aState->GetStateProperty("checked", string);
SetCheckboxControlFrameState(aPresContext, string);
return NS_OK;
}
//------------------------------------------------------------
// Extra Debug Methods
//------------------------------------------------------------
#ifdef DEBUG_rodsXXX
NS_IMETHODIMP
nsGfxCheckboxControlFrame::Reflow(nsIPresContext* aPresContext,
@ -197,7 +552,7 @@ nsGfxCheckboxControlFrame::Reflow(nsIPresContext* aPresContext,
const nsHTMLReflowState& aReflowState,
nsReflowStatus& aStatus)
{
nsresult rv = nsNativeFormControlFrame::Reflow(aPresContext, aDesiredSize, aReflowState, aStatus);
nsresult rv = nsFormControlFrame::Reflow(aPresContext, aDesiredSize, aReflowState, aStatus);
COMPARE_QUIRK_SIZE("nsGfxCheckboxControlFrame", 13, 13)
return rv;

View File

@ -22,13 +22,13 @@
#ifndef nsGfxCheckboxControlFrame_h___
#define nsGfxCheckboxControlFrame_h___
#include "nsCheckboxControlFrame.h"
#include "nsFormControlFrame.h"
#include "nsIStatefulFrame.h"
class nsGfxCheckboxControlFrame : public nsCheckboxControlFrame {
private:
typedef nsCheckboxControlFrame Inherited;
class nsGfxCheckboxControlFrame : public nsFormControlFrame,
public nsIStatefulFrame
{
public:
nsGfxCheckboxControlFrame();
@ -37,17 +37,43 @@ public:
return MakeFrameName("CheckboxControl", aResult);
}
#endif
// this should be protected, but VC6 is lame.
enum CheckState { eOff, eOn, eMixed } ;
// overrides base class HandleEvent to do nothing
// events are handled by the DOM
NS_IMETHOD HandleEvent(nsIPresContext* aPresContext,
nsGUIEvent* aEvent,
nsEventStatus* aEventStatus) { return NS_OK; }
NS_IMETHOD Init(nsIPresContext* aPresContext,
nsIContent* aContent,
nsIFrame* aParent,
nsIStyleContext* aContext,
nsIFrame* aPrevInFlow) ;
NS_IMETHOD AttributeChanged(nsIPresContext* aPresContext,
nsIContent* aChild,
PRInt32 aNameSpaceID,
nsIAtom* aAttribute,
PRInt32 aHint) ;
NS_IMETHOD Paint(nsIPresContext* aPresContext,
nsIRenderingContext& aRenderingContext,
const nsRect& aDirtyRect,
nsFramePaintLayer aWhichLayer);
void InitializeControl(nsIPresContext* aPresContext);
// nsIFormControlFrame
NS_IMETHOD SetProperty(nsIPresContext* aPresContext, nsIAtom* aName, const nsString& aValue);
NS_IMETHOD GetProperty(nsIAtom* aName, nsString& aValue);
virtual void Reset(nsIPresContext* aPresContext);
virtual PRInt32 GetMaxNumValues();
virtual PRBool GetNamesValues(PRInt32 aMaxNumValues, PRInt32& aNumValues,
nsString* aValues, nsString* aNames);
// nsIStatefulFrame
NS_IMETHOD QueryInterface(const nsIID& aIID, void** aInstancePtr);
NS_IMETHOD GetStateType(nsIPresContext* aPresContext, nsIStatefulFrame::StateType* aStateType);
NS_IMETHOD SaveState(nsIPresContext* aPresContext, nsIPresState** aState);
NS_IMETHOD RestoreState(nsIPresContext* aPresContext, nsIPresState* aState);
#ifdef DEBUG_rodsXXX
NS_IMETHOD Reflow(nsIPresContext* aCX,
nsHTMLReflowMetrics& aDesiredSize,
@ -56,8 +82,35 @@ public:
#endif
protected:
virtual CheckState GetCheckboxState();
virtual void SetCheckboxState(nsIPresContext* aPresContext, CheckState aValue);
// native/gfx implementations need to implement needs.
CheckState GetCheckboxState();
void SetCheckboxState(nsIPresContext* aPresContext, CheckState aValue);
// Utility methods for implementing SetProperty/GetProperty
void SetCheckboxControlFrameState(nsIPresContext* aPresContext,
const nsString& aValue);
void GetCheckboxControlFrameState(nsString& aValue);
// utility routine for converting from DOM values to internal enum
void CheckStateToString ( CheckState inState, nsString& outStateAsString ) ;
CheckState StringToCheckState ( const nsString & aStateAsString ) ;
// figure out if we're a tri-state checkbox.
PRBool IsTristateCheckbox ( ) const { return mIsTristate; }
// we just became a tri-state, or we just lost tri-state status. fix up
// the attributes for the new mode.
void SwitchModesWithEmergencyBrake ( nsIPresContext* aPresContext,
PRBool inIsNowTristate ) ;
// for tri-state checkbox. meaningless for normal HTML
PRBool mIsTristate;
static nsIAtom* GetTristateAtom() ;
static nsIAtom* GetTristateValueAtom() ;
protected:
virtual void PaintCheckBox(nsIPresContext* aPresContext,
nsIRenderingContext& aRenderingContext,
@ -68,7 +121,11 @@ protected:
//GFX-rendered state variables
CheckState mChecked;
private:
NS_IMETHOD_(nsrefcnt) AddRef() { return NS_OK; }
NS_IMETHOD_(nsrefcnt) Release() { return NS_OK; }
};
#endif

View File

@ -21,7 +21,6 @@
*/
#include "nsGfxRadioControlFrame.h"
#include "nsIRadioButton.h"
#include "nsHTMLAtoms.h"
#include "nsHTMLParts.h"
#include "nsFormFrame.h"
@ -31,6 +30,8 @@
#include "nsIComponentManager.h"
#include "nsCOMPtr.h"
#include "nsCSSRendering.h"
#include "nsIPresState.h"
#include "nsINameSpaceManager.h"
nsresult
@ -57,11 +58,31 @@ nsGfxRadioControlFrame::nsGfxRadioControlFrame()
nsGfxRadioControlFrame::~nsGfxRadioControlFrame()
{
NS_IF_RELEASE(mRadioButtonFaceStyle);
NS_IF_RELEASE(mRadioButtonFaceStyle);
}
//--------------------------------------------------------------
// Frames are not refcounted, no need to AddRef
NS_IMETHODIMP
nsGfxRadioControlFrame::QueryInterface(const nsIID& aIID, void** aInstancePtr)
{
NS_PRECONDITION(0 != aInstancePtr, "null ptr");
if (NULL == aInstancePtr) {
return NS_ERROR_NULL_POINTER;
}
if (aIID.Equals(NS_GET_IID(nsIRadioControlFrame))) {
*aInstancePtr = (void*) ((nsIRadioControlFrame*) this);
return NS_OK;
}
if (aIID.Equals(NS_GET_IID(nsIStatefulFrame))) {
*aInstancePtr = (void*) ((nsIStatefulFrame*) this);
return NS_OK;
}
return nsFormControlFrame::QueryInterface(aIID, aInstancePtr);
}
//--------------------------------------------------------------
NS_IMETHODIMP
nsGfxRadioControlFrame::GetAdditionalStyleContext(PRInt32 aIndex,
nsIStyleContext** aStyleContext) const
@ -82,6 +103,7 @@ nsGfxRadioControlFrame::GetAdditionalStyleContext(PRInt32 aIndex,
return NS_OK;
}
//--------------------------------------------------------------
NS_IMETHODIMP
nsGfxRadioControlFrame::SetAdditionalStyleContext(PRInt32 aIndex,
nsIStyleContext* aStyleContext)
@ -99,7 +121,69 @@ nsGfxRadioControlFrame::SetAdditionalStyleContext(PRInt32 aIndex,
return NS_OK;
}
//--------------------------------------------------------------
NS_IMETHODIMP nsGfxRadioControlFrame::SetProperty(nsIPresContext* aPresContext, nsIAtom* aName, const nsString& aValue)
{
if (nsHTMLAtoms::checked == aName) {
PRBool state = (aValue == NS_STRING_TRUE) ? PR_TRUE : PR_FALSE;
SetRadioState(aPresContext, state);
if (mFormFrame) {
mFormFrame->OnRadioChecked(aPresContext, *this, state);
}
}
else {
return nsFormControlFrame::SetProperty(aPresContext, aName, aValue);
}
return NS_OK;
}
//--------------------------------------------------------------
NS_IMETHODIMP nsGfxRadioControlFrame::GetProperty(nsIAtom* aName, nsString& aValue)
{
// Return the value of the property from the widget it is not null.
// If is null, assume the widget is GFX-rendered and return a member variable instead.
if (nsHTMLAtoms::checked == aName) {
nsFormControlHelper::GetBoolString(GetRadioState(), aValue);
} else {
return nsFormControlFrame::GetProperty(aName, aValue);
}
return NS_OK;
}
//--------------------------------------------------------------
PRBool
nsGfxRadioControlFrame::GetChecked(PRBool aGetInitialValue)
{
PRBool checked = PR_FALSE;
if (PR_TRUE == aGetInitialValue) {
GetDefaultCheckState(&checked);
}
else {
GetCurrentCheckState(&checked);
}
return(checked);
}
//--------------------------------------------------------------
void
nsGfxRadioControlFrame::SetChecked(nsIPresContext* aPresContext, PRBool aValue, PRBool aSetInitialValue)
{
if (aSetInitialValue) {
if (aValue) {
mContent->SetAttribute(kNameSpaceID_HTML, nsHTMLAtoms::checked, nsAutoString("1"), PR_FALSE); // XXX should be "empty" value
} else {
mContent->SetAttribute(kNameSpaceID_HTML, nsHTMLAtoms::checked, nsAutoString("0"), PR_FALSE);
}
}
SetRadioState(aPresContext, aValue);
}
//--------------------------------------------------------------
NS_IMETHODIMP
nsGfxRadioControlFrame::SetRadioButtonFaceStyleContext(nsIStyleContext *aRadioButtonFaceStyleContext)
{
@ -108,6 +192,47 @@ nsGfxRadioControlFrame::SetRadioButtonFaceStyleContext(nsIStyleContext *aRadioBu
return NS_OK;
}
//--------------------------------------------------------------
PRBool
nsGfxRadioControlFrame::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;
}
PRBool state = GetRadioState();
if(PR_TRUE != state) {
return PR_FALSE;
}
nsAutoString value;
result = GetValue(&value);
if (NS_CONTENT_ATTR_HAS_VALUE == result) {
aValues[0] = value;
} else {
aValues[0] = "on";
}
aNames[0] = name;
aNumValues = 1;
return PR_TRUE;
}
//--------------------------------------------------------------
void
nsGfxRadioControlFrame::Reset(nsIPresContext* aPresContext)
{
PRBool checked = PR_TRUE;
GetDefaultCheckState(&checked);
SetCurrentCheckState(checked);
}
//--------------------------------------------------------------
void
nsGfxRadioControlFrame::PaintRadioButton(nsIPresContext* aPresContext,
nsIRenderingContext& aRenderingContext,
@ -141,6 +266,7 @@ nsGfxRadioControlFrame::PaintRadioButton(nsIPresContext* aPresContext,
}
}
//--------------------------------------------------------------
NS_METHOD
nsGfxRadioControlFrame::Paint(nsIPresContext* aPresContext,
nsIRenderingContext& aRenderingContext,
@ -153,7 +279,7 @@ nsGfxRadioControlFrame::Paint(nsIPresContext* aPresContext,
return NS_OK;
// Paint the background
Inherited::Paint(aPresContext, aRenderingContext, aDirtyRect, aWhichLayer);
nsFormControlFrame::Paint(aPresContext, aRenderingContext, aDirtyRect, aWhichLayer);
if (NS_FRAME_PAINT_LAYER_FOREGROUND == aWhichLayer) {
PaintRadioButton(aPresContext, aRenderingContext, aDirtyRect);
@ -162,17 +288,79 @@ nsGfxRadioControlFrame::Paint(nsIPresContext* aPresContext,
}
//--------------------------------------------------------------
PRBool nsGfxRadioControlFrame::GetRadioState()
{
return mChecked;
}
//--------------------------------------------------------------
void nsGfxRadioControlFrame::SetRadioState(nsIPresContext* aPresContext, PRBool aValue)
{
mChecked = aValue;
nsFormControlHelper::ForceDrawFrame(aPresContext, this);
}
void
nsGfxRadioControlFrame::InitializeControl(nsIPresContext* aPresContext)
{
nsFormControlFrame::InitializeControl(aPresContext);
// set the widget to the initial state
PRBool checked = PR_FALSE;
nsresult result = GetDefaultCheckState(&checked);
if (NS_CONTENT_ATTR_HAS_VALUE == result) {
SetRadioState(aPresContext, checked);
}
}
//----------------------------------------------------------------------
// nsIStatefulFrame
//----------------------------------------------------------------------
NS_IMETHODIMP
nsGfxRadioControlFrame::GetStateType(nsIPresContext* aPresContext, nsIStatefulFrame::StateType* aStateType)
{
*aStateType = nsIStatefulFrame::eRadioType;
return NS_OK;
}
//----------------------------------------------------------------------
NS_IMETHODIMP
nsGfxRadioControlFrame::SaveState(nsIPresContext* aPresContext, nsIPresState** aState)
{
// Construct a pres state.
NS_NewPresState(aState); // The addref happens here.
// This string will hold a single item, whether or not we're checked.
nsAutoString stateString;
nsFormControlHelper::GetBoolString(GetRadioState(), stateString);
(*aState)->SetStateProperty("checked", stateString);
return NS_OK;
}
//----------------------------------------------------------------------
NS_IMETHODIMP
nsGfxRadioControlFrame::RestoreState(nsIPresContext* aPresContext, nsIPresState* aState)
{
if (!mDidInit) {
mPresContext = aPresContext;
InitializeControl(aPresContext);
mDidInit = PR_TRUE;
}
nsAutoString string;
aState->GetStateProperty("checked", string);
PRBool state = (string == NS_STRING_TRUE) ? PR_TRUE : PR_FALSE;
SetRadioState(aPresContext, state);
return NS_OK;
}
//----------------------------------------------------------------------
// Extra Debug Helper Methods
//----------------------------------------------------------------------
#ifdef DEBUG_rodsXXX
NS_IMETHODIMP
nsGfxRadioControlFrame::Reflow(nsIPresContext* aPresContext,

View File

@ -23,25 +23,36 @@
#ifndef nsGfxRadioControlFrame_h___
#define nsGfxRadioControlFrame_h___
#include "nsRadioControlFrame.h"
#include "nsFormControlFrame.h"
#include "nsIStatefulFrame.h"
#include "nsIRadioControlFrame.h"
// nsGfxRadioControlFrame
#define NS_GFX_RADIO_CONTROL_FRAME_FACE_CONTEXT_INDEX 0 // for additional style contexts
#define NS_GFX_RADIO_CONTROL_FRAME_LAST_CONTEXT_INDEX 0
class nsGfxRadioControlFrame : public nsRadioControlFrame
class nsGfxRadioControlFrame : public nsFormControlFrame,
public nsIStatefulFrame,
public nsIRadioControlFrame
{
private:
typedef nsRadioControlFrame Inherited;
public:
nsGfxRadioControlFrame();
~nsGfxRadioControlFrame();
//nsIRadioControlFrame methods
NS_IMETHOD QueryInterface(const nsIID& aIID, void** aInstancePtr);
NS_IMETHOD SetRadioButtonFaceStyleContext(nsIStyleContext *aRadioButtonFaceStyleContext);
virtual PRBool GetChecked(PRBool aGetInitialValue);
virtual void SetChecked(nsIPresContext* aPresContext, PRBool aValue, PRBool aSetInitialValue);
void InitializeControl(nsIPresContext* aPresContext);
NS_IMETHOD GetAdditionalStyleContext(PRInt32 aIndex,
nsIStyleContext** aStyleContext) const;
NS_IMETHOD SetAdditionalStyleContext(PRInt32 aIndex,
@ -67,6 +78,21 @@ public:
nsIRenderingContext& aRenderingContext,
const nsRect& aDirtyRect);
virtual PRInt32 GetMaxNumValues() { return 1; }
virtual PRBool GetNamesValues(PRInt32 aMaxNumValues, PRInt32& aNumValues,
nsString* aValues, nsString* aNames);
virtual void Reset(nsIPresContext* aPresContext);
// nsIFormControlFrame
NS_IMETHOD SetProperty(nsIPresContext* aPresContext, nsIAtom* aName, const nsString& aValue);
NS_IMETHOD GetProperty(nsIAtom* aName, nsString& aValue);
//nsIStatefulFrame
NS_IMETHOD GetStateType(nsIPresContext* aPresContext, nsIStatefulFrame::StateType* aStateType);
NS_IMETHOD SaveState(nsIPresContext* aPresContext, nsIPresState** aState);
NS_IMETHOD RestoreState(nsIPresContext* aPresContext, nsIPresState* aState);
///XXX: End o the temporary methods
#ifdef DEBUG_rodsXXX
NS_IMETHOD Reflow(nsIPresContext* aCX,

View File

@ -92,6 +92,7 @@ nsHTMLButtonControlFrame::nsHTMLButtonControlFrame()
nsHTMLButtonControlFrame::~nsHTMLButtonControlFrame()
{
nsFormControlFrame::RegUnRegAccessKey(mPresContext, NS_STATIC_CAST(nsIFrame*, this), PR_FALSE);
if (mFormFrame) {
mFormFrame->RemoveFormControlFrame(*this);
mFormFrame = nsnull;
@ -513,15 +514,18 @@ nsHTMLButtonControlFrame::Reflow(nsIPresContext* aPresContext,
nsReflowStatus& aStatus)
{
if (!mFormFrame && (eReflowReason_Initial == aReflowState.reason)) {
mPresContext = aPresContext;
nsFormControlFrame::RegUnRegAccessKey(aPresContext, NS_STATIC_CAST(nsIFrame*, this), PR_TRUE);
nsFormFrame::AddFormControlFrame(aPresContext, *NS_STATIC_CAST(nsIFrame*, this));
}
#if 0
nsresult skiprv = nsFormControlFrame::SkipResizeReflow(mCacheSize, mCachedMaxElementSize, aPresContext,
aDesiredSize, aReflowState, aStatus);
if (NS_SUCCEEDED(skiprv)) {
return skiprv;
}
#endif
// XXX remove the following when the reflow state is fixed
ButtonHack((nsHTMLReflowState&)aReflowState, "html4 button");
@ -662,10 +666,12 @@ nsHTMLButtonControlFrame::Reflow(nsIPresContext* aPresContext,
//aDesiredSize.width += aReflowState.mComputedBorderPadding.left + aReflowState.mComputedBorderPadding.right;
//aDesiredSize.height += aReflowState.mComputedBorderPadding.top + aReflowState.mComputedBorderPadding.bottom;
#if 1
//adjust our max element size, if necessary
if (aDesiredSize.maxElementSize) {
aDesiredSize.AddBorderPaddingToMaxElementSize(aReflowState.mComputedBorderPadding);
}
#endif
aDesiredSize.ascent = aDesiredSize.height;
aDesiredSize.descent = 0;
@ -684,11 +690,10 @@ nsHTMLButtonControlFrame::GetSkipSides() const
}
NS_IMETHODIMP
nsHTMLButtonControlFrame::GetFont(nsIPresContext* aPresContext,
const nsFont*& aFont)
nsHTMLButtonControlFrame::GetFont(nsIPresContext* aPresContext,
const nsFont*& aFont)
{
nsFormControlHelper::GetFont(this, aPresContext, mStyleContext, aFont);
return NS_OK;
return nsFormControlHelper::GetFont(this, aPresContext, mStyleContext, aFont);
}
NS_IMETHODIMP

View File

@ -156,6 +156,8 @@ protected:
PRBool mDidInit;
nsButtonFrameRenderer mRenderer;
nsCOMPtr<nsIPresContext> mPresContext;
//Resize Reflow OpitmizationSize;
nsSize mCacheSize;
nsSize mCachedMaxElementSize;

View File

@ -46,6 +46,7 @@
#include "nsIHTMLAttributes.h"
#include "nsGenericHTMLElement.h"
#include "nsFormFrame.h"
#include "nsFormControlFrame.h"
//Enumeration of possible mouse states used to detect mouse clicks
/*enum nsMouseState {
@ -145,6 +146,8 @@ protected:
nsCursor mPreviousCursor;
nsRect mTranslatedRect;
PRBool mGotFocus;
nsCOMPtr<nsIPresContext> mPresContext;
};
@ -160,6 +163,8 @@ nsImageControlFrame::nsImageControlFrame()
nsImageControlFrame::~nsImageControlFrame()
{
nsFormControlFrame::RegUnRegAccessKey(mPresContext, NS_STATIC_CAST(nsIFrame*, this), PR_FALSE);
if (mFormFrame) {
mFormFrame->RemoveFormControlFrame(*this);
mFormFrame = nsnull;
@ -255,6 +260,8 @@ nsImageControlFrame::Reflow(nsIPresContext* aPresContext,
nsReflowStatus& aStatus)
{
if (!mFormFrame && (eReflowReason_Initial == aReflowState.reason)) {
mPresContext = aPresContext;
nsFormControlFrame::RegUnRegAccessKey(aPresContext, NS_STATIC_CAST(nsIFrame*, this), PR_TRUE);
// add ourself as an nsIFormControlFrame
nsFormFrame::AddFormControlFrame(aPresContext, *NS_STATIC_CAST(nsIFrame*, this));
}

View File

@ -30,7 +30,6 @@
#include "nsIFrame.h"
#include "nsISupports.h"
#include "nsIAtom.h"
#include "nsIPresContext.h"
#include "nsIHTMLContent.h"
#include "nsHTMLIIDs.h"
#include "nsHTMLParts.h"
@ -39,6 +38,7 @@
#include "nsStyleConsts.h"
#include "nsStyleUtil.h"
#include "nsFont.h"
#include "nsFormControlFrame.h"
static NS_DEFINE_IID(kLegendFrameCID, NS_LEGEND_FRAME_CID);
static NS_DEFINE_IID(kIDOMHTMLLegendElementIID, NS_IDOMHTMLLEGENDELEMENT_IID);
@ -63,6 +63,11 @@ nsLegendFrame::nsLegendFrame()
{
}
nsLegendFrame::~nsLegendFrame()
{
nsFormControlFrame::RegUnRegAccessKey(mPresContext, NS_STATIC_CAST(nsIFrame*, this), PR_FALSE);
}
// Frames are not refcounted, no need to AddRef
NS_IMETHODIMP
nsLegendFrame::QueryInterface(REFNSIID aIID, void** aInstancePtrResult)
@ -78,6 +83,20 @@ nsLegendFrame::QueryInterface(REFNSIID aIID, void** aInstancePtrResult)
return nsHTMLContainerFrame::QueryInterface(aIID, aInstancePtrResult);
}
NS_IMETHODIMP
nsLegendFrame::Reflow(nsIPresContext* aPresContext,
nsHTMLReflowMetrics& aDesiredSize,
const nsHTMLReflowState& aReflowState,
nsReflowStatus& aStatus)
{
if (eReflowReason_Initial == aReflowState.reason) {
mPresContext = aPresContext;
nsFormControlFrame::RegUnRegAccessKey(aPresContext, NS_STATIC_CAST(nsIFrame*, this), PR_TRUE);
}
return nsAreaFrame::Reflow(aPresContext, aDesiredSize, aReflowState, aStatus);
}
PRInt32 nsLegendFrame::GetAlign()
{
PRInt32 intValue = NS_STYLE_TEXT_ALIGN_LEFT;

View File

@ -24,6 +24,9 @@
#define nsLegendFrame_h___
#include "nsAreaFrame.h"
#include "nsIPresContext.h"
#include "nsCOMPtr.h"
class nsIContent;
class nsIFrame;
class nsIPresContext;
@ -38,14 +41,23 @@ class nsLegendFrame : public nsAreaFrame {
public:
nsLegendFrame();
virtual ~nsLegendFrame();
NS_IMETHOD QueryInterface(const nsIID& aIID, void** aInstancePtr);
NS_IMETHOD Reflow(nsIPresContext* aPresContext,
nsHTMLReflowMetrics& aDesiredSize,
const nsHTMLReflowState& aReflowState,
nsReflowStatus& aStatus);
#ifdef NS_DEBUG
NS_IMETHOD GetFrameName(nsString& aResult) const;
#endif
PRInt32 GetAlign();
nsCOMPtr<nsIPresContext> mPresContext;
};

View File

@ -123,6 +123,8 @@ nsListControlFrame::nsListControlFrame()
//---------------------------------------------------------
nsListControlFrame::~nsListControlFrame()
{
nsFormControlFrame::RegUnRegAccessKey(mPresContext, NS_STATIC_CAST(nsIFrame*, this), PR_FALSE);
// if list is dropped down
// make sure it gets rolled up
if (IsInDropDownMode()) {
@ -286,7 +288,7 @@ nsListControlFrame::Reflow(nsIPresContext* aPresContext,
const nsHTMLReflowState& aReflowState,
nsReflowStatus& aStatus)
{
#ifdef DEBUG_rodsXXX
#ifdef DEBUG_rods
printf("nsListControlFrame::Reflow Reason: ");
switch (aReflowState.reason) {
case eReflowReason_Initial:printf("eReflowReason_Initial\n");break;
@ -355,6 +357,7 @@ nsListControlFrame::Reflow(nsIPresContext* aPresContext,
mHasBeenInitialized = PR_TRUE;
InitSelectionCache(-1); // Reset sel cache so as not to send event
Reset(mPresContext);
#if 1
nsCOMPtr<nsIReflowCommand> cmd;
nsresult rv = NS_NewHTMLReflowCommand(getter_AddRefs(cmd), this, nsIReflowCommand::StyleChanged);
if (NS_FAILED(rv)) { return rv; }
@ -368,10 +371,18 @@ nsListControlFrame::Reflow(nsIPresContext* aPresContext,
rv = shell->AppendReflowCommand(cmd);
// must do this next line regardless of result of AppendReflowCommand
shell->ExitReflowLock(PR_TRUE);
#else
if (mParent) {
nsCOMPtr<nsIPresShell> shell;
nsresult rv = mPresContext->GetShell(getter_AddRefs(shell));
mState |= NS_FRAME_IS_DIRTY;
mParent->ReflowDirtyChild(shell, (nsIFrame*) this);
}
#endif
}
}
#if 1
#if 0
nsresult skiprv = nsFormControlFrame::SkipResizeReflow(mCacheSize, mCachedMaxElementSize, aPresContext,
aDesiredSize, aReflowState, aStatus);
if (NS_SUCCEEDED(skiprv)) {
@ -416,6 +427,7 @@ nsListControlFrame::Reflow(nsIPresContext* aPresContext,
// Add the list frame as a child of the form
if (IsInDropDownMode() == PR_FALSE && !mFormFrame && (eReflowReason_Initial == aReflowState.reason)) {
nsFormControlFrame::RegUnRegAccessKey(aPresContext, NS_STATIC_CAST(nsIFrame*, this), PR_TRUE);
nsFormFrame::AddFormControlFrame(aPresContext, *NS_STATIC_CAST(nsIFrame*, this));
}
@ -1943,6 +1955,17 @@ nsListControlFrame::AddOption(nsIPresContext* aPresContext, PRInt32 aIndex)
Reset(aPresContext); // this sets mSelectedIndex to the defaulted selection
wasReset = PR_TRUE;
}
#if DEBUG_rods
{
nsAutoString text = "No Value";
nsresult rv = option->GetLabel(text);
if (NS_CONTENT_ATTR_NOT_THERE == rv || 0 == text.Length()) {
option->GetText(text);
}
printf("this %p Index: %d [%s] CB: %p\n", this, aIndex, text.ToNewCString(), mComboboxFrame); //leaks
}
#endif
}
}
@ -2468,6 +2491,30 @@ void nsListControlFrame::ResetSelectedItem()
}
}
//----------------------------------------------------------------------
// helper
//----------------------------------------------------------------------
PRBool
nsListControlFrame::IsLeftButton(nsIDOMEvent* aMouseEvent)
{
// only allow selection with the left button
nsCOMPtr<nsIDOMMouseEvent> mouseEvent = do_QueryInterface(aMouseEvent);
if (mouseEvent) {
PRUint16 whichButton;
if (NS_SUCCEEDED(mouseEvent->GetButton(&whichButton))) {
if (whichButton != 1) {
aMouseEvent->PreventDefault();
aMouseEvent->PreventCapture();
aMouseEvent->PreventBubble();
return PR_FALSE;
} else {
return PR_TRUE;
}
}
}
return PR_FALSE;
}
//----------------------------------------------------------------------
// nsIDOMMouseListener
//----------------------------------------------------------------------
@ -2479,6 +2526,11 @@ nsListControlFrame::MouseUp(nsIDOMEvent* aMouseEvent)
return NS_OK;
}
// only allow selection with the left button
if (!IsLeftButton(aMouseEvent)) {
return NS_ERROR_FAILURE; // means consume event
}
// Check to see if the disabled option was clicked on
// NS_ERROR_FAILURE is returned is it isn't over an option
PRBool optionIsDisabled;
@ -2512,7 +2564,11 @@ nsListControlFrame::MouseUp(nsIDOMEvent* aMouseEvent)
UpdateSelection(PR_TRUE, PR_FALSE, mContent);
}
return NS_OK;
aMouseEvent->PreventDefault();
aMouseEvent->PreventCapture();
aMouseEvent->PreventBubble();
return NS_ERROR_FAILURE;
//return NS_OK;
}
//---------------------------------------------------------
@ -2579,6 +2635,11 @@ nsListControlFrame::MouseDown(nsIDOMEvent* aMouseEvent)
return NS_OK;
}
// only allow selection with the left button
if (!IsLeftButton(aMouseEvent)) {
return NS_ERROR_FAILURE; // means consume event
}
// Check to see if the disabled option was clicked on
// NS_ERROR_FAILURE is returned is it isn't over an option
PRBool optionIsDisabled;
@ -2673,7 +2734,11 @@ nsListControlFrame::MouseDown(nsIDOMEvent* aMouseEvent)
}
}
}
return NS_OK;
aMouseEvent->PreventDefault();
aMouseEvent->PreventCapture();
aMouseEvent->PreventBubble();
return NS_ERROR_FAILURE; //consumes event
//return NS_OK;
}
//----------------------------------------------------------------------

View File

@ -217,6 +217,7 @@ protected:
PRBool HasSameContent(nsIFrame* aFrame1, nsIFrame* aFrame2);
void HandleListSelection(nsIDOMEvent * aDOMEvent);
PRInt32 GetSelectedIndexFromFrame(nsIFrame *aHitFrame);
PRBool IsLeftButton(nsIDOMEvent* aMouseEvent);
// onChange detection
nsresult InitSelectionCache(PRInt32 aLength);

View File

@ -30,7 +30,6 @@
#include "nsIHTMLContent.h"
#include "nsHTMLIIDs.h"
#include "nsITextWidget.h"
#include "nsITextAreaWidget.h"
#include "nsWidgetsCID.h"
#include "nsSize.h"
#include "nsString.h"

View File

@ -34,13 +34,8 @@ CPPSRCS= \
nsListControlFrame.cpp \
nsFormFrame.cpp \
nsFormControlFrame.cpp \
nsButtonControlFrame.cpp \
nsCheckboxControlFrame.cpp \
nsFileControlFrame.cpp \
nsRadioControlFrame.cpp \
nsTextControlFrame.cpp \
nsGfxTextControlFrame.cpp \
nsTextControlFrame.cpp \
nsFieldSetFrame.cpp \
nsLegendFrame.cpp \
nsHTMLButtonControlFrame.cpp \
@ -51,7 +46,6 @@ CPPSRCS= \
nsGfxCheckboxControlFrame.cpp \
nsGfxRadioControlFrame.cpp \
nsGfxAutoTextControlFrame.cpp \
nsNativeFormControlFrame.cpp \
nsRadioControlGroup.cpp
CPP_OBJS= \
@ -61,11 +55,7 @@ CPP_OBJS= \
.\$(OBJDIR)\nsListControlFrame.obj \
.\$(OBJDIR)\nsFormFrame.obj \
.\$(OBJDIR)\nsFormControlFrame.obj \
.\$(OBJDIR)\nsButtonControlFrame.obj \
.\$(OBJDIR)\nsCheckboxControlFrame.obj \
.\$(OBJDIR)\nsFileControlFrame.obj \
.\$(OBJDIR)\nsRadioControlFrame.obj \
.\$(OBJDIR)\nsTextControlFrame.obj \
.\$(OBJDIR)\nsGfxTextControlFrame.obj \
.\$(OBJDIR)\nsFieldSetFrame.obj \
.\$(OBJDIR)\nsLegendFrame.obj \
@ -77,7 +67,6 @@ CPP_OBJS= \
.\$(OBJDIR)\nsGfxCheckboxControlFrame.obj \
.\$(OBJDIR)\nsGfxRadioControlFrame.obj \
.\$(OBJDIR)\nsGfxAutoTextControlFrame.obj \
.\$(OBJDIR)\nsNativeFormControlFrame.obj \
.\$(OBJDIR)\nsRadioControlGroup.obj

View File

@ -22,7 +22,7 @@
#ifndef nsCheckboxControlFrame_h___
#define nsCheckboxControlFrame_h___
#include "nsNativeFormControlFrame.h"
#include "nsFormControlFrame.h"
#include "nsIStatefulFrame.h"
class nsIPresState;
@ -47,7 +47,7 @@ class nsIPresState;
// become checked since "mixed" doesn't exist on normal checkboxes.
//
class nsCheckboxControlFrame : public nsNativeFormControlFrame,
class nsCheckboxControlFrame : public nsFormControlFrame,
public nsIStatefulFrame
{
public:

View File

@ -132,6 +132,8 @@ nsComboboxControlFrame::~nsComboboxControlFrame()
NS_IF_RELEASE(mPresContext);
NS_IF_RELEASE(mDisplayContent);
NS_IF_RELEASE(mButtonContent);
nsFormControlFrame::RegUnRegAccessKey(mPresContext, NS_STATIC_CAST(nsIFrame*, this), PR_FALSE);
}
//--------------------------------------------------------------
@ -265,9 +267,7 @@ nsComboboxControlFrame::Reset(nsIPresContext* aPresContext)
}
void
nsComboboxControlFrame::PostCreateWidget(nsIPresContext* aPresContext,
nscoord& aWidth,
nscoord& aHeight)
nsComboboxControlFrame::InitializeControl(nsIPresContext* aPresContext)
{
Reset(aPresContext);
}
@ -724,6 +724,7 @@ nsComboboxControlFrame::Reflow(nsIPresContext* aPresContext,
if (!mFormFrame && (eReflowReason_Initial == aReflowState.reason)) {
nsFormControlFrame::RegUnRegAccessKey(aPresContext, NS_STATIC_CAST(nsIFrame*, this), PR_TRUE);
nsFormFrame::AddFormControlFrame(aPresContext, *NS_STATIC_CAST(nsIFrame*,this));
}
@ -912,6 +913,7 @@ nsComboboxControlFrame::Reflow(nsIPresContext* aPresContext,
#else // DO_OLD_REFLOW
#ifdef DEBUG_rods
nsComboboxControlFrame * pCB = nsnull;
static int myCounter = 0;
#endif
@ -922,7 +924,8 @@ nsComboboxControlFrame::Reflow(nsIPresContext* aPresContext,
nsReflowStatus& aStatus)
{
#ifdef DEBUG_rods
printf("****** nsComboboxControlFrame::Reflow %d Reason: ", myCounter++);
//if (pCB) {
printf("%p ****** nsComboboxControlFrame::Reflow %d Reason: ", this, myCounter++);
switch (aReflowState.reason) {
case eReflowReason_Initial:
printf("eReflowReason_Initial\n");break;
@ -933,6 +936,7 @@ nsComboboxControlFrame::Reflow(nsIPresContext* aPresContext,
break;
case eReflowReason_StyleChange:printf("eReflowReason_StyleChange\n");break;
}
//}
#endif
#if 0
@ -993,7 +997,9 @@ nsComboboxControlFrame::Reflow(nsIPresContext* aPresContext,
// but it does seems to go into this code.
} else {
if (targetFrame != dropdownFrame) {
#ifdef DEBUG_rods
printf("+++++++++++++++++++++++\n");
#endif
rv = nsAreaFrame::Reflow(aPresContext, aDesiredSize, aReflowState, aStatus);
displayFrame->GetRect(displayRect);
buttonFrame->GetRect(buttonRect);
@ -1001,14 +1007,34 @@ nsComboboxControlFrame::Reflow(nsIPresContext* aPresContext,
buttonRect.height = displayRect.height;
buttonFrame->SetRect(aPresContext, buttonRect);
aStatus = NS_FRAME_COMPLETE;
#ifdef DEBUG_rods
printf("--> W: %d H: %d\n", aDesiredSize.width, aDesiredSize.height);
#endif
return rv;
} else {
#if 0
nsRect dropdownRect;
dropdownFrame->GetRect(dropdownRect);
nsHTMLReflowMetrics dropdownDesiredSize(aDesiredSize);
ReflowComboChildFrame(dropdownFrame, aPresContext, dropdownDesiredSize, firstPassState,
aStatus, firstPassState.availableWidth, firstPassState.availableHeight);
return NS_OK;
aStatus, dropdownRect.width, dropdownRect.height);
nsCOMPtr<nsIStyleContext> context;
targetFrame->GetStyleContext(getter_AddRefs(context));
const nsStyleDisplay* disp = (const nsStyleDisplay*)context->GetStyleData(eStyleStruct_Display);
printf("IsVisible %s\n", disp->mVisible == NS_STYLE_VISIBILITY_VISIBLE?"yes":"No");
//if (disp->mVisible == NS_STYLE_VISIBILITY_VISIBLE) {
nsRect rect;
GetRect(rect);
aDesiredSize.width = rect.width;// + borderPadding.left + borderPadding.right;
aDesiredSize.height = rect.height;// + borderPadding.top + borderPadding.bottom;
aDesiredSize.ascent = aDesiredSize.height;
aDesiredSize.descent = 0;
dropdownRect.width = rect.width;
dropdownFrame->SetRect(aPresContext, dropdownRect);
printf("Skipping out..........................");
aStatus = NS_FRAME_COMPLETE;
return NS_OK;
//}
#endif
}
}
@ -1035,10 +1061,15 @@ nsComboboxControlFrame::Reflow(nsIPresContext* aPresContext,
dx->GetCanonicalPixelScale(scale);
scrollbarWidth = NSIntPixelsToTwips(info.mSize, p2t*scale);
}
#ifdef DEBUG_rods
printf("UNC %d AV %d \n", firstPassState.mComputedWidth,firstPassState.availableWidth);
#endif
//Set the desired size for the button and display frame
if (NS_UNCONSTRAINEDSIZE == firstPassState.mComputedWidth) {
#ifdef DEBUG_rods
printf("=====================================\n");
#endif
// A width has not been specified for the select so size the display area to
// match the width of the longest item in the drop-down list. The dropdown
// list has already been reflowed and sized to shrink around its contents above.
@ -1077,7 +1108,9 @@ nsComboboxControlFrame::Reflow(nsIPresContext* aPresContext,
dspBorderPadding.SizeTo(0, 0, 0, 0);
dspSpacing->CalcBorderPaddingFor(displayFrame, dspBorderPadding);
#ifdef DEBUG_rods
printf("W: %d\n", dropdownRect.width-size.width+dspBorderPadding.left+dspBorderPadding.right);
#endif
// Set width of display to match width of the drop down
SetChildFrameSize(displayFrame, dropdownRect.width-size.width+dspBorderPadding.left+dspBorderPadding.right,
size.height+dspBorderPadding.top+dspBorderPadding.bottom);
@ -1103,7 +1136,9 @@ nsComboboxControlFrame::Reflow(nsIPresContext* aPresContext,
}
} else {
#ifdef DEBUG_rods
printf("*************************************\n");
#endif
// for debug -------
PRInt32 length = 0;
mListControlFrame->GetNumberOfOptions(&length);
@ -1129,7 +1164,9 @@ nsComboboxControlFrame::Reflow(nsIPresContext* aPresContext,
// nsAreaFrame::Reflow adds in the border and padding so we need to remove it
//displayWidth -= borderPadding.left + borderPadding.right;
#ifdef DEBUG_rods
printf("WW: %d\n", displayWidth);
#endif
// Set the displayFrame to match the displayWidth computed above
if (displayWidth >= 0) {
SetChildFrameSize(displayFrame, displayWidth, size.height);
@ -1146,7 +1183,9 @@ nsComboboxControlFrame::Reflow(nsIPresContext* aPresContext,
buttonRect.height = displayRect.height;
buttonFrame->SetRect(aPresContext, buttonRect);
displayFrame->SetRect(aPresContext, displayRect);
#ifdef DEBUG_rods
printf("DW: %d\n", aDesiredSize.width);
#endif
// nsAreaFrame::Reflow adds in the border and padding so we need to remove it
// XXX rods - this hould not be subtracted in
//aDesiredSize.width += borderPadding.left + borderPadding.right;
@ -1156,6 +1195,8 @@ nsComboboxControlFrame::Reflow(nsIPresContext* aPresContext,
}
aDesiredSize.width = firstPassState.mComputedWidth + borderPadding.left + borderPadding.right;
aDesiredSize.height = firstPassState.mComputedHeight + borderPadding.top + borderPadding.bottom;
aDesiredSize.ascent = aDesiredSize.height;
aDesiredSize.descent = 0;
}
// Set the max element size to be the same as the desired element size.
@ -1164,18 +1205,15 @@ nsComboboxControlFrame::Reflow(nsIPresContext* aPresContext,
aDesiredSize.maxElementSize->height = aDesiredSize.height;
}
nsRect absoluteTwips;
nsRect absolutePixels;
GetAbsoluteFramePosition(aPresContext, this, absoluteTwips, absolutePixels);
PositionDropdown(aPresContext, aDesiredSize.height, absoluteTwips, absolutePixels);
aStatus = NS_FRAME_COMPLETE;
#if 0
COMPARE_QUIRK_SIZE("nsComboboxControlFrame", 127, 22)
#endif
nsFormControlFrame::SetupCachedSizes(mCacheSize, mCachedMaxElementSize, aDesiredSize);
#ifdef DEBUG_rods
printf("--> W: %d H: %d\n", aDesiredSize.width, aDesiredSize.height);
#endif
return rv;
}
@ -1422,6 +1460,7 @@ nsComboboxControlFrame::SelectionChanged()
}
if (shouldSetValue) {
rv = htmlContent->SetHTMLAttribute(nsHTMLAtoms::value, mTextStr, PR_TRUE);
#if 1
if (NS_SUCCEEDED(rv)) {
nsIFrame* displayFrame = GetDisplayFrame(mPresContext);
@ -1439,6 +1478,15 @@ nsComboboxControlFrame::SelectionChanged()
NS_RELEASE(cmd);
}
}
#else
if (mParent) {
nsCOMPtr<nsIPresShell> shell;
rv = mPresContext->GetShell(getter_AddRefs(shell));
mState |= NS_FRAME_IS_DIRTY;
mParent->ReflowDirtyChild(shell, (nsIFrame*) this);
}
#endif
}
}
}
@ -1467,12 +1515,19 @@ nsComboboxControlFrame::DoneAddingContent(PRBool aIsDone)
NS_IMETHODIMP
nsComboboxControlFrame::AddOption(nsIPresContext* aPresContext, PRInt32 aIndex)
{
#ifdef DEBUG_rodsXXX
if (!pCB) pCB = this;
#endif
nsISelectControlFrame* listFrame = nsnull;
nsIFrame* dropdownFrame = GetDropdownFrame();
nsresult rv = dropdownFrame->QueryInterface(NS_GET_IID(nsISelectControlFrame),
(void**)&listFrame);
if (NS_SUCCEEDED(rv) && listFrame) {
rv = listFrame->AddOption(aPresContext, aIndex);
PRInt32 index;
mListControlFrame->GetSelectedIndex(&index);
UpdateSelection(PR_FALSE, PR_TRUE, index);
NS_RELEASE(listFrame);
}
// If we added the first option, we might need to select it.

View File

@ -35,8 +35,6 @@
#include "nsIRollupListener.h"
#include "nsIPresState.h"
class nsButtonControlFrame;
class nsTextControlFrame;
class nsFormFrame;
class nsIView;
class nsStyleContext;
@ -109,9 +107,7 @@ public:
NS_IMETHOD GetProperty(nsIAtom* aName, nsString& aValue);
void SetFocus(PRBool aOn, PRBool aRepaint);
void ScrollIntoView(nsIPresContext* aPresContext);
virtual void PostCreateWidget(nsIPresContext* aPresContext,
nscoord& aWidth,
nscoord& aHeight);
virtual void InitializeControl(nsIPresContext* aPresContext);
virtual PRBool IsSuccessful(nsIFormControlFrame* aSubmitter);
virtual void SetFormFrame(nsFormFrame* aFormFrame) { mFormFrame = aFormFrame; }
virtual void Reset(nsIPresContext* aPresContext);

View File

@ -22,9 +22,7 @@
#include "nsFileControlFrame.h"
#include "nsFormFrame.h"
#include "nsButtonControlFrame.h"
#include "nsTextControlFrame.h"
#include "nsNativeTextControlFrame.h" // XXX: remove when frame construction is done properly
#include "nsGfxTextControlFrame.h"
#include "nsIContent.h"
#include "prtypes.h"
#include "nsIAtom.h"
@ -312,7 +310,7 @@ nsFileControlFrame::SetInitialChildList(nsIPresContext* aPresContext,
* frame constuctor create the frame and its implementation. So we are given the text
* node from the constructor and we find it in our tree.
*/
nsTextControlFrame*
nsGfxTextControlFrame*
nsFileControlFrame::GetTextControlFrame(nsIPresContext* aPresContext, nsIFrame* aStart)
{
// find the text control frame.
@ -331,13 +329,13 @@ nsFileControlFrame::GetTextControlFrame(nsIPresContext* aPresContext, nsIFrame*
value.ToUpperCase();
nsString txt("TEXT");
if (value == txt) {
return (nsTextControlFrame*)childFrame;
return (nsGfxTextControlFrame*)childFrame;
}
}
}
// if not continue looking
nsTextControlFrame* frame = GetTextControlFrame(aPresContext, childFrame);
nsGfxTextControlFrame* frame = GetTextControlFrame(aPresContext, childFrame);
if (frame)
return frame;

View File

@ -30,8 +30,7 @@
#include "nsIStatefulFrame.h"
class nsIPresState;
class nsButtonControlFrame;
class nsTextControlFrame;
class nsGfxTextControlFrame;
class nsFormFrame;
class nsISupportsArray;
class nsIHTMLContent;
@ -176,7 +175,7 @@ protected:
virtual PRIntn GetSkipSides() const;
nsTextControlFrame* mTextFrame;
nsGfxTextControlFrame* mTextFrame;
nsFormFrame* mFormFrame;
nsIHTMLContent* mTextContent;
nsString* mCachedState;
@ -184,7 +183,7 @@ protected:
nsIPresContext* mPresContext; // weak reference
private:
nsTextControlFrame* GetTextControlFrame(nsIPresContext* aPresContext,
nsGfxTextControlFrame* GetTextControlFrame(nsIPresContext* aPresContext,
nsIFrame* aStart);
NS_IMETHOD_(nsrefcnt) AddRef() { return NS_OK; }

View File

@ -54,6 +54,11 @@
#include "nsStyleUtil.h"
#include "nsINameSpaceManager.h"
#include "nsIDOMHTMLInputElement.h"
#include "nsIDOMHTMLLabelElement.h"
#include "nsIDOMHTMLTextAreaElement.h"
#include "nsIDOMHTMLLegendElement.h"
#include "nsIDOMHTMLButtonElement.h"
#include "nsIEventStateManager.h"
static NS_DEFINE_IID(kIWidgetIID, NS_IWIDGET_IID);
@ -87,6 +92,7 @@ nsFormControlFrame::~nsFormControlFrame()
mFormFrame->RemoveRadioControlFrame(this);
mFormFrame = nsnull;
}
RegUnRegAccessKey(mPresContext, NS_STATIC_CAST(nsIFrame*, this), PR_FALSE);
}
// Frames are not refcounted, no need to AddRef
@ -302,42 +308,29 @@ nsFormControlFrame::Reflow(nsIPresContext* aPresContext,
const nsHTMLReflowState& aReflowState,
nsReflowStatus& aStatus)
{
if (!mDidInit) {
mPresContext = aPresContext;
InitializeControl(aPresContext);
mDidInit = PR_TRUE;
}
// add ourself as an nsIFormControlFrame
if (!mFormFrame && (eReflowReason_Initial == aReflowState.reason)) {
nsFormFrame::AddFormControlFrame(aPresContext, *NS_STATIC_CAST(nsIFrame*, this));
}
nsresult skiprv = SkipResizeReflow(mCacheSize, mCachedMaxElementSize, aPresContext,
aDesiredSize, aReflowState, aStatus);
if (NS_SUCCEEDED(skiprv)) {
return skiprv;
}
nsWidgetRendering mode;
aPresContext->GetWidgetRenderingMode(&mode);
if (eWidgetRendering_Native == mode) {
GetDesiredSize(aPresContext, aReflowState, aDesiredSize, mWidgetSize);
if (!mDidInit) {
PostCreateWidget(aPresContext, aDesiredSize.width, aDesiredSize.height);
mDidInit = PR_TRUE;
}
aDesiredSize.ascent = aDesiredSize.height;
aDesiredSize.descent = 0;
} else {
nsresult rv = nsLeafFrame::Reflow(aPresContext, aDesiredSize, aReflowState, aStatus);
if (!mDidInit) {
//GetDesiredSize(aPresContext, aReflowState, aDesiredSize);
PostCreateWidget(aPresContext, aDesiredSize.width, aDesiredSize.height);
mDidInit = PR_TRUE;
}
return rv;
}
nsresult rv = nsLeafFrame::Reflow(aPresContext, aDesiredSize, aReflowState, aStatus);
aStatus = NS_FRAME_COMPLETE;
SetupCachedSizes(mCacheSize, mCachedMaxElementSize, aDesiredSize);
return NS_OK;
return rv;
}
@ -347,9 +340,72 @@ nsFormControlFrame::GetWidgetInitData(nsIPresContext* aPresContext)
return nsnull;
}
void
nsFormControlFrame::PostCreateWidget(nsIPresContext* aPresContext, nscoord& aWidth, nscoord& aHeight)
nsresult
nsFormControlFrame::RegUnRegAccessKey(nsIPresContext* aPresContext, nsIFrame * aFrame, PRBool aDoReg)
{
#if 0
NS_ASSERTION(aPresContext, "aPresContext is NULL in RegUnRegAccessKey!");
NS_ASSERTION(aFrame, "aFrame is NULL in RegUnRegAccessKey!");
nsresult rv = NS_ERROR_FAILURE;
nsAutoString accessKey;
if (aFrame != nsnull) {
nsCOMPtr<nsIContent> content;
if (NS_SUCCEEDED(aFrame->GetContent(getter_AddRefs(content)))) {
#if 1
PRInt32 nameSpaceID;
content->GetNameSpaceID(nameSpaceID);
nsAutoString resultValue;
rv = content->GetAttribute(nameSpaceID, nsHTMLAtoms::accesskey, accessKey);
#else
nsCOMPtr<nsIDOMHTMLInputElement> inputElement(do_QueryInterface(content));
if (inputElement) {
rv = inputElement->GetAccessKey(accessKey);
} else {
nsCOMPtr<nsIDOMHTMLTextAreaElement> textarea(do_QueryInterface(content));
if (textarea) {
rv = textarea->GetAccessKey(accessKey);
} else {
nsCOMPtr<nsIDOMHTMLLabelElement> label(do_QueryInterface(content));
if (label) {
rv = label->GetAccessKey(accessKey);
} else {
nsCOMPtr<nsIDOMHTMLLegendElement> legend(do_QueryInterface(content));
if (legend) {
rv = legend->GetAccessKey(accessKey);
} else {
nsCOMPtr<nsIDOMHTMLButtonElement> btn(do_QueryInterface(content));
if (btn) {
rv = btn->GetAccessKey(accessKey);
}
}
}
}
}
#endif
}
}
if (NS_CONTENT_ATTR_NOT_THERE != rv) {
nsCOMPtr<nsIEventStateManager> stateManager;
if (NS_SUCCEEDED(aPresContext->GetEventStateManager(getter_AddRefs(stateManager)))) {
if (aDoReg) {
return stateManager->RegisterAccessKey(aFrame, (PRUint32)accessKey.First());
} else {
return stateManager->UnregisterAccessKey(aFrame);
}
}
}
#endif
return NS_ERROR_FAILURE;
}
void
nsFormControlFrame::InitializeControl(nsIPresContext* aPresContext)
{
RegUnRegAccessKey(aPresContext, NS_STATIC_CAST(nsIFrame*, this), PR_TRUE);
}
void

View File

@ -31,11 +31,14 @@
#include "nsLeafFrame.h"
#include "nsCoord.h"
#include "nsIStyleContext.h"
#include "nsIPresContext.h"
#include "nsCOMPtr.h"
class nsIView;
class nsIPresContext;
class nsStyleCoord;
class nsFormFrame;
class nsIFocusableContent;
#define CSS_NOTSET -1
#define ATTR_NOTSET -1
@ -152,11 +155,9 @@ public:
virtual void ControlChanged(nsIPresContext* aPresContext) {}
/**
* Perform opertations after the widget associated with this frame has been
* created.
* Chance to Initialize to a defualt value
*/
virtual void PostCreateWidget(nsIPresContext* aPresContext,
nscoord& aWidth, nscoord& aHeight);
virtual void InitializeControl(nsIPresContext* aPresContext);
virtual void SetFocus(PRBool aOn = PR_TRUE, PRBool aRepaint = PR_FALSE);
virtual void ScrollIntoView(nsIPresContext* aPresContext);
@ -221,6 +222,8 @@ public:
nsHTMLReflowMetrics& aDesiredSize,
const nsHTMLReflowState& aReflowState,
nsReflowStatus& aStatus);
// AccessKey Helper function
static nsresult RegUnRegAccessKey(nsIPresContext* aPresContext, nsIFrame * aFrame, PRBool aDoReg);
protected:
@ -301,6 +304,8 @@ protected:
nscoord mSuggestedWidth;
nscoord mSuggestedHeight;
nsCOMPtr<nsIPresContext> mPresContext;
// Reflow Optimization
nsSize mCacheSize;
nsSize mCachedMaxElementSize;

View File

@ -453,7 +453,7 @@ nsFormControlHelper::CalculateSize (nsIPresContext* aPresContext,
// need to set charWidth and aDesiredSize.height
charWidth = GetTextSize(aPresContext, aFrame, 1, aDesiredSize, aRendContext);
col = (col <= 0) ? 15 : col; // XXX why a default of 15 pixels, why hide it
// XXX this conflicts with a default of 20 found in nsTextControlFrame.
// XXX this conflicts with a default of 20 found in nsGfxTextControlFrame.
aDesiredSize.width = NSIntPixelsToTwips(col, p2t);
} else {
col = (col <= 0) ? 1 : col; // XXX why a default of 1 char, why hide it

View File

@ -66,8 +66,7 @@
static NS_DEFINE_CID(kIOServiceCID, NS_IOSERVICE_CID);
#include "nsIDocument.h"
#include "nsILinkHandler.h"
#include "nsRadioControlFrame.h"
#include "nsIRadioButton.h"
#include "nsGfxRadioControlFrame.h"
#include "nsDocument.h"
#include "nsIDOMHTMLFormElement.h"
#include "nsIDOMNSHTMLFormElement.h"
@ -84,6 +83,7 @@ static NS_DEFINE_CID(kIOServiceCID, NS_IOSERVICE_CID);
// Get base target for submission
#include "nsIHTMLContent.h"
#include "nsIDOMHTMLInputElement.h"
#include "net.h"
#include "xp_file.h"
@ -333,6 +333,32 @@ void nsFormFrame::RemoveFormControlFrame(nsIFormControlFrame& aFrame)
mFormControls.RemoveElement(&aFrame);
}
NS_IMETHODIMP
nsFormFrame::RemoveFrame(nsIPresContext* aPresContext,
nsIPresShell& aPresShell,
nsIAtom* aListName,
nsIFrame* aOldFrame)
{
nsresult rv = NS_OK;
nsIFormControlFrame* fcFrame = nsnull;
nsresult result = aOldFrame->QueryInterface(kIFormControlFrameIID, (void**)&fcFrame);
if ((NS_OK == result) || (nsnull != fcFrame)) {
PRInt32 type;
fcFrame->GetType(&type);
if (NS_FORM_INPUT_RADIO == type) {
nsRadioControlGroup * group;
nsAutoString name;
nsresult rv = GetRadioInfo(fcFrame, name, group);
if (NS_SUCCEEDED(rv) && nsnull != group) {
DoDefaultSelection(aPresContext, group, (nsGfxRadioControlFrame*)fcFrame);
}
}
}
return nsBlockFrame::RemoveFrame(aPresContext, aPresShell, aListName, aOldFrame);
}
nsresult nsFormFrame::GetRadioInfo(nsIFormControlFrame* aFrame,
nsString& aName,
nsRadioControlGroup *& aGroup)
@ -359,6 +385,57 @@ nsresult nsFormFrame::GetRadioInfo(nsIFormControlFrame* aFrame,
return NS_ERROR_FAILURE;
}
void nsFormFrame::DoDefaultSelection(nsIPresContext* aPresContext,
nsRadioControlGroup * aGroup,
nsGfxRadioControlFrame * aRadioToIgnore)
{
// If in standard mode, then a radio group MUST default
// to the first item in the group (it must be selected)
nsCompatibility mode;
aPresContext->GetCompatibilityMode(&mode);
if (eCompatibility_Standard == mode) {
// first find out if any have a default selection
PRInt32 i;
PRInt32 numItems = aGroup->GetNumRadios();
PRBool oneIsSelected = PR_FALSE;
for (i=0;i<numItems && !oneIsSelected;i++) {
nsGfxRadioControlFrame * radioBtn = (nsGfxRadioControlFrame*) aGroup->GetRadioAt(i);
nsCOMPtr<nsIContent> content;
radioBtn->GetContent(getter_AddRefs(content));
if (content) {
nsCOMPtr<nsIDOMHTMLInputElement> input(do_QueryInterface(content));
if (input) {
input->GetDefaultChecked(&oneIsSelected);
}
}
}
// if there isn't a default selcted radio then
// select the firdst one in the group.
// if aRadioToIgnore is not null then it is being deleted
// so don't select that item, select the next one if there is one.
if (!oneIsSelected && numItems > 0) {
nsGfxRadioControlFrame * radioBtn = (nsGfxRadioControlFrame*) aGroup->GetRadioAt(0);
if (aRadioToIgnore != nsnull && aRadioToIgnore == radioBtn) {
if (numItems == 1) {
return;
}
radioBtn = (nsGfxRadioControlFrame*) aGroup->GetRadioAt(1);
}
nsCOMPtr<nsIContent> content;
radioBtn->GetContent(getter_AddRefs(content));
if (content) {
nsCOMPtr<nsIDOMHTMLInputElement> input(do_QueryInterface(content));
if (input) {
input->SetChecked(PR_TRUE);
OnRadioChecked(aPresContext, *radioBtn, PR_TRUE);
}
}
}
}
}
void nsFormFrame::AddFormControlFrame(nsIPresContext* aPresContext, nsIFormControlFrame& aFrame)
{
mFormControls.AppendElement(&aFrame);
@ -381,7 +458,7 @@ void nsFormFrame::AddFormControlFrame(nsIPresContext* aPresContext, nsIFormContr
// radio group processing
if (NS_FORM_INPUT_RADIO == type) {
nsRadioControlFrame* radioFrame = (nsRadioControlFrame*)&aFrame;
nsGfxRadioControlFrame* radioFrame = (nsGfxRadioControlFrame*)&aFrame;
// gets the name of the radio group and the group
nsRadioControlGroup * group;
nsAutoString name;
@ -401,6 +478,7 @@ void nsFormFrame::AddFormControlFrame(nsIPresContext* aPresContext, nsIFormContr
radioFrame->SetChecked(aPresContext, PR_FALSE, PR_TRUE);
}
}
DoDefaultSelection(aPresContext, group);
}
}
@ -411,7 +489,7 @@ void nsFormFrame::RemoveRadioControlFrame(nsIFormControlFrame * aFrame)
// radio group processing
if (NS_FORM_INPUT_RADIO == type) {
nsRadioControlFrame* radioFrame = (nsRadioControlFrame*)aFrame;
nsGfxRadioControlFrame* radioFrame = (nsGfxRadioControlFrame*)aFrame;
// gets the name of the radio group and the group
nsRadioControlGroup * group;
nsAutoString name;
@ -423,7 +501,7 @@ void nsFormFrame::RemoveRadioControlFrame(nsIFormControlFrame * aFrame)
}
void
nsFormFrame::OnRadioChecked(nsIPresContext* aPresContext, nsRadioControlFrame& aControl, PRBool aChecked)
nsFormFrame::OnRadioChecked(nsIPresContext* aPresContext, nsGfxRadioControlFrame& aControl, PRBool aChecked)
{
nsString radioName;
aControl.GetName(&radioName);
@ -437,7 +515,7 @@ nsFormFrame::OnRadioChecked(nsIPresContext* aPresContext, nsRadioControlFrame& a
nsRadioControlGroup* group = (nsRadioControlGroup *) mRadioGroups.ElementAt(j);
nsString groupName;
group->GetName(groupName);
nsRadioControlFrame* checkedRadio = group->GetCheckedRadio();
nsGfxRadioControlFrame* checkedRadio = group->GetCheckedRadio();
if (groupName.Equals(radioName)) {
if (aChecked) {
if (&aControl != checkedRadio) {

View File

@ -34,7 +34,7 @@ class nsIFrame;
class nsIPresContext;
struct nsHTMLReflowState;
class nsFormControlFrame;
class nsRadioControlFrame;
class nsGfxRadioControlFrame;
class nsIFormControlFrame;
class nsIDOMHTMLFormElement;
class nsIDocument;
@ -52,6 +52,11 @@ public:
NS_IMETHOD QueryInterface(REFNSIID aIID, void** aInstancePtr);
NS_IMETHOD RemoveFrame(nsIPresContext* aPresContext,
nsIPresShell& aPresShell,
nsIAtom* aListName,
nsIFrame* aOldFrame);
// nsIFormManager
NS_IMETHOD OnReset(nsIPresContext* aPresContext);
@ -60,7 +65,7 @@ public:
// other methods
void OnRadioChecked(nsIPresContext* aPresContext, nsRadioControlFrame& aRadio, PRBool aChecked = PR_TRUE);
void OnRadioChecked(nsIPresContext* aPresContext, nsGfxRadioControlFrame& aRadio, PRBool aChecked = PR_TRUE);
void AddFormControlFrame(nsIPresContext* aPresContext, nsIFormControlFrame& aFrame);
static void AddFormControlFrame(nsIPresContext* aPresContext, nsIFrame& aFrame);
@ -93,6 +98,10 @@ protected:
NS_IMETHOD_(nsrefcnt) Release(void);
void RemoveRadioGroups();
void DoDefaultSelection(nsIPresContext* aPresContext,
nsRadioControlGroup * aGroup,
nsGfxRadioControlFrame * aRadioToIgnore = nsnull);
nsresult ProcessValue(nsIFormProcessor& aFormProcessor, nsIFormControlFrame* aFrameControl, const nsString& aName, nsString& aNewValue);
nsresult ProcessAsURLEncoded(nsIFormProcessor* aFormProcessor, PRBool aIsPost, nsString& aData, nsIFormControlFrame* aFrame);
nsresult ProcessAsMultipart(nsIFormProcessor* aFormProcessor, nsIFileSpec*& aMultipartDataFile, nsIFormControlFrame* aFrame);

View File

@ -332,7 +332,7 @@ nsGfxButtonControlFrame::Reflow(nsIPresContext* aPresContext,
nsFormFrame::AddFormControlFrame(aPresContext, *NS_STATIC_CAST(nsIFrame*, this));
}
#if 1
#if 0
nsresult skiprv = nsFormControlFrame::SkipResizeReflow(mCacheSize, mCachedMaxElementSize, aPresContext,
aDesiredSize, aReflowState, aStatus);
@ -362,6 +362,12 @@ nsGfxButtonControlFrame::Reflow(nsIPresContext* aPresContext,
aPresContext->GetCompatibilityMode(&mode);
if (mode == eCompatibility_NavQuirks) {
// nsHTMLButtonControlFrame::Reflow registers it for Standard Mode
// and sets up mPresContext
if (eReflowReason_Initial == aReflowState.reason) {
mPresContext = aPresContext;
nsFormControlFrame::RegUnRegAccessKey(aPresContext, NS_STATIC_CAST(nsIFrame*, this), PR_TRUE);
}
// Do NavQuirks Sizing and layout
rv = DoNavQuirksReflow(aPresContext, aDesiredSize, aReflowState, aStatus);
} else {

View File

@ -27,9 +27,12 @@
#include "nsFormFrame.h"
#include "nsIFormControl.h"
#include "nsIContent.h"
#include "nsWidgetsCID.h"
#include "nsIComponentManager.h"
#include "nsHTMLAtoms.h"
#include "nsINameSpaceManager.h"
#include "nsIPresState.h"
//------------------------------------------------------------
nsresult
NS_NewGfxCheckboxControlFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame)
{
@ -46,18 +49,156 @@ NS_NewGfxCheckboxControlFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame)
}
//------------------------------------------------------------
// Initialize GFX-rendered state
nsGfxCheckboxControlFrame::nsGfxCheckboxControlFrame()
: mChecked(eOff)
{
}
//----------------------------------------------------------------------
// nsISupports
//----------------------------------------------------------------------
// Frames are not refcounted, no need to AddRef
NS_IMETHODIMP
nsGfxCheckboxControlFrame::QueryInterface(const nsIID& aIID, void** aInstancePtr)
{
NS_ASSERTION(aInstancePtr, "QueryInterface requires a non-NULL destination!");
if ( !aInstancePtr )
return NS_ERROR_NULL_POINTER;
if (aIID.Equals(NS_GET_IID(nsIStatefulFrame))) {
*aInstancePtr = (void*)(nsIStatefulFrame*) this;
return NS_OK;
}
return nsFormControlFrame::QueryInterface(aIID, aInstancePtr);
}
//------------------------------------------------------------
//
// Init
//
// We need to override this in order to see if we're a tristate checkbox.
//
NS_IMETHODIMP
nsGfxCheckboxControlFrame::Init(nsIPresContext* aPresContext,
nsIContent* aContent,
nsIFrame* aParent,
nsIStyleContext* aContext,
nsIFrame* aPrevInFlow)
{
nsFormControlFrame::Init ( aPresContext, aContent, aParent, aContext, aPrevInFlow );
// figure out if we're a tristate at the start. This may change later on once
// we've been running for a while, so more code is in AttributeChanged() to pick
// that up. Regardless, we need this check when initializing.
nsAutoString value;
nsresult res = mContent->GetAttribute ( kNameSpaceID_None, GetTristateAtom(), value );
if ( res == NS_CONTENT_ATTR_HAS_VALUE )
mIsTristate = PR_TRUE;
// give the attribute a default value so it's always present, if we're a tristate
if ( IsTristateCheckbox() )
mContent->SetAttribute ( kNameSpaceID_None, GetTristateValueAtom(), "0", PR_FALSE );
return NS_OK;
}
//------------------------------------------------------------
//
// GetTristateAtom [static]
//
// Use a lazily instantiated static initialization scheme to create an atom that
// represents the attribute set when this should be a tri-state checkbox.
//
// Does NOT addref!
//
nsIAtom*
nsGfxCheckboxControlFrame :: GetTristateAtom ( )
{
return nsHTMLAtoms::moz_tristate;
}
//------------------------------------------------------------
//
// GetTristateValueAtom [static]
//
// Use a lazily instantiated static initialization scheme to create an atom that
// represents the attribute that holds the value when the button is a tri-state (since
// we can't use "checked").
//
// Does NOT addref!
//
nsIAtom*
nsGfxCheckboxControlFrame :: GetTristateValueAtom ( )
{
return nsHTMLAtoms::moz_tristatevalue;
}
//------------------------------------------------------------
//
// AttributeChanged
//
// Override to check for the attribute that determines if we're a normal or a
// tristate checkbox. If we notice a switch from one to the other, we need
// to adjust the proper attributes in the content model accordingly.
//
// Also, since the value of a tri-state is kept in a separate attribute (we
// can't use "checked" because it's a boolean), we have to notice it changing
// here.
//
NS_IMETHODIMP
nsGfxCheckboxControlFrame::AttributeChanged(nsIPresContext* aPresContext,
nsIContent* aChild,
PRInt32 aNameSpaceID,
nsIAtom* aAttribute,
PRInt32 aHint)
{
if ( aAttribute == GetTristateAtom() ) {
nsAutoString value;
nsresult res = mContent->GetAttribute ( kNameSpaceID_None, GetTristateAtom(), value );
PRBool isNowTristate = (res == NS_CONTENT_ATTR_HAS_VALUE);
if ( isNowTristate != mIsTristate )
SwitchModesWithEmergencyBrake(aPresContext, isNowTristate);
}
else if ( aAttribute == GetTristateValueAtom() ) {
// ignore this change if we're not a tri-state checkbox
if ( IsTristateCheckbox() ) {
nsAutoString value;
nsresult res = mContent->GetAttribute ( kNameSpaceID_None, GetTristateValueAtom(), value );
if ( res == NS_CONTENT_ATTR_HAS_VALUE )
SetCheckboxControlFrameState(aPresContext, value);
}
}
else
return nsFormControlFrame::AttributeChanged(aPresContext, aChild, aNameSpaceID, aAttribute, aHint);
return NS_OK;
}
//------------------------------------------------------------
//
// InitializeControl
//
// Set the default checked state of the checkbox.
//
void
nsGfxCheckboxControlFrame::InitializeControl(nsIPresContext* aPresContext)
{
nsFormControlFrame::InitializeControl(aPresContext);
PRBool checked = PR_FALSE;
nsresult result = GetDefaultCheckState(&checked);
if (NS_CONTENT_ATTR_HAS_VALUE == result) {
SetCheckboxState (aPresContext, checked ? eOn : eOff );
}
}
//------------------------------------------------------------
void
nsGfxCheckboxControlFrame::PaintCheckBox(nsIPresContext* aPresContext,
nsIRenderingContext& aRenderingContext,
const nsRect& aDirtyRect,
nsFramePaintLayer aWhichLayer)
nsIRenderingContext& aRenderingContext,
const nsRect& aDirtyRect,
nsFramePaintLayer aWhichLayer)
{
aRenderingContext.PushState();
@ -111,6 +252,7 @@ nsGfxCheckboxControlFrame::PaintCheckBox(nsIPresContext* aPresContext,
}
//------------------------------------------------------------
//
// PaintMixedMark
//
@ -155,6 +297,7 @@ nsGfxCheckboxControlFrame::PaintMixedMark ( nsIRenderingContext& aRenderingConte
} // PaintMixedMark
//------------------------------------------------------------
NS_METHOD
nsGfxCheckboxControlFrame::Paint(nsIPresContext* aPresContext,
nsIRenderingContext& aRenderingContext,
@ -167,7 +310,7 @@ nsGfxCheckboxControlFrame::Paint(nsIPresContext* aPresContext,
return NS_OK;
// Paint the background
Inherited::Paint(aPresContext, aRenderingContext, aDirtyRect, aWhichLayer);
nsFormControlFrame::Paint(aPresContext, aRenderingContext, aDirtyRect, aWhichLayer);
if (NS_FRAME_PAINT_LAYER_FOREGROUND == aWhichLayer) {
// Paint the checkmark
PaintCheckBox(aPresContext, aRenderingContext, aDirtyRect, aWhichLayer);
@ -176,20 +319,232 @@ nsGfxCheckboxControlFrame::Paint(nsIPresContext* aPresContext,
}
nsCheckboxControlFrame::CheckState
nsGfxCheckboxControlFrame :: GetCheckboxState ( )
//------------------------------------------------------------
nsGfxCheckboxControlFrame::CheckState
nsGfxCheckboxControlFrame::GetCheckboxState ( )
{
return mChecked;
}
//------------------------------------------------------------
void
nsGfxCheckboxControlFrame :: SetCheckboxState (nsIPresContext* aPresContext,
nsCheckboxControlFrame::CheckState aValue )
nsGfxCheckboxControlFrame::SetCheckboxState (nsIPresContext* aPresContext,
nsGfxCheckboxControlFrame::CheckState aValue )
{
mChecked = aValue;
nsFormControlHelper::ForceDrawFrame(aPresContext, this);
}
//------------------------------------------------------------
void nsGfxCheckboxControlFrame::GetCheckboxControlFrameState(nsString& aValue)
{
CheckStateToString(GetCheckboxState(), aValue);
}
//------------------------------------------------------------
void nsGfxCheckboxControlFrame::SetCheckboxControlFrameState(nsIPresContext* aPresContext,
const nsString& aValue)
{
CheckState state = StringToCheckState(aValue);
SetCheckboxState(aPresContext, state);
}
//------------------------------------------------------------
NS_IMETHODIMP nsGfxCheckboxControlFrame::SetProperty(nsIPresContext* aPresContext,
nsIAtom* aName,
const nsString& aValue)
{
if (nsHTMLAtoms::checked == aName)
SetCheckboxControlFrameState(aPresContext, aValue);
else
return nsFormControlFrame::SetProperty(aPresContext, aName, aValue);
return NS_OK;
}
//------------------------------------------------------------
NS_IMETHODIMP nsGfxCheckboxControlFrame::GetProperty(nsIAtom* aName, nsString& aValue)
{
if (nsHTMLAtoms::checked == aName)
GetCheckboxControlFrameState(aValue);
else
return nsFormControlFrame::GetProperty(aName, aValue);
return NS_OK;
}
//------------------------------------------------------------
PRInt32
nsGfxCheckboxControlFrame::GetMaxNumValues()
{
return 1;
}
//------------------------------------------------------------
PRBool
nsGfxCheckboxControlFrame::GetNamesValues(PRInt32 aMaxNumValues, PRInt32& aNumValues,
nsString* aValues, nsString* aNames)
{
nsAutoString name;
nsresult nameResult = GetName(&name);
if ((aMaxNumValues <= 0) || (NS_CONTENT_ATTR_HAS_VALUE != nameResult)) {
return PR_FALSE;
}
PRBool result = PR_TRUE;
CheckState state = GetCheckboxState();
nsAutoString value;
nsresult valueResult = GetValue(&value);
if (eOn != state) {
result = PR_FALSE;
} else {
if (NS_CONTENT_ATTR_HAS_VALUE != valueResult) {
aValues[0] = "on";
} else {
aValues[0] = value;
}
aNames[0] = name;
aNumValues = 1;
}
return result;
}
//------------------------------------------------------------
void
nsGfxCheckboxControlFrame::Reset(nsIPresContext* aPresContext)
{
PRBool checked;
GetDefaultCheckState(&checked);
SetCheckboxState (aPresContext, checked ? eOn : eOff );
}
//------------------------------------------------------------
//
// CheckStateToString
//
// Converts from a CheckState to a string
//
void
nsGfxCheckboxControlFrame::CheckStateToString ( CheckState inState, nsString& outStateAsString )
{
switch ( inState ) {
case eOn:
outStateAsString = NS_STRING_TRUE;
break;
case eOff:
outStateAsString = NS_STRING_FALSE;
break;
case eMixed:
outStateAsString = "2";
break;
}
} // CheckStateToString
//------------------------------------------------------------
//
// StringToCheckState
//
// Converts from a string to a CheckState enum
//
nsGfxCheckboxControlFrame::CheckState
nsGfxCheckboxControlFrame::StringToCheckState ( const nsString & aStateAsString )
{
if ( aStateAsString == NS_STRING_TRUE )
return eOn;
else if ( aStateAsString == NS_STRING_FALSE )
return eOff;
// not true and not false means mixed
return eMixed;
} // StringToCheckState
//------------------------------------------------------------
//
// SwitchModesWithEmergencyBrake
//
// Since we use an attribute to decide if we're a tristate box or not, this can change
// at any time. Since we have to use separate attributes to store the values depending
// on the mode, we have to convert from one to the other.
//
void
nsGfxCheckboxControlFrame::SwitchModesWithEmergencyBrake ( nsIPresContext* aPresContext,
PRBool inIsNowTristate )
{
if ( inIsNowTristate ) {
// we were a normal checkbox, and now we're a tristate. That means that the
// state of the checkbox was in "checked" and needs to be copied over into
// our parallel attribute.
nsAutoString value;
CheckStateToString ( GetCheckboxState(), value );
mContent->SetAttribute ( kNameSpaceID_None, GetTristateValueAtom(), value, PR_FALSE );
}
else {
// we were a tri-state checkbox, and now we're a normal checkbox. The current
// state is already up to date (because it's always up to date). We just have
// to make sure it's not mixed. If it is, just set it to checked. Remove our
// parallel attribute so that we're nice and HTML4 compliant.
if ( GetCheckboxState() == eMixed )
SetCheckboxState(aPresContext, eOn);
mContent->UnsetAttribute ( kNameSpaceID_None, GetTristateValueAtom(), PR_FALSE );
}
// switch!
mIsTristate = inIsNowTristate;
} // SwitchModesWithEmergencyBrake
//----------------------------------------------------------------------
// nsIStatefulFrame
//----------------------------------------------------------------------
NS_IMETHODIMP nsGfxCheckboxControlFrame::GetStateType(nsIPresContext* aPresContext,
nsIStatefulFrame::StateType* aStateType)
{
*aStateType=nsIStatefulFrame::eCheckboxType;
return NS_OK;
}
NS_IMETHODIMP nsGfxCheckboxControlFrame::SaveState(nsIPresContext* aPresContext,
nsIPresState** aState)
{
// Construct a pres state.
NS_NewPresState(aState); // The addref happens here.
// This string will hold a single item, whether or not we're checked.
nsAutoString stateString;
GetCheckboxControlFrameState(stateString);
(*aState)->SetStateProperty("checked", stateString);
return NS_OK;
}
NS_IMETHODIMP nsGfxCheckboxControlFrame::RestoreState(nsIPresContext* aPresContext,
nsIPresState* aState)
{
if (!mDidInit) {
mPresContext = aPresContext;
InitializeControl(aPresContext);
mDidInit = PR_TRUE;
}
nsAutoString string;
aState->GetStateProperty("checked", string);
SetCheckboxControlFrameState(aPresContext, string);
return NS_OK;
}
//------------------------------------------------------------
// Extra Debug Methods
//------------------------------------------------------------
#ifdef DEBUG_rodsXXX
NS_IMETHODIMP
nsGfxCheckboxControlFrame::Reflow(nsIPresContext* aPresContext,
@ -197,7 +552,7 @@ nsGfxCheckboxControlFrame::Reflow(nsIPresContext* aPresContext,
const nsHTMLReflowState& aReflowState,
nsReflowStatus& aStatus)
{
nsresult rv = nsNativeFormControlFrame::Reflow(aPresContext, aDesiredSize, aReflowState, aStatus);
nsresult rv = nsFormControlFrame::Reflow(aPresContext, aDesiredSize, aReflowState, aStatus);
COMPARE_QUIRK_SIZE("nsGfxCheckboxControlFrame", 13, 13)
return rv;

View File

@ -22,13 +22,13 @@
#ifndef nsGfxCheckboxControlFrame_h___
#define nsGfxCheckboxControlFrame_h___
#include "nsCheckboxControlFrame.h"
#include "nsFormControlFrame.h"
#include "nsIStatefulFrame.h"
class nsGfxCheckboxControlFrame : public nsCheckboxControlFrame {
private:
typedef nsCheckboxControlFrame Inherited;
class nsGfxCheckboxControlFrame : public nsFormControlFrame,
public nsIStatefulFrame
{
public:
nsGfxCheckboxControlFrame();
@ -37,17 +37,43 @@ public:
return MakeFrameName("CheckboxControl", aResult);
}
#endif
// this should be protected, but VC6 is lame.
enum CheckState { eOff, eOn, eMixed } ;
// overrides base class HandleEvent to do nothing
// events are handled by the DOM
NS_IMETHOD HandleEvent(nsIPresContext* aPresContext,
nsGUIEvent* aEvent,
nsEventStatus* aEventStatus) { return NS_OK; }
NS_IMETHOD Init(nsIPresContext* aPresContext,
nsIContent* aContent,
nsIFrame* aParent,
nsIStyleContext* aContext,
nsIFrame* aPrevInFlow) ;
NS_IMETHOD AttributeChanged(nsIPresContext* aPresContext,
nsIContent* aChild,
PRInt32 aNameSpaceID,
nsIAtom* aAttribute,
PRInt32 aHint) ;
NS_IMETHOD Paint(nsIPresContext* aPresContext,
nsIRenderingContext& aRenderingContext,
const nsRect& aDirtyRect,
nsFramePaintLayer aWhichLayer);
void InitializeControl(nsIPresContext* aPresContext);
// nsIFormControlFrame
NS_IMETHOD SetProperty(nsIPresContext* aPresContext, nsIAtom* aName, const nsString& aValue);
NS_IMETHOD GetProperty(nsIAtom* aName, nsString& aValue);
virtual void Reset(nsIPresContext* aPresContext);
virtual PRInt32 GetMaxNumValues();
virtual PRBool GetNamesValues(PRInt32 aMaxNumValues, PRInt32& aNumValues,
nsString* aValues, nsString* aNames);
// nsIStatefulFrame
NS_IMETHOD QueryInterface(const nsIID& aIID, void** aInstancePtr);
NS_IMETHOD GetStateType(nsIPresContext* aPresContext, nsIStatefulFrame::StateType* aStateType);
NS_IMETHOD SaveState(nsIPresContext* aPresContext, nsIPresState** aState);
NS_IMETHOD RestoreState(nsIPresContext* aPresContext, nsIPresState* aState);
#ifdef DEBUG_rodsXXX
NS_IMETHOD Reflow(nsIPresContext* aCX,
nsHTMLReflowMetrics& aDesiredSize,
@ -56,8 +82,35 @@ public:
#endif
protected:
virtual CheckState GetCheckboxState();
virtual void SetCheckboxState(nsIPresContext* aPresContext, CheckState aValue);
// native/gfx implementations need to implement needs.
CheckState GetCheckboxState();
void SetCheckboxState(nsIPresContext* aPresContext, CheckState aValue);
// Utility methods for implementing SetProperty/GetProperty
void SetCheckboxControlFrameState(nsIPresContext* aPresContext,
const nsString& aValue);
void GetCheckboxControlFrameState(nsString& aValue);
// utility routine for converting from DOM values to internal enum
void CheckStateToString ( CheckState inState, nsString& outStateAsString ) ;
CheckState StringToCheckState ( const nsString & aStateAsString ) ;
// figure out if we're a tri-state checkbox.
PRBool IsTristateCheckbox ( ) const { return mIsTristate; }
// we just became a tri-state, or we just lost tri-state status. fix up
// the attributes for the new mode.
void SwitchModesWithEmergencyBrake ( nsIPresContext* aPresContext,
PRBool inIsNowTristate ) ;
// for tri-state checkbox. meaningless for normal HTML
PRBool mIsTristate;
static nsIAtom* GetTristateAtom() ;
static nsIAtom* GetTristateValueAtom() ;
protected:
virtual void PaintCheckBox(nsIPresContext* aPresContext,
nsIRenderingContext& aRenderingContext,
@ -68,7 +121,11 @@ protected:
//GFX-rendered state variables
CheckState mChecked;
private:
NS_IMETHOD_(nsrefcnt) AddRef() { return NS_OK; }
NS_IMETHOD_(nsrefcnt) Release() { return NS_OK; }
};
#endif

View File

@ -125,6 +125,8 @@ nsGfxListControlFrame::nsGfxListControlFrame()
//---------------------------------------------------------
nsGfxListControlFrame::~nsGfxListControlFrame()
{
nsFormControlFrame::RegUnRegAccessKey(mPresContext, NS_STATIC_CAST(nsIFrame*, this), PR_FALSE);
// if list is dropped down
// make sure it gets rolled up
if (IsInDropDownMode()) {
@ -375,6 +377,7 @@ nsGfxListControlFrame::Reflow(nsIPresContext* aPresContext,
// Add the list frame as a child of the form
if (IsInDropDownMode() == PR_FALSE && !mFormFrame && (eReflowReason_Initial == aReflowState.reason)) {
nsFormControlFrame::RegUnRegAccessKey(aPresContext, NS_STATIC_CAST(nsIFrame*, this), PR_TRUE);
nsFormFrame::AddFormControlFrame(aPresContext, *NS_STATIC_CAST(nsIFrame*, this));
}
@ -583,8 +586,8 @@ nsGfxListControlFrame::Reflow(nsIPresContext* aPresContext,
// for the list frame and use that as the max/minimum size for the contents
if (visibleHeight == 0) {
nsCOMPtr<nsIFontMetrics> fontMet;
nsFormControlHelper::GetFrameFontFM(aPresContext, this, getter_AddRefs(fontMet));
if (fontMet) {
nsresult res = nsFormControlHelper::GetFrameFontFM(aPresContext, this, getter_AddRefs(fontMet));
if (NS_SUCCEEDED(res) && fontMet) {
aReflowState.rendContext->SetFont(fontMet);
fontMet->GetHeight(visibleHeight);
mMaxHeight = visibleHeight;
@ -654,8 +657,7 @@ NS_IMETHODIMP
nsGfxListControlFrame::GetFont(nsIPresContext* aPresContext,
const nsFont*& aFont)
{
nsFormControlHelper::GetFont(this, aPresContext, mStyleContext, aFont);
return NS_OK;
return nsFormControlHelper::GetFont(this, aPresContext, mStyleContext, aFont);
}
@ -1459,10 +1461,7 @@ nsGfxListControlFrame::SetContentSelected(PRInt32 aIndex, PRBool aSelected)
if (aSelected) {
DisplaySelected(content);
// Now that it is selected scroll to it
nsCOMPtr<nsIContent> content(do_QueryInterface(content));
if (content) {
ScrollToFrame(content);
}
ScrollToFrame(content);
} else {
DisplayDeselected(content);
}

View File

@ -89,7 +89,7 @@ public:
NS_IMETHOD GetProperty(nsIAtom* aName, nsString& aValue);
NS_IMETHOD GetMultiple(PRBool* aResult, nsIDOMHTMLSelectElement* aSelect = nsnull);
NS_IMETHOD GetFont(nsIPresContext* aPresContext,
const nsFont*& aFont);
const nsFont*& aFont);
NS_IMETHOD GetFormContent(nsIContent*& aContent) const;
virtual void SetFocus(PRBool aOn = PR_TRUE, PRBool aRepaint = PR_FALSE);

View File

@ -21,7 +21,6 @@
*/
#include "nsGfxRadioControlFrame.h"
#include "nsIRadioButton.h"
#include "nsHTMLAtoms.h"
#include "nsHTMLParts.h"
#include "nsFormFrame.h"
@ -31,6 +30,8 @@
#include "nsIComponentManager.h"
#include "nsCOMPtr.h"
#include "nsCSSRendering.h"
#include "nsIPresState.h"
#include "nsINameSpaceManager.h"
nsresult
@ -57,11 +58,31 @@ nsGfxRadioControlFrame::nsGfxRadioControlFrame()
nsGfxRadioControlFrame::~nsGfxRadioControlFrame()
{
NS_IF_RELEASE(mRadioButtonFaceStyle);
NS_IF_RELEASE(mRadioButtonFaceStyle);
}
//--------------------------------------------------------------
// Frames are not refcounted, no need to AddRef
NS_IMETHODIMP
nsGfxRadioControlFrame::QueryInterface(const nsIID& aIID, void** aInstancePtr)
{
NS_PRECONDITION(0 != aInstancePtr, "null ptr");
if (NULL == aInstancePtr) {
return NS_ERROR_NULL_POINTER;
}
if (aIID.Equals(NS_GET_IID(nsIRadioControlFrame))) {
*aInstancePtr = (void*) ((nsIRadioControlFrame*) this);
return NS_OK;
}
if (aIID.Equals(NS_GET_IID(nsIStatefulFrame))) {
*aInstancePtr = (void*) ((nsIStatefulFrame*) this);
return NS_OK;
}
return nsFormControlFrame::QueryInterface(aIID, aInstancePtr);
}
//--------------------------------------------------------------
NS_IMETHODIMP
nsGfxRadioControlFrame::GetAdditionalStyleContext(PRInt32 aIndex,
nsIStyleContext** aStyleContext) const
@ -82,6 +103,7 @@ nsGfxRadioControlFrame::GetAdditionalStyleContext(PRInt32 aIndex,
return NS_OK;
}
//--------------------------------------------------------------
NS_IMETHODIMP
nsGfxRadioControlFrame::SetAdditionalStyleContext(PRInt32 aIndex,
nsIStyleContext* aStyleContext)
@ -99,7 +121,69 @@ nsGfxRadioControlFrame::SetAdditionalStyleContext(PRInt32 aIndex,
return NS_OK;
}
//--------------------------------------------------------------
NS_IMETHODIMP nsGfxRadioControlFrame::SetProperty(nsIPresContext* aPresContext, nsIAtom* aName, const nsString& aValue)
{
if (nsHTMLAtoms::checked == aName) {
PRBool state = (aValue == NS_STRING_TRUE) ? PR_TRUE : PR_FALSE;
SetRadioState(aPresContext, state);
if (mFormFrame) {
mFormFrame->OnRadioChecked(aPresContext, *this, state);
}
}
else {
return nsFormControlFrame::SetProperty(aPresContext, aName, aValue);
}
return NS_OK;
}
//--------------------------------------------------------------
NS_IMETHODIMP nsGfxRadioControlFrame::GetProperty(nsIAtom* aName, nsString& aValue)
{
// Return the value of the property from the widget it is not null.
// If is null, assume the widget is GFX-rendered and return a member variable instead.
if (nsHTMLAtoms::checked == aName) {
nsFormControlHelper::GetBoolString(GetRadioState(), aValue);
} else {
return nsFormControlFrame::GetProperty(aName, aValue);
}
return NS_OK;
}
//--------------------------------------------------------------
PRBool
nsGfxRadioControlFrame::GetChecked(PRBool aGetInitialValue)
{
PRBool checked = PR_FALSE;
if (PR_TRUE == aGetInitialValue) {
GetDefaultCheckState(&checked);
}
else {
GetCurrentCheckState(&checked);
}
return(checked);
}
//--------------------------------------------------------------
void
nsGfxRadioControlFrame::SetChecked(nsIPresContext* aPresContext, PRBool aValue, PRBool aSetInitialValue)
{
if (aSetInitialValue) {
if (aValue) {
mContent->SetAttribute(kNameSpaceID_HTML, nsHTMLAtoms::checked, nsAutoString("1"), PR_FALSE); // XXX should be "empty" value
} else {
mContent->SetAttribute(kNameSpaceID_HTML, nsHTMLAtoms::checked, nsAutoString("0"), PR_FALSE);
}
}
SetRadioState(aPresContext, aValue);
}
//--------------------------------------------------------------
NS_IMETHODIMP
nsGfxRadioControlFrame::SetRadioButtonFaceStyleContext(nsIStyleContext *aRadioButtonFaceStyleContext)
{
@ -108,6 +192,47 @@ nsGfxRadioControlFrame::SetRadioButtonFaceStyleContext(nsIStyleContext *aRadioBu
return NS_OK;
}
//--------------------------------------------------------------
PRBool
nsGfxRadioControlFrame::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;
}
PRBool state = GetRadioState();
if(PR_TRUE != state) {
return PR_FALSE;
}
nsAutoString value;
result = GetValue(&value);
if (NS_CONTENT_ATTR_HAS_VALUE == result) {
aValues[0] = value;
} else {
aValues[0] = "on";
}
aNames[0] = name;
aNumValues = 1;
return PR_TRUE;
}
//--------------------------------------------------------------
void
nsGfxRadioControlFrame::Reset(nsIPresContext* aPresContext)
{
PRBool checked = PR_TRUE;
GetDefaultCheckState(&checked);
SetCurrentCheckState(checked);
}
//--------------------------------------------------------------
void
nsGfxRadioControlFrame::PaintRadioButton(nsIPresContext* aPresContext,
nsIRenderingContext& aRenderingContext,
@ -141,6 +266,7 @@ nsGfxRadioControlFrame::PaintRadioButton(nsIPresContext* aPresContext,
}
}
//--------------------------------------------------------------
NS_METHOD
nsGfxRadioControlFrame::Paint(nsIPresContext* aPresContext,
nsIRenderingContext& aRenderingContext,
@ -153,7 +279,7 @@ nsGfxRadioControlFrame::Paint(nsIPresContext* aPresContext,
return NS_OK;
// Paint the background
Inherited::Paint(aPresContext, aRenderingContext, aDirtyRect, aWhichLayer);
nsFormControlFrame::Paint(aPresContext, aRenderingContext, aDirtyRect, aWhichLayer);
if (NS_FRAME_PAINT_LAYER_FOREGROUND == aWhichLayer) {
PaintRadioButton(aPresContext, aRenderingContext, aDirtyRect);
@ -162,17 +288,79 @@ nsGfxRadioControlFrame::Paint(nsIPresContext* aPresContext,
}
//--------------------------------------------------------------
PRBool nsGfxRadioControlFrame::GetRadioState()
{
return mChecked;
}
//--------------------------------------------------------------
void nsGfxRadioControlFrame::SetRadioState(nsIPresContext* aPresContext, PRBool aValue)
{
mChecked = aValue;
nsFormControlHelper::ForceDrawFrame(aPresContext, this);
}
void
nsGfxRadioControlFrame::InitializeControl(nsIPresContext* aPresContext)
{
nsFormControlFrame::InitializeControl(aPresContext);
// set the widget to the initial state
PRBool checked = PR_FALSE;
nsresult result = GetDefaultCheckState(&checked);
if (NS_CONTENT_ATTR_HAS_VALUE == result) {
SetRadioState(aPresContext, checked);
}
}
//----------------------------------------------------------------------
// nsIStatefulFrame
//----------------------------------------------------------------------
NS_IMETHODIMP
nsGfxRadioControlFrame::GetStateType(nsIPresContext* aPresContext, nsIStatefulFrame::StateType* aStateType)
{
*aStateType = nsIStatefulFrame::eRadioType;
return NS_OK;
}
//----------------------------------------------------------------------
NS_IMETHODIMP
nsGfxRadioControlFrame::SaveState(nsIPresContext* aPresContext, nsIPresState** aState)
{
// Construct a pres state.
NS_NewPresState(aState); // The addref happens here.
// This string will hold a single item, whether or not we're checked.
nsAutoString stateString;
nsFormControlHelper::GetBoolString(GetRadioState(), stateString);
(*aState)->SetStateProperty("checked", stateString);
return NS_OK;
}
//----------------------------------------------------------------------
NS_IMETHODIMP
nsGfxRadioControlFrame::RestoreState(nsIPresContext* aPresContext, nsIPresState* aState)
{
if (!mDidInit) {
mPresContext = aPresContext;
InitializeControl(aPresContext);
mDidInit = PR_TRUE;
}
nsAutoString string;
aState->GetStateProperty("checked", string);
PRBool state = (string == NS_STRING_TRUE) ? PR_TRUE : PR_FALSE;
SetRadioState(aPresContext, state);
return NS_OK;
}
//----------------------------------------------------------------------
// Extra Debug Helper Methods
//----------------------------------------------------------------------
#ifdef DEBUG_rodsXXX
NS_IMETHODIMP
nsGfxRadioControlFrame::Reflow(nsIPresContext* aPresContext,

View File

@ -23,25 +23,36 @@
#ifndef nsGfxRadioControlFrame_h___
#define nsGfxRadioControlFrame_h___
#include "nsRadioControlFrame.h"
#include "nsFormControlFrame.h"
#include "nsIStatefulFrame.h"
#include "nsIRadioControlFrame.h"
// nsGfxRadioControlFrame
#define NS_GFX_RADIO_CONTROL_FRAME_FACE_CONTEXT_INDEX 0 // for additional style contexts
#define NS_GFX_RADIO_CONTROL_FRAME_LAST_CONTEXT_INDEX 0
class nsGfxRadioControlFrame : public nsRadioControlFrame
class nsGfxRadioControlFrame : public nsFormControlFrame,
public nsIStatefulFrame,
public nsIRadioControlFrame
{
private:
typedef nsRadioControlFrame Inherited;
public:
nsGfxRadioControlFrame();
~nsGfxRadioControlFrame();
//nsIRadioControlFrame methods
NS_IMETHOD QueryInterface(const nsIID& aIID, void** aInstancePtr);
NS_IMETHOD SetRadioButtonFaceStyleContext(nsIStyleContext *aRadioButtonFaceStyleContext);
virtual PRBool GetChecked(PRBool aGetInitialValue);
virtual void SetChecked(nsIPresContext* aPresContext, PRBool aValue, PRBool aSetInitialValue);
void InitializeControl(nsIPresContext* aPresContext);
NS_IMETHOD GetAdditionalStyleContext(PRInt32 aIndex,
nsIStyleContext** aStyleContext) const;
NS_IMETHOD SetAdditionalStyleContext(PRInt32 aIndex,
@ -67,6 +78,21 @@ public:
nsIRenderingContext& aRenderingContext,
const nsRect& aDirtyRect);
virtual PRInt32 GetMaxNumValues() { return 1; }
virtual PRBool GetNamesValues(PRInt32 aMaxNumValues, PRInt32& aNumValues,
nsString* aValues, nsString* aNames);
virtual void Reset(nsIPresContext* aPresContext);
// nsIFormControlFrame
NS_IMETHOD SetProperty(nsIPresContext* aPresContext, nsIAtom* aName, const nsString& aValue);
NS_IMETHOD GetProperty(nsIAtom* aName, nsString& aValue);
//nsIStatefulFrame
NS_IMETHOD GetStateType(nsIPresContext* aPresContext, nsIStatefulFrame::StateType* aStateType);
NS_IMETHOD SaveState(nsIPresContext* aPresContext, nsIPresState** aState);
NS_IMETHOD RestoreState(nsIPresContext* aPresContext, nsIPresState* aState);
///XXX: End o the temporary methods
#ifdef DEBUG_rodsXXX
NS_IMETHOD Reflow(nsIPresContext* aCX,

View File

@ -31,7 +31,6 @@
#include "nsIHTMLContent.h"
#include "nsHTMLIIDs.h"
#include "nsITextWidget.h"
#include "nsITextAreaWidget.h"
#include "nsWidgetsCID.h"
#include "nsSize.h"
#include "nsString.h"
@ -81,6 +80,7 @@
#include "nsIPresShell.h"
#include "nsIEventStateManager.h"
#include "nsStyleUtil.h"
#include "nsLinebreakConverter.h"
// for anonymous content and frames
#include "nsHTMLParts.h"
@ -100,9 +100,7 @@
static NS_DEFINE_IID(kIFrameIID, NS_IFRAME_IID);
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);
@ -189,12 +187,17 @@ nsGfxTextControlFrame::QueryInterface(const nsIID& aIID, void** aInstancePtr)
NS_PRECONDITION(0 != aInstancePtr, "null ptr");
if (NULL == aInstancePtr) {
return NS_ERROR_NULL_POINTER;
} else if (aIID.Equals(NS_GET_IID(nsIGfxTextControlFrame))) {
*aInstancePtr = (void*)(nsIGfxTextControlFrame*) this;
return NS_OK;
} else if (aIID.Equals(NS_GET_IID(nsIStatefulFrame))) {
*aInstancePtr = (void*)(nsIStatefulFrame*) this;
return NS_OK;
}
return nsTextControlFrame::QueryInterface(aIID, aInstancePtr);
return nsFormControlFrame::QueryInterface(aIID, aInstancePtr);
}
NS_IMETHODIMP
@ -205,7 +208,7 @@ nsGfxTextControlFrame::Init(nsIPresContext* aPresContext,
nsIFrame* aPrevInFlow)
{
mFramePresContext = aPresContext;
return (nsTextControlFrame::Init(aPresContext, aContent, aParent, aContext, aPrevInFlow));
return nsFormControlFrame::Init(aPresContext, aContent, aParent, aContext, aPrevInFlow);
}
NS_IMETHODIMP
@ -333,6 +336,8 @@ nsGfxTextControlFrame::nsGfxTextControlFrame()
nsGfxTextControlFrame::~nsGfxTextControlFrame()
{
nsFormControlFrame::RegUnRegAccessKey(mPresContext, NS_STATIC_CAST(nsIFrame*, this), PR_FALSE);
nsresult result;
if (mDisplayFrame) {
mFrameConstructor->RemoveMappingsForFrameSubtree(mFramePresContext,
@ -1080,6 +1085,12 @@ void nsGfxTextControlFrame::CalcSizeOfSubDocInTwips(const nsMargin &aBorder,
aSubBounds.height = (aFrameSize.height - (aBorder.top + aPadding.top + aBorder.bottom + aPadding.bottom));
}
PRInt32
nsGfxTextControlFrame::GetMaxNumValues()
{
return 1;
}
PRBool
nsGfxTextControlFrame::GetNamesValues(PRInt32 aMaxNumValues, PRInt32& aNumValues,
nsString* aValues, nsString* aNames)
@ -1990,6 +2001,8 @@ nsGfxTextControlFrame::Reflow(nsIPresContext* aPresContext,
// add ourself as an nsIFormControlFrame
if (!mFormFrame && (eReflowReason_Initial == aReflowState.reason)) {
mPresContext = aPresContext;
nsFormControlFrame::RegUnRegAccessKey(aPresContext, NS_STATIC_CAST(nsIFrame*, this), PR_TRUE);
nsFormFrame::AddFormControlFrame(aPresContext, *NS_STATIC_CAST(nsIFrame*, this));
}
@ -2991,7 +3004,7 @@ nsGfxTextControlFrame::GetAdditionalChildListName(PRInt32 aIndex,
return NS_OK;
}
return nsTextControlFrame::GetAdditionalChildListName(aIndex, aListName);
return nsLeafFrame::GetAdditionalChildListName(aIndex, aListName);
}
NS_IMETHODIMP
@ -3004,7 +3017,7 @@ nsGfxTextControlFrame::FirstChild(nsIPresContext* aPresContext,
return NS_OK;
}
return nsTextControlFrame::FirstChild(aPresContext, aListName, aFirstChild);
return nsLeafFrame::FirstChild(aPresContext, aListName, aFirstChild);
}
NS_IMETHODIMP
@ -3015,7 +3028,58 @@ nsGfxTextControlFrame::Destroy(nsIPresContext* aPresContext)
mDisplayFrame->Destroy(aPresContext);
mDisplayFrame=nsnull;
}
return nsTextControlFrame::Destroy(aPresContext);
return nsLeafFrame::Destroy(aPresContext);
}
//----------------------------------------------------------------------
// nsIStatefulFrame
//----------------------------------------------------------------------
NS_IMETHODIMP
nsGfxTextControlFrame::GetStateType(nsIPresContext* aPresContext, nsIStatefulFrame::StateType* aStateType)
{
*aStateType = nsIStatefulFrame::eTextType;
return NS_OK;
}
NS_IMETHODIMP
nsGfxTextControlFrame::SaveState(nsIPresContext* aPresContext, nsIPresState** aState)
{
// Construct a pres state.
NS_NewPresState(aState); // The addref happens here.
nsAutoString theString;
nsresult res = GetProperty(nsHTMLAtoms::value, theString);
if (NS_SUCCEEDED(res)) {
char* chars = theString.ToNewCString();
if (chars) {
// GetProperty returns platform-native line breaks. We must convert
// these to content line breaks.
char* newChars = nsLinebreakConverter::ConvertLineBreaks(chars,
nsLinebreakConverter::eLinebreakPlatform, nsLinebreakConverter::eLinebreakContent);
if (newChars) {
nsCRT::free(chars);
chars = newChars;
}
(*aState)->SetStateProperty("value", nsAutoString(chars));
nsCRT::free(chars);
} else {
res = NS_ERROR_OUT_OF_MEMORY;
}
}
(*aState)->SetStateProperty("value", theString);
return res;
}
NS_IMETHODIMP
nsGfxTextControlFrame::RestoreState(nsIPresContext* aPresContext, nsIPresState* aState)
{
nsAutoString stateString;
aState->GetStateProperty("value", stateString);
nsresult res = SetProperty(aPresContext, nsHTMLAtoms::value, stateString);
return res;
}
#ifdef NS_DEBUG

View File

@ -27,7 +27,6 @@
#include "nsCOMPtr.h"
#include "nsCWeakReference.h"
#include "nsFormControlFrame.h"
#include "nsTextControlFrame.h"
#include "nsIDocumentLoaderObserver.h"
#include "nsIEditor.h"
#include "nsIDocumentObserver.h"
@ -46,6 +45,8 @@
#include "nsIWebShell.h"
#include "nsIViewManager.h"
#include "nsIStatefulFrame.h"
#include "nsCSSFrameConstructor.h"
class nsIFrame;
@ -377,7 +378,8 @@ protected:
* and attaches an editor to the subdocument.
******************************************************************************/
class nsGfxTextControlFrame : public nsTextControlFrame,
class nsGfxTextControlFrame : public nsFormControlFrame,
public nsIStatefulFrame,
public nsIGfxTextControlFrame
{
private:
@ -420,9 +422,6 @@ public:
NS_IMETHOD GetProperty(nsIAtom* aName, nsString& aValue);
virtual void SetFocus(PRBool aOn = PR_TRUE, PRBool aRepaint = PR_FALSE);
virtual nsWidgetInitData* GetWidgetInitData(nsIPresContext* aPresContext);
virtual void PostCreateWidget(nsIPresContext* aPresContext,
nscoord& aWidth,
nscoord& aHeight) {};
/** handler for attribute changes to mContent */
NS_IMETHOD AttributeChanged(nsIPresContext* aPresContext,
@ -451,6 +450,7 @@ public:
virtual void EnterPressed(nsIPresContext* aPresContext) ;
virtual PRInt32 GetMaxNumValues();
virtual PRBool GetNamesValues(PRInt32 aMaxNumValues, PRInt32& aNumValues,
nsString* aValues, nsString* aNames);
virtual void Reset(nsIPresContext* aPresContext);
@ -509,7 +509,14 @@ public:
NS_IMETHOD GetWebShell(nsIWebShell **aWebShell);
NS_IMETHOD SetInnerFocus();
//nsIStatefulFrame
NS_IMETHOD GetStateType(nsIPresContext* aPresContext, nsIStatefulFrame::StateType* aStateType);
NS_IMETHOD SaveState(nsIPresContext* aPresContext, nsIPresState** aState);
NS_IMETHOD RestoreState(nsIPresContext* aPresContext, nsIPresState* aState);
protected:
PRInt32 GetDefaultColumnWidth() const { return (PRInt32)(20); } // this was DEFAULT_PIXEL_WIDTH
/** calculate the inner region of the text control (size - border and padding) in pixels */
virtual void CalcSizeOfSubDocInTwips(const nsMargin &aBorder,

View File

@ -92,6 +92,7 @@ nsHTMLButtonControlFrame::nsHTMLButtonControlFrame()
nsHTMLButtonControlFrame::~nsHTMLButtonControlFrame()
{
nsFormControlFrame::RegUnRegAccessKey(mPresContext, NS_STATIC_CAST(nsIFrame*, this), PR_FALSE);
if (mFormFrame) {
mFormFrame->RemoveFormControlFrame(*this);
mFormFrame = nsnull;
@ -513,15 +514,18 @@ nsHTMLButtonControlFrame::Reflow(nsIPresContext* aPresContext,
nsReflowStatus& aStatus)
{
if (!mFormFrame && (eReflowReason_Initial == aReflowState.reason)) {
mPresContext = aPresContext;
nsFormControlFrame::RegUnRegAccessKey(aPresContext, NS_STATIC_CAST(nsIFrame*, this), PR_TRUE);
nsFormFrame::AddFormControlFrame(aPresContext, *NS_STATIC_CAST(nsIFrame*, this));
}
#if 0
nsresult skiprv = nsFormControlFrame::SkipResizeReflow(mCacheSize, mCachedMaxElementSize, aPresContext,
aDesiredSize, aReflowState, aStatus);
if (NS_SUCCEEDED(skiprv)) {
return skiprv;
}
#endif
// XXX remove the following when the reflow state is fixed
ButtonHack((nsHTMLReflowState&)aReflowState, "html4 button");
@ -662,10 +666,12 @@ nsHTMLButtonControlFrame::Reflow(nsIPresContext* aPresContext,
//aDesiredSize.width += aReflowState.mComputedBorderPadding.left + aReflowState.mComputedBorderPadding.right;
//aDesiredSize.height += aReflowState.mComputedBorderPadding.top + aReflowState.mComputedBorderPadding.bottom;
#if 1
//adjust our max element size, if necessary
if (aDesiredSize.maxElementSize) {
aDesiredSize.AddBorderPaddingToMaxElementSize(aReflowState.mComputedBorderPadding);
}
#endif
aDesiredSize.ascent = aDesiredSize.height;
aDesiredSize.descent = 0;
@ -684,11 +690,10 @@ nsHTMLButtonControlFrame::GetSkipSides() const
}
NS_IMETHODIMP
nsHTMLButtonControlFrame::GetFont(nsIPresContext* aPresContext,
const nsFont*& aFont)
nsHTMLButtonControlFrame::GetFont(nsIPresContext* aPresContext,
const nsFont*& aFont)
{
nsFormControlHelper::GetFont(this, aPresContext, mStyleContext, aFont);
return NS_OK;
return nsFormControlHelper::GetFont(this, aPresContext, mStyleContext, aFont);
}
NS_IMETHODIMP

View File

@ -156,6 +156,8 @@ protected:
PRBool mDidInit;
nsButtonFrameRenderer mRenderer;
nsCOMPtr<nsIPresContext> mPresContext;
//Resize Reflow OpitmizationSize;
nsSize mCacheSize;
nsSize mCachedMaxElementSize;

View File

@ -46,6 +46,7 @@
#include "nsIHTMLAttributes.h"
#include "nsGenericHTMLElement.h"
#include "nsFormFrame.h"
#include "nsFormControlFrame.h"
//Enumeration of possible mouse states used to detect mouse clicks
/*enum nsMouseState {
@ -145,6 +146,8 @@ protected:
nsCursor mPreviousCursor;
nsRect mTranslatedRect;
PRBool mGotFocus;
nsCOMPtr<nsIPresContext> mPresContext;
};
@ -160,6 +163,8 @@ nsImageControlFrame::nsImageControlFrame()
nsImageControlFrame::~nsImageControlFrame()
{
nsFormControlFrame::RegUnRegAccessKey(mPresContext, NS_STATIC_CAST(nsIFrame*, this), PR_FALSE);
if (mFormFrame) {
mFormFrame->RemoveFormControlFrame(*this);
mFormFrame = nsnull;
@ -255,6 +260,8 @@ nsImageControlFrame::Reflow(nsIPresContext* aPresContext,
nsReflowStatus& aStatus)
{
if (!mFormFrame && (eReflowReason_Initial == aReflowState.reason)) {
mPresContext = aPresContext;
nsFormControlFrame::RegUnRegAccessKey(aPresContext, NS_STATIC_CAST(nsIFrame*, this), PR_TRUE);
// add ourself as an nsIFormControlFrame
nsFormFrame::AddFormControlFrame(aPresContext, *NS_STATIC_CAST(nsIFrame*, this));
}

View File

@ -54,18 +54,10 @@
#include "nsIDocument.h"
#include "nsIHTMLDocument.h"
#include "nsIDOMHTMLAnchorElement.h"
#include "nsFormControlFrame.h"
#include "nsIFocusableContent.h"
//Enumeration of possible mouse states used to detect mouse clicks
enum nsMouseState {
eMouseNone,
eMouseEnter,
eMouseExit,
eMouseDown,
eMouseUp
};
static NS_DEFINE_IID(kIFormControlIID, NS_IFORMCONTROL_IID);
static NS_DEFINE_IID(kIFormControlFrameIID, NS_IFORMCONTROLFRAME_IID);
static NS_DEFINE_IID(kViewCID, NS_VIEW_CID);
@ -78,6 +70,7 @@ class nsLabelFrame : public nsHTMLContainerFrame
{
public:
nsLabelFrame();
virtual ~nsLabelFrame();
NS_IMETHOD Init(nsIPresContext* aPresContext,
nsIContent* aContent,
@ -127,6 +120,8 @@ protected:
PRBool mControlIsInside;
nsIFormControlFrame* mControlFrame;
nsRect mTranslatedRect;
nsCOMPtr<nsIPresContext> mPresContext;
};
nsresult
@ -155,6 +150,11 @@ nsLabelFrame::nsLabelFrame()
mTranslatedRect = nsRect(0,0,0,0);
}
nsLabelFrame::~nsLabelFrame()
{
nsFormControlFrame::RegUnRegAccessKey(mPresContext, NS_STATIC_CAST(nsIFrame*, this), PR_FALSE);
}
void
nsLabelFrame::GetTranslatedRect(nsIPresContext* aPresContext, nsRect& aRect)
{
@ -541,7 +541,10 @@ nsLabelFrame::Reflow(nsIPresContext* aPresContext,
aReflowState.reflowCommand->GetNext(nextFrame);
NS_ASSERTION(nextFrame == mFrames.FirstChild(), "unexpected next reflow command frame");
}
}
} else if (eReflowReason_Initial == aReflowState.reason) {
mPresContext = aPresContext;
nsFormControlFrame::RegUnRegAccessKey(aPresContext, NS_STATIC_CAST(nsIFrame*, this), PR_TRUE);
}
// XXX remove the following when the reflow state is fixed
LabelHack((nsHTMLReflowState&)aReflowState, "BUG - label");

View File

@ -30,7 +30,6 @@
#include "nsIFrame.h"
#include "nsISupports.h"
#include "nsIAtom.h"
#include "nsIPresContext.h"
#include "nsIHTMLContent.h"
#include "nsHTMLIIDs.h"
#include "nsHTMLParts.h"
@ -39,6 +38,7 @@
#include "nsStyleConsts.h"
#include "nsStyleUtil.h"
#include "nsFont.h"
#include "nsFormControlFrame.h"
static NS_DEFINE_IID(kLegendFrameCID, NS_LEGEND_FRAME_CID);
static NS_DEFINE_IID(kIDOMHTMLLegendElementIID, NS_IDOMHTMLLEGENDELEMENT_IID);
@ -63,6 +63,11 @@ nsLegendFrame::nsLegendFrame()
{
}
nsLegendFrame::~nsLegendFrame()
{
nsFormControlFrame::RegUnRegAccessKey(mPresContext, NS_STATIC_CAST(nsIFrame*, this), PR_FALSE);
}
// Frames are not refcounted, no need to AddRef
NS_IMETHODIMP
nsLegendFrame::QueryInterface(REFNSIID aIID, void** aInstancePtrResult)
@ -78,6 +83,20 @@ nsLegendFrame::QueryInterface(REFNSIID aIID, void** aInstancePtrResult)
return nsHTMLContainerFrame::QueryInterface(aIID, aInstancePtrResult);
}
NS_IMETHODIMP
nsLegendFrame::Reflow(nsIPresContext* aPresContext,
nsHTMLReflowMetrics& aDesiredSize,
const nsHTMLReflowState& aReflowState,
nsReflowStatus& aStatus)
{
if (eReflowReason_Initial == aReflowState.reason) {
mPresContext = aPresContext;
nsFormControlFrame::RegUnRegAccessKey(aPresContext, NS_STATIC_CAST(nsIFrame*, this), PR_TRUE);
}
return nsAreaFrame::Reflow(aPresContext, aDesiredSize, aReflowState, aStatus);
}
PRInt32 nsLegendFrame::GetAlign()
{
PRInt32 intValue = NS_STYLE_TEXT_ALIGN_LEFT;

View File

@ -24,6 +24,9 @@
#define nsLegendFrame_h___
#include "nsAreaFrame.h"
#include "nsIPresContext.h"
#include "nsCOMPtr.h"
class nsIContent;
class nsIFrame;
class nsIPresContext;
@ -38,14 +41,23 @@ class nsLegendFrame : public nsAreaFrame {
public:
nsLegendFrame();
virtual ~nsLegendFrame();
NS_IMETHOD QueryInterface(const nsIID& aIID, void** aInstancePtr);
NS_IMETHOD Reflow(nsIPresContext* aPresContext,
nsHTMLReflowMetrics& aDesiredSize,
const nsHTMLReflowState& aReflowState,
nsReflowStatus& aStatus);
#ifdef NS_DEBUG
NS_IMETHOD GetFrameName(nsString& aResult) const;
#endif
PRInt32 GetAlign();
nsCOMPtr<nsIPresContext> mPresContext;
};

View File

@ -123,6 +123,8 @@ nsListControlFrame::nsListControlFrame()
//---------------------------------------------------------
nsListControlFrame::~nsListControlFrame()
{
nsFormControlFrame::RegUnRegAccessKey(mPresContext, NS_STATIC_CAST(nsIFrame*, this), PR_FALSE);
// if list is dropped down
// make sure it gets rolled up
if (IsInDropDownMode()) {
@ -286,7 +288,7 @@ nsListControlFrame::Reflow(nsIPresContext* aPresContext,
const nsHTMLReflowState& aReflowState,
nsReflowStatus& aStatus)
{
#ifdef DEBUG_rodsXXX
#ifdef DEBUG_rods
printf("nsListControlFrame::Reflow Reason: ");
switch (aReflowState.reason) {
case eReflowReason_Initial:printf("eReflowReason_Initial\n");break;
@ -355,6 +357,7 @@ nsListControlFrame::Reflow(nsIPresContext* aPresContext,
mHasBeenInitialized = PR_TRUE;
InitSelectionCache(-1); // Reset sel cache so as not to send event
Reset(mPresContext);
#if 1
nsCOMPtr<nsIReflowCommand> cmd;
nsresult rv = NS_NewHTMLReflowCommand(getter_AddRefs(cmd), this, nsIReflowCommand::StyleChanged);
if (NS_FAILED(rv)) { return rv; }
@ -368,10 +371,18 @@ nsListControlFrame::Reflow(nsIPresContext* aPresContext,
rv = shell->AppendReflowCommand(cmd);
// must do this next line regardless of result of AppendReflowCommand
shell->ExitReflowLock(PR_TRUE);
#else
if (mParent) {
nsCOMPtr<nsIPresShell> shell;
nsresult rv = mPresContext->GetShell(getter_AddRefs(shell));
mState |= NS_FRAME_IS_DIRTY;
mParent->ReflowDirtyChild(shell, (nsIFrame*) this);
}
#endif
}
}
#if 1
#if 0
nsresult skiprv = nsFormControlFrame::SkipResizeReflow(mCacheSize, mCachedMaxElementSize, aPresContext,
aDesiredSize, aReflowState, aStatus);
if (NS_SUCCEEDED(skiprv)) {
@ -416,6 +427,7 @@ nsListControlFrame::Reflow(nsIPresContext* aPresContext,
// Add the list frame as a child of the form
if (IsInDropDownMode() == PR_FALSE && !mFormFrame && (eReflowReason_Initial == aReflowState.reason)) {
nsFormControlFrame::RegUnRegAccessKey(aPresContext, NS_STATIC_CAST(nsIFrame*, this), PR_TRUE);
nsFormFrame::AddFormControlFrame(aPresContext, *NS_STATIC_CAST(nsIFrame*, this));
}
@ -1943,6 +1955,17 @@ nsListControlFrame::AddOption(nsIPresContext* aPresContext, PRInt32 aIndex)
Reset(aPresContext); // this sets mSelectedIndex to the defaulted selection
wasReset = PR_TRUE;
}
#if DEBUG_rods
{
nsAutoString text = "No Value";
nsresult rv = option->GetLabel(text);
if (NS_CONTENT_ATTR_NOT_THERE == rv || 0 == text.Length()) {
option->GetText(text);
}
printf("this %p Index: %d [%s] CB: %p\n", this, aIndex, text.ToNewCString(), mComboboxFrame); //leaks
}
#endif
}
}
@ -2468,6 +2491,30 @@ void nsListControlFrame::ResetSelectedItem()
}
}
//----------------------------------------------------------------------
// helper
//----------------------------------------------------------------------
PRBool
nsListControlFrame::IsLeftButton(nsIDOMEvent* aMouseEvent)
{
// only allow selection with the left button
nsCOMPtr<nsIDOMMouseEvent> mouseEvent = do_QueryInterface(aMouseEvent);
if (mouseEvent) {
PRUint16 whichButton;
if (NS_SUCCEEDED(mouseEvent->GetButton(&whichButton))) {
if (whichButton != 1) {
aMouseEvent->PreventDefault();
aMouseEvent->PreventCapture();
aMouseEvent->PreventBubble();
return PR_FALSE;
} else {
return PR_TRUE;
}
}
}
return PR_FALSE;
}
//----------------------------------------------------------------------
// nsIDOMMouseListener
//----------------------------------------------------------------------
@ -2479,6 +2526,11 @@ nsListControlFrame::MouseUp(nsIDOMEvent* aMouseEvent)
return NS_OK;
}
// only allow selection with the left button
if (!IsLeftButton(aMouseEvent)) {
return NS_ERROR_FAILURE; // means consume event
}
// Check to see if the disabled option was clicked on
// NS_ERROR_FAILURE is returned is it isn't over an option
PRBool optionIsDisabled;
@ -2512,7 +2564,11 @@ nsListControlFrame::MouseUp(nsIDOMEvent* aMouseEvent)
UpdateSelection(PR_TRUE, PR_FALSE, mContent);
}
return NS_OK;
aMouseEvent->PreventDefault();
aMouseEvent->PreventCapture();
aMouseEvent->PreventBubble();
return NS_ERROR_FAILURE;
//return NS_OK;
}
//---------------------------------------------------------
@ -2579,6 +2635,11 @@ nsListControlFrame::MouseDown(nsIDOMEvent* aMouseEvent)
return NS_OK;
}
// only allow selection with the left button
if (!IsLeftButton(aMouseEvent)) {
return NS_ERROR_FAILURE; // means consume event
}
// Check to see if the disabled option was clicked on
// NS_ERROR_FAILURE is returned is it isn't over an option
PRBool optionIsDisabled;
@ -2673,7 +2734,11 @@ nsListControlFrame::MouseDown(nsIDOMEvent* aMouseEvent)
}
}
}
return NS_OK;
aMouseEvent->PreventDefault();
aMouseEvent->PreventCapture();
aMouseEvent->PreventBubble();
return NS_ERROR_FAILURE; //consumes event
//return NS_OK;
}
//----------------------------------------------------------------------

View File

@ -217,6 +217,7 @@ protected:
PRBool HasSameContent(nsIFrame* aFrame1, nsIFrame* aFrame2);
void HandleListSelection(nsIDOMEvent * aDOMEvent);
PRInt32 GetSelectedIndexFromFrame(nsIFrame *aHitFrame);
PRBool IsLeftButton(nsIDOMEvent* aMouseEvent);
// onChange detection
nsresult InitSelectionCache(PRInt32 aLength);

View File

@ -70,8 +70,6 @@ public:
virtual void Reset(nsIPresContext* aPresContext);
virtual const nsIID& GetCID();
virtual const nsIID& GetIID();
//
// XXX: The following paint methods are TEMPORARY. It is being used to get printing working
// under windows. Later it may be used to GFX-render the controls to the display.

View File

@ -38,20 +38,20 @@ nsRadioControlGroup::GetRadioCount() const
return mRadios.Count();
}
nsRadioControlFrame*
nsGfxRadioControlFrame*
nsRadioControlGroup::GetRadioAt(PRInt32 aIndex) const
{
return (nsRadioControlFrame*) mRadios.ElementAt(aIndex);
return (nsGfxRadioControlFrame*) mRadios.ElementAt(aIndex);
}
PRBool
nsRadioControlGroup::AddRadio(nsRadioControlFrame* aRadio)
nsRadioControlGroup::AddRadio(nsGfxRadioControlFrame* aRadio)
{
return mRadios.AppendElement(aRadio);
}
PRBool
nsRadioControlGroup::RemoveRadio(nsRadioControlFrame* aRadio)
nsRadioControlGroup::RemoveRadio(nsGfxRadioControlFrame* aRadio)
{
if (aRadio == mCheckedRadio) {
mCheckedRadio = nsnull;
@ -59,14 +59,14 @@ nsRadioControlGroup::RemoveRadio(nsRadioControlFrame* aRadio)
return mRadios.RemoveElement(aRadio);
}
nsRadioControlFrame*
nsGfxRadioControlFrame*
nsRadioControlGroup::GetCheckedRadio()
{
return mCheckedRadio;
}
void
nsRadioControlGroup::SetCheckedRadio(nsRadioControlFrame* aRadio)
nsRadioControlGroup::SetCheckedRadio(nsGfxRadioControlFrame* aRadio)
{
mCheckedRadio = aRadio;
}

View File

@ -23,7 +23,7 @@
#ifndef nsRadioControlGroup_h___
#define nsRadioControlGroup_h___
#include "nsRadioControlFrame.h"
#include "nsGfxRadioControlFrame.h"
class nsRadioControlGroup
@ -32,19 +32,21 @@ public:
nsRadioControlGroup(nsString& aName);
virtual ~nsRadioControlGroup();
PRBool AddRadio(nsRadioControlFrame* aRadio);
PRBool AddRadio(nsGfxRadioControlFrame* aRadio);
PRInt32 GetRadioCount() const;
nsRadioControlFrame* GetRadioAt(PRInt32 aIndex) const;
PRBool RemoveRadio(nsRadioControlFrame* aRadio);
nsGfxRadioControlFrame* GetRadioAt(PRInt32 aIndex) const;
PRInt32 GetNumRadios() const { return mRadios.Count(); }
nsRadioControlFrame* GetCheckedRadio();
void SetCheckedRadio(nsRadioControlFrame* aRadio);
PRBool RemoveRadio(nsGfxRadioControlFrame* aRadio);
nsGfxRadioControlFrame* GetCheckedRadio();
void SetCheckedRadio(nsGfxRadioControlFrame* aRadio);
void GetName(nsString& aNameResult) const;
protected:
nsString mName;
nsVoidArray mRadios;
nsRadioControlFrame* mCheckedRadio;
nsGfxRadioControlFrame* mCheckedRadio;
};

View File

@ -30,7 +30,6 @@
#include "nsIHTMLContent.h"
#include "nsHTMLIIDs.h"
#include "nsITextWidget.h"
#include "nsITextAreaWidget.h"
#include "nsWidgetsCID.h"
#include "nsSize.h"
#include "nsString.h"