now use CSS style to get colors for rendering. Checkboxes also use the CSS border rendering code. Added New utility methods to nsFormControlFrame to PaintCircular backgrounds and borders. Set compiler directive to gfx-render radiobuttons and checkboxes both for printing and on-screen display. git-svn-id: svn://10.0.0.236/trunk@20146 18797224-902f-48f8-a5cc-f745e15eee43
417 lines
12 KiB
C++
417 lines
12 KiB
C++
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
|
*
|
|
* The contents of this file are subject to the Netscape Public License
|
|
* Version 1.0 (the "NPL"); you may not use this file except in
|
|
* compliance with the NPL. You may obtain a copy of the NPL at
|
|
* http://www.mozilla.org/NPL/
|
|
*
|
|
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
|
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
|
* for the specific language governing rights and limitations under the
|
|
* NPL.
|
|
*
|
|
* The Initial Developer of this code under the NPL is Netscape
|
|
* Communications Corporation. Portions created by Netscape are
|
|
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
|
* Reserved.
|
|
*/
|
|
|
|
#include "nsFileControlFrame.h"
|
|
#include "nsFormControlHelper.h"
|
|
#include "nsButtonControlFrame.h"
|
|
#include "nsHTMLParts.h"
|
|
#include "nsIRenderingContext.h"
|
|
#include "nsIPresContext.h"
|
|
#include "nsIPresShell.h"
|
|
#include "nsIStyleContext.h"
|
|
#include "nsLeafFrame.h"
|
|
#include "nsCSSRendering.h"
|
|
#include "nsHTMLIIDs.h"
|
|
#include "nsIButton.h"
|
|
#include "nsIViewManager.h"
|
|
#include "nsISupports.h"
|
|
#include "nsHTMLAtoms.h"
|
|
#include "nsIButton.h"
|
|
#include "nsIView.h"
|
|
#include "nsViewsCID.h"
|
|
#include "nsWidgetsCID.h"
|
|
#include "nsIDeviceContext.h"
|
|
#include "nsIFontMetrics.h"
|
|
#include "nsIFormControl.h"
|
|
#include "nsStyleUtil.h"
|
|
#include "nsDOMEvent.h"
|
|
#include "nsStyleConsts.h"
|
|
#include "nsIHTMLAttributes.h"
|
|
#include "nsGenericHTMLElement.h"
|
|
#include "nsFormFrame.h"
|
|
#include "nsILookAndFeel.h"
|
|
|
|
static NS_DEFINE_IID(kIFormControlIID, NS_IFORMCONTROL_IID);
|
|
static NS_DEFINE_IID(kIButtonIID, NS_IBUTTON_IID);
|
|
static NS_DEFINE_IID(kLookAndFeelCID, NS_LOOKANDFEEL_CID);
|
|
static NS_DEFINE_IID(kILookAndFeelIID, NS_ILOOKANDFEEL_IID);
|
|
|
|
void
|
|
nsButtonControlFrame::GetDefaultLabel(nsString& aString)
|
|
{
|
|
PRInt32 type;
|
|
GetType(&type);
|
|
if (NS_FORM_INPUT_RESET == type) {
|
|
aString = "Reset";
|
|
}
|
|
else if (NS_FORM_INPUT_SUBMIT == type) {
|
|
aString = "Submit Query";
|
|
}
|
|
else if (NS_FORM_BROWSE == type) {
|
|
aString = "Browse...";
|
|
}
|
|
else {
|
|
aString = " ";
|
|
}
|
|
}
|
|
|
|
PRBool
|
|
nsButtonControlFrame::IsSuccessful(nsIFormControlFrame* aSubmitter)
|
|
{
|
|
PRInt32 type;
|
|
GetType(&type);
|
|
if ((NS_FORM_INPUT_HIDDEN == type) || (this == aSubmitter)) {
|
|
return nsFormControlFrame::IsSuccessful(aSubmitter);
|
|
} else {
|
|
return PR_FALSE;
|
|
}
|
|
}
|
|
|
|
PRInt32
|
|
nsButtonControlFrame::GetMaxNumValues()
|
|
{
|
|
PRInt32 type;
|
|
GetType(&type);
|
|
if ((NS_FORM_INPUT_SUBMIT == type) || (NS_FORM_INPUT_HIDDEN == type)) {
|
|
return 1;
|
|
} else {
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
|
|
PRBool
|
|
nsButtonControlFrame::GetNamesValues(PRInt32 aMaxNumValues, PRInt32& aNumValues,
|
|
nsString* aValues, nsString* aNames)
|
|
{
|
|
nsAutoString name;
|
|
nsresult result = GetName(&name);
|
|
if ((aMaxNumValues <= 0) || (NS_CONTENT_ATTR_HAS_VALUE != result)) {
|
|
return PR_FALSE;
|
|
}
|
|
|
|
PRInt32 type;
|
|
GetType(&type);
|
|
|
|
if (NS_FORM_INPUT_RESET == type) {
|
|
aNumValues = 0;
|
|
return PR_FALSE;
|
|
} else {
|
|
nsAutoString value;
|
|
nsresult valResult = GetValue(&value);
|
|
aValues[0] = value;
|
|
aNames[0] = name;
|
|
aNumValues = 1;
|
|
return PR_TRUE;
|
|
}
|
|
}
|
|
|
|
|
|
nsresult
|
|
NS_NewButtonControlFrame(nsIFrame*& aResult)
|
|
{
|
|
aResult = new nsButtonControlFrame;
|
|
if (nsnull == aResult) {
|
|
return NS_ERROR_OUT_OF_MEMORY;
|
|
}
|
|
return NS_OK;
|
|
}
|
|
|
|
nscoord
|
|
nsButtonControlFrame::GetVerticalBorderWidth(float aPixToTwip) const
|
|
{
|
|
return NSIntPixelsToTwips(4, aPixToTwip);
|
|
}
|
|
|
|
nscoord
|
|
nsButtonControlFrame::GetHorizontalBorderWidth(float aPixToTwip) const
|
|
{
|
|
return GetVerticalBorderWidth(aPixToTwip);
|
|
}
|
|
|
|
nscoord
|
|
nsButtonControlFrame::GetVerticalInsidePadding(float aPixToTwip,
|
|
nscoord aInnerHeight) const
|
|
{
|
|
float pad;
|
|
nsILookAndFeel * lookAndFeel;
|
|
if (NS_OK == nsRepository::CreateInstance(kLookAndFeelCID, nsnull, kILookAndFeelIID, (void**)&lookAndFeel)) {
|
|
lookAndFeel->GetMetric(nsILookAndFeel::eMetricFloat_ButtonVerticalInsidePadding, pad);
|
|
NS_RELEASE(lookAndFeel);
|
|
}
|
|
return (nscoord)NSToIntRound((float)aInnerHeight * pad);
|
|
}
|
|
|
|
nscoord
|
|
nsButtonControlFrame::GetHorizontalInsidePadding(nsIPresContext& aPresContext,
|
|
float aPixToTwip,
|
|
nscoord aInnerWidth,
|
|
nscoord aCharWidth) const
|
|
{
|
|
nsCompatibility mode;
|
|
aPresContext.GetCompatibilityMode(mode);
|
|
|
|
float pad;
|
|
PRInt32 padQuirks;
|
|
PRInt32 padQuirksOffset;
|
|
nsILookAndFeel * lookAndFeel;
|
|
if (NS_OK == nsRepository::CreateInstance(kLookAndFeelCID, nsnull, kILookAndFeelIID, (void**)&lookAndFeel)) {
|
|
lookAndFeel->GetMetric(nsILookAndFeel::eMetricFloat_ButtonHorizontalInsidePadding, pad);
|
|
lookAndFeel->GetMetric(nsILookAndFeel::eMetric_ButtonHorizontalInsidePaddingNavQuirks, padQuirks);
|
|
lookAndFeel->GetMetric(nsILookAndFeel::eMetric_ButtonHorizontalInsidePaddingOffsetNavQuirks, padQuirksOffset);
|
|
NS_RELEASE(lookAndFeel);
|
|
}
|
|
if (eCompatibility_NavQuirks == mode) {
|
|
return (nscoord)NSToIntRound(float(aInnerWidth) * pad);
|
|
} else {
|
|
return NSIntPixelsToTwips(padQuirks, aPixToTwip) + padQuirksOffset;
|
|
}
|
|
}
|
|
|
|
|
|
NS_IMETHODIMP
|
|
nsButtonControlFrame::AttributeChanged(nsIPresContext* aPresContext,
|
|
nsIContent* aChild,
|
|
nsIAtom* aAttribute,
|
|
PRInt32 aHint)
|
|
{
|
|
nsresult result = NS_OK;
|
|
if (mWidget) {
|
|
if (nsHTMLAtoms::value == aAttribute) {
|
|
nsIButton* button = nsnull;
|
|
result = mWidget->QueryInterface(kIButtonIID, (void**)&button);
|
|
if ((NS_SUCCEEDED(result)) && (nsnull != button)) {
|
|
nsString value;
|
|
nsresult result = GetValue(&value);
|
|
button->SetLabel(value);
|
|
NS_RELEASE(button);
|
|
nsFormFrame::StyleChangeReflow(aPresContext, this);
|
|
}
|
|
} else if (nsHTMLAtoms::size == aAttribute) {
|
|
nsFormFrame::StyleChangeReflow(aPresContext, this);
|
|
}
|
|
// Allow the base class to handle common attributes supported
|
|
// by all form elements...
|
|
else {
|
|
result = nsFormControlFrame::AttributeChanged(aPresContext, aChild, aAttribute, aHint);
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
|
|
|
|
NS_METHOD
|
|
nsButtonControlFrame::Paint(nsIPresContext& aPresContext,
|
|
nsIRenderingContext& aRenderingContext,
|
|
const nsRect& aDirtyRect,
|
|
nsFramePaintLayer aWhichLayer)
|
|
{
|
|
if (eFramePaintLayer_Content == aWhichLayer) {
|
|
PaintButton(aPresContext, aRenderingContext, aDirtyRect);
|
|
}
|
|
return NS_OK;
|
|
}
|
|
|
|
|
|
void
|
|
nsButtonControlFrame::MouseClicked(nsIPresContext* aPresContext)
|
|
{
|
|
PRInt32 type;
|
|
GetType(&type);
|
|
|
|
if ((nsnull != mFormFrame) && !nsFormFrame::GetDisabled(this)) {
|
|
nsEventStatus status = nsEventStatus_eIgnore;
|
|
nsEvent event;
|
|
event.eventStructType = NS_EVENT;
|
|
nsIContent *formContent = nsnull;
|
|
mFormFrame->GetContent(formContent);
|
|
|
|
switch(type) {
|
|
case NS_FORM_INPUT_RESET:
|
|
event.message = NS_FORM_RESET;
|
|
if (nsnull != formContent) {
|
|
formContent->HandleDOMEvent(*aPresContext, &event, nsnull, DOM_EVENT_INIT, status);
|
|
}
|
|
if (nsEventStatus_eConsumeNoDefault != status) {
|
|
mFormFrame->OnReset();
|
|
}
|
|
break;
|
|
case NS_FORM_INPUT_SUBMIT:
|
|
event.message = NS_FORM_SUBMIT;
|
|
if (nsnull != formContent) {
|
|
formContent->HandleDOMEvent(*aPresContext, &event, nsnull, DOM_EVENT_INIT, status);
|
|
}
|
|
if (nsEventStatus_eConsumeNoDefault != status) {
|
|
mFormFrame->OnSubmit(aPresContext, this);
|
|
}
|
|
}
|
|
NS_IF_RELEASE(formContent);
|
|
}
|
|
//else if ((NS_FORM_BROWSE == type) && mMouseListener) {
|
|
else if (nsnull != mMouseListener) {
|
|
mMouseListener->MouseClicked(aPresContext);
|
|
}
|
|
}
|
|
|
|
NS_METHOD
|
|
nsButtonControlFrame::Reflow(nsIPresContext& aPresContext,
|
|
nsHTMLReflowMetrics& aDesiredSize,
|
|
const nsHTMLReflowState& aReflowState,
|
|
nsReflowStatus& aStatus)
|
|
{
|
|
PRInt32 type;
|
|
GetType(&type);
|
|
|
|
if (NS_FORM_INPUT_IMAGE == type) {
|
|
nsSize ignore;
|
|
GetDesiredSize(&aPresContext, aReflowState, aDesiredSize, ignore);
|
|
nsMargin bp;
|
|
AddBordersAndPadding(&aPresContext, aReflowState, aDesiredSize, bp);
|
|
if (nsnull != aDesiredSize.maxElementSize) {
|
|
aDesiredSize.AddBorderPaddingToMaxElementSize(bp);
|
|
aDesiredSize.maxElementSize->width = aDesiredSize.width;
|
|
aDesiredSize.maxElementSize->height = aDesiredSize.height;
|
|
}
|
|
aStatus = NS_FRAME_COMPLETE;
|
|
return NS_OK;
|
|
}
|
|
else {
|
|
return nsFormControlFrame:: Reflow(aPresContext, aDesiredSize, aReflowState, aStatus);
|
|
}
|
|
}
|
|
|
|
void
|
|
nsButtonControlFrame::GetDesiredSize(nsIPresContext* aPresContext,
|
|
const nsHTMLReflowState& aReflowState,
|
|
nsHTMLReflowMetrics& aDesiredLayoutSize,
|
|
nsSize& aDesiredWidgetSize)
|
|
{
|
|
PRInt32 type;
|
|
GetType(&type);
|
|
|
|
if (NS_FORM_INPUT_HIDDEN == type) { // there is no physical rep
|
|
aDesiredLayoutSize.width = 0;
|
|
aDesiredLayoutSize.height = 0;
|
|
aDesiredLayoutSize.ascent = 0;
|
|
aDesiredLayoutSize.descent = 0;
|
|
} else {
|
|
nsSize styleSize;
|
|
GetStyleSize(*aPresContext, aReflowState, styleSize);
|
|
// a browse button shares is style context with its parent nsInputFile
|
|
// it uses everything from it except width
|
|
if (NS_FORM_BROWSE == type) {
|
|
styleSize.width = CSS_NOTSET;
|
|
}
|
|
nsSize size;
|
|
PRBool widthExplicit, heightExplicit;
|
|
PRInt32 ignore;
|
|
nsAutoString defaultLabel;
|
|
GetDefaultLabel(defaultLabel);
|
|
nsInputDimensionSpec spec(nsHTMLAtoms::size, PR_TRUE, nsHTMLAtoms::value,
|
|
&defaultLabel, 1, PR_FALSE, nsnull, 1);
|
|
nsFormControlHelper::CalculateSize(aPresContext, this, styleSize, spec, size,
|
|
widthExplicit, heightExplicit, ignore,
|
|
aReflowState.rendContext);
|
|
aDesiredLayoutSize.width = size.width;
|
|
aDesiredLayoutSize.height= size.height;
|
|
aDesiredLayoutSize.ascent = aDesiredLayoutSize.height;
|
|
aDesiredLayoutSize.descent = 0;
|
|
}
|
|
|
|
aDesiredWidgetSize.width = aDesiredLayoutSize.width;
|
|
aDesiredWidgetSize.height= aDesiredLayoutSize.height;
|
|
}
|
|
|
|
|
|
void
|
|
nsButtonControlFrame::PostCreateWidget(nsIPresContext* aPresContext, nscoord& aWidth, nscoord& aHeight)
|
|
{
|
|
nsIButton* button = nsnull;
|
|
if (mWidget && (NS_OK == mWidget->QueryInterface(kIButtonIID,(void**)&button))) {
|
|
nsFont font(aPresContext->GetDefaultFixedFont());
|
|
GetFont(aPresContext, font);
|
|
mWidget->SetFont(font);
|
|
SetColors(*aPresContext);
|
|
|
|
nsAutoString value;
|
|
nsresult result = GetValue(&value);
|
|
|
|
if (NS_CONTENT_ATTR_HAS_VALUE != result) {
|
|
GetDefaultLabel(value);
|
|
}
|
|
button->SetLabel(value);
|
|
NS_RELEASE(button);
|
|
|
|
mWidget->Enable(!nsFormFrame::GetDisabled(this));
|
|
}
|
|
}
|
|
|
|
const nsIID&
|
|
nsButtonControlFrame::GetIID()
|
|
{
|
|
static NS_DEFINE_IID(kButtonIID, NS_IBUTTON_IID);
|
|
return kButtonIID;
|
|
}
|
|
|
|
const nsIID&
|
|
nsButtonControlFrame::GetCID()
|
|
{
|
|
static NS_DEFINE_IID(kButtonCID, NS_BUTTON_CID);
|
|
return kButtonCID;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
nsButtonControlFrame::GetFrameName(nsString& aResult) const
|
|
{
|
|
return MakeFrameName("ButtonControl", aResult);
|
|
}
|
|
|
|
|
|
void
|
|
nsButtonControlFrame::PaintButton(nsIPresContext& aPresContext,
|
|
nsIRenderingContext& aRenderingContext,
|
|
const nsRect& aDirtyRect)
|
|
{
|
|
|
|
nsString label;
|
|
nsresult result = GetValue(&label);
|
|
nsFormControlHelper::PaintRectangularButton(aPresContext,
|
|
aRenderingContext,
|
|
aDirtyRect, mRect.width,
|
|
mRect.height,PR_FALSE, PR_FALSE,
|
|
mStyleContext, label, this);
|
|
|
|
}
|
|
|
|
NS_IMETHODIMP nsButtonControlFrame::SetProperty(nsIAtom* aName, const nsString& aValue)
|
|
{
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP nsButtonControlFrame::GetProperty(nsIAtom* aName, nsString& aValue)
|
|
{
|
|
return NS_OK;
|
|
}
|
|
|
|
nsresult nsButtonControlFrame::RequiresWidget(PRBool& aRequiresWidget)
|
|
{
|
|
aRequiresWidget = PR_TRUE;
|
|
return NS_OK;
|
|
}
|
|
|