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 550132c65d
commit 226e0b0cb2
52 changed files with 2113 additions and 262 deletions

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;