This commit is contained in:
Dão Gottwald 2009-04-02 12:04:29 +02:00
Родитель 76aeb9e73e 3f7e05fa09
Коммит 65f1815407
15 изменённых файлов: 246 добавлений и 64 удалений

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

@ -89,8 +89,7 @@ PaintIndeterminateMark(nsIRenderingContext& aRenderingContext,
//------------------------------------------------------------
nsIFrame*
NS_NewGfxCheckboxControlFrame(nsIPresShell* aPresShell,
nsStyleContext* aContext)
NS_NewGfxCheckboxControlFrame(nsIPresShell* aPresShell, nsStyleContext* aContext)
{
return new (aPresShell) nsGfxCheckboxControlFrame(aContext);
}
@ -112,22 +111,63 @@ NS_QUERYFRAME_HEAD(nsGfxCheckboxControlFrame)
NS_QUERYFRAME_ENTRY(nsICheckboxControlFrame)
NS_QUERYFRAME_TAIL_INHERITING(nsFormControlFrame)
#ifdef ACCESSIBILITY
NS_IMETHODIMP
nsGfxCheckboxControlFrame::GetAccessible(nsIAccessible** aAccessible)
nsGfxCheckboxControlFrame::Init(nsIContent* aContent,
nsIFrame* aParent,
nsIFrame* aPrevInFlow)
{
nsCOMPtr<nsIAccessibilityService> accService
= do_GetService("@mozilla.org/accessibilityService;1");
nsresult rv = nsFormControlFrame::Init(aContent, aParent, aPrevInFlow);
if (NS_SUCCEEDED(rv)) {
mCheckButtonFaceStyle =
PresContext()->PresShell()->StyleSet()->
ResolvePseudoStyleFor(aContent, nsCSSAnonBoxes::check,
GetStyleContext());
}
return rv;
}
#ifdef ACCESSIBILITY
NS_IMETHODIMP nsGfxCheckboxControlFrame::GetAccessible(nsIAccessible** aAccessible)
{
nsCOMPtr<nsIAccessibilityService> accService = do_GetService("@mozilla.org/accessibilityService;1");
if (accService) {
return accService->CreateHTMLCheckboxAccessible(
static_cast<nsIFrame*>(this), aAccessible);
return accService->CreateHTMLCheckboxAccessible(static_cast<nsIFrame*>(this), aAccessible);
}
return NS_ERROR_FAILURE;
}
#endif
//--------------------------------------------------------------
nsStyleContext*
nsGfxCheckboxControlFrame::GetAdditionalStyleContext(PRInt32 aIndex) const
{
switch (aIndex) {
case NS_GFX_CHECKBOX_CONTROL_FRAME_FACE_CONTEXT_INDEX:
return mCheckButtonFaceStyle;
break;
default:
return nsnull;
}
}
//--------------------------------------------------------------
void
nsGfxCheckboxControlFrame::SetAdditionalStyleContext(PRInt32 aIndex,
nsStyleContext* aStyleContext)
{
switch (aIndex) {
case NS_GFX_CHECKBOX_CONTROL_FRAME_FACE_CONTEXT_INDEX:
mCheckButtonFaceStyle = aStyleContext;
break;
}
}
//------------------------------------------------------------
NS_IMETHODIMP
nsGfxCheckboxControlFrame::OnChecked(nsPresContext* aPresContext,
@ -137,6 +177,12 @@ nsGfxCheckboxControlFrame::OnChecked(nsPresContext* aPresContext,
return NS_OK;
}
static void PaintCheckMarkFromStyle(nsIFrame* aFrame,
nsIRenderingContext* aCtx, const nsRect& aDirtyRect, nsPoint aPt) {
static_cast<nsGfxCheckboxControlFrame*>(aFrame)
->PaintCheckBoxFromStyle(*aCtx, aPt, aDirtyRect);
}
class nsDisplayCheckMark : public nsDisplayItem {
public:
nsDisplayCheckMark(nsGfxCheckboxControlFrame* aFrame)
@ -198,8 +244,45 @@ nsGfxCheckboxControlFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
if (IsThemed())
return NS_OK; // No need to paint the checkmark. The theme will do it.
return aLists.Content()->AppendNewToTop(new (aBuilder)
nsDisplayCheckMark(this));
// Paint the checkmark
if (mCheckButtonFaceStyle) {
// This code actually works now; not sure how useful it'll be
// (The purpose is to allow the UA stylesheet to substitute its own
// checkmark for the default one)
// XXXbz maybe we should just remove this, together with the
// attendant complexity
const nsStyleBackground* myBackground = mCheckButtonFaceStyle->GetStyleBackground();
if (!myBackground->IsTransparent())
return aLists.Content()->AppendNewToTop(new (aBuilder)
nsDisplayGeneric(this, PaintCheckMarkFromStyle, "CheckMarkFromStyle"));
}
return aLists.Content()->AppendNewToTop(new (aBuilder) nsDisplayCheckMark(this));
}
void
nsGfxCheckboxControlFrame::PaintCheckBoxFromStyle(
nsIRenderingContext& aRenderingContext, nsPoint aPt, const nsRect& aDirtyRect) {
const nsStylePosition* myPosition = mCheckButtonFaceStyle->GetStylePosition();
const nsStyleBorder* myBorder = mCheckButtonFaceStyle->GetStyleBorder();
const nsStyleBackground* myBackground = mCheckButtonFaceStyle->GetStyleBackground();
NS_ASSERTION(myPosition->mWidth.GetUnit() == eStyleUnit_Coord &&
myPosition->mHeight.GetUnit() == eStyleUnit_Coord,
"styles for :-moz-checkbox are incorrect or author-accessible");
nscoord width = myPosition->mWidth.GetCoordValue();
nscoord height = myPosition->mHeight.GetCoordValue();
// Position the button centered within the control's rectangle.
nscoord x = (mRect.width - width) / 2;
nscoord y = (mRect.height - height) / 2;
nsRect rect(aPt.x + x, aPt.y + y, width, height);
nsCSSRendering::PaintBackgroundWithSC(PresContext(), aRenderingContext,
this, aDirtyRect, rect, *myBackground,
*myBorder, PR_FALSE);
nsCSSRendering::PaintBorder(PresContext(), aRenderingContext, this,
aDirtyRect, rect, *myBorder,
mCheckButtonFaceStyle);
}
//------------------------------------------------------------

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

@ -73,11 +73,22 @@ public:
//nsICheckboxControlFrame methods
NS_IMETHOD OnChecked(nsPresContext* aPresContext, PRBool aChecked);
virtual nsStyleContext* GetAdditionalStyleContext(PRInt32 aIndex) const;
virtual void SetAdditionalStyleContext(PRInt32 aIndex,
nsStyleContext* aStyleContext);
NS_DECL_QUERYFRAME
NS_IMETHOD Init(nsIContent* aContent,
nsIFrame* aParent,
nsIFrame* asPrevInFlow);
void PaintCheckBox(nsIRenderingContext& aRenderingContext,
nsPoint aPt, const nsRect& aDirtyRect);
void PaintCheckBoxFromStyle(nsIRenderingContext& aRenderingContext,
nsPoint aPt, const nsRect& aDirtyRect);
protected:
PRBool IsChecked();

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

@ -66,16 +66,29 @@ NS_QUERYFRAME_HEAD(nsGfxRadioControlFrame)
NS_QUERYFRAME_ENTRY(nsIRadioControlFrame)
NS_QUERYFRAME_TAIL_INHERITING(nsFormControlFrame)
#ifdef ACCESSIBILITY
NS_IMETHODIMP
nsGfxRadioControlFrame::GetAccessible(nsIAccessible** aAccessible)
nsGfxRadioControlFrame::Init(nsIContent* aContent,
nsIFrame* aParent,
nsIFrame* aPrevInFlow)
{
nsCOMPtr<nsIAccessibilityService> accService
= do_GetService("@mozilla.org/accessibilityService;1");
nsresult rv = nsFormControlFrame::Init(aContent, aParent, aPrevInFlow);
if (NS_SUCCEEDED(rv)) {
mRadioButtonFaceStyle =
PresContext()->PresShell()->StyleSet()->
ResolvePseudoStyleFor(aContent, nsCSSAnonBoxes::radio,
GetStyleContext());
}
return rv;
}
#ifdef ACCESSIBILITY
NS_IMETHODIMP nsGfxRadioControlFrame::GetAccessible(nsIAccessible** aAccessible)
{
nsCOMPtr<nsIAccessibilityService> accService = do_GetService("@mozilla.org/accessibilityService;1");
if (accService) {
return accService->CreateHTMLRadioButtonAccessible(
static_cast<nsIFrame*>(this), aAccessible);
return accService->CreateHTMLRadioButtonAccessible(static_cast<nsIFrame*>(this), aAccessible);
}
return NS_ERROR_FAILURE;
@ -83,45 +96,120 @@ nsGfxRadioControlFrame::GetAccessible(nsIAccessible** aAccessible)
#endif
//--------------------------------------------------------------
// Draw the dot for a non-native radio button in the checked state.
static void
PaintCheckedRadioButton(nsIFrame* aFrame,
nsIRenderingContext* aCtx,
const nsRect& aDirtyRect,
nsPoint aPt)
nsStyleContext*
nsGfxRadioControlFrame::GetAdditionalStyleContext(PRInt32 aIndex) const
{
// The dot is an ellipse precisely filling the content-box, drawn in
// the foreground color.
nsRect rect(aPt, aFrame->GetSize());
rect.Deflate(aFrame->GetUsedBorderAndPadding());
aCtx->SetColor(aFrame->GetStyleColor()->mColor);
aCtx->FillEllipse(rect);
switch (aIndex) {
case NS_GFX_RADIO_CONTROL_FRAME_FACE_CONTEXT_INDEX:
return mRadioButtonFaceStyle;
break;
default:
return nsnull;
}
}
//--------------------------------------------------------------
void
nsGfxRadioControlFrame::SetAdditionalStyleContext(PRInt32 aIndex,
nsStyleContext* aStyleContext)
{
switch (aIndex) {
case NS_GFX_RADIO_CONTROL_FRAME_FACE_CONTEXT_INDEX:
mRadioButtonFaceStyle = aStyleContext;
break;
}
}
//--------------------------------------------------------------
void
nsGfxRadioControlFrame::PaintRadioButtonFromStyle(
nsIRenderingContext& aRenderingContext, nsPoint aPt, const nsRect& aDirtyRect)
{
const nsStyleBorder* myBorder = mRadioButtonFaceStyle->GetStyleBorder();
// Paint the button for the radio button using CSS background rendering code
const nsStyleBackground* myColor = mRadioButtonFaceStyle->GetStyleBackground();
const nsStyleColor* color = mRadioButtonFaceStyle->GetStyleColor();
const nsStylePosition* myPosition = mRadioButtonFaceStyle->GetStylePosition();
NS_ASSERTION(myPosition->mWidth.GetUnit() == eStyleUnit_Coord &&
myPosition->mHeight.GetUnit() == eStyleUnit_Coord,
"styles for :-moz-radio are incorrect or author-accessible");
nscoord width = myPosition->mWidth.GetCoordValue();
nscoord height = myPosition->mHeight.GetCoordValue();
// Position the button centered within the radio control's rectangle.
nscoord x = (mRect.width - width) / 2;
nscoord y = (mRect.height - height) / 2;
nsRect rect = nsRect(x, y, width, height) + aPt;
// So we will use PaintBackgroundWithSC to paint the dot,
// but it uses the mBackgroundColor for painting and we need to use the mColor
// so create a temporary style color struct and set it up appropriately
// XXXldb It would make more sense to use
// |aRenderingContext.FillEllipse| here, but on at least GTK that
// doesn't draw a round enough circle.
nsStyleBackground tmpColor = *myColor;
tmpColor.mBackgroundColor = color->mColor;
nsPresContext* pc = PresContext();
nsCSSRendering::PaintBackgroundWithSC(pc, aRenderingContext,
this, aDirtyRect, rect,
tmpColor, *myBorder, PR_FALSE);
nsCSSRendering::PaintBorder(pc, aRenderingContext, this,
aDirtyRect, rect, *myBorder, mRadioButtonFaceStyle, 0);
}
class nsDisplayRadioButtonFromStyle : public nsDisplayItem {
public:
nsDisplayRadioButtonFromStyle(nsGfxRadioControlFrame* aFrame)
: nsDisplayItem(aFrame) {
MOZ_COUNT_CTOR(nsDisplayRadioButtonFromStyle);
}
#ifdef NS_BUILD_REFCNT_LOGGING
virtual ~nsDisplayRadioButtonFromStyle() {
MOZ_COUNT_DTOR(nsDisplayRadioButtonFromStyle);
}
#endif
virtual void Paint(nsDisplayListBuilder* aBuilder, nsIRenderingContext* aCtx,
const nsRect& aDirtyRect);
NS_DISPLAY_DECL_NAME("RadioButton")
};
void
nsDisplayRadioButtonFromStyle::Paint(nsDisplayListBuilder* aBuilder,
nsIRenderingContext* aCtx, const nsRect& aDirtyRect) {
static_cast<nsGfxRadioControlFrame*>(mFrame)->
PaintRadioButtonFromStyle(*aCtx, aBuilder->ToReferenceFrame(mFrame), aDirtyRect);
}
//--------------------------------------------------------------
NS_IMETHODIMP
nsGfxRadioControlFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
const nsRect& aDirtyRect,
const nsDisplayListSet& aLists)
{
nsresult rv = nsFormControlFrame::BuildDisplayList(aBuilder, aDirtyRect,
aLists);
nsresult rv = nsFormControlFrame::BuildDisplayList(aBuilder, aDirtyRect, aLists);
NS_ENSURE_SUCCESS(rv, rv);
if (!IsVisibleForPainting(aBuilder))
return NS_OK;
if (IsThemed())
return NS_OK; // The theme will paint the check, if any.
return NS_OK; // No need to paint the radio button. The theme will do it.
if (!mRadioButtonFaceStyle)
return NS_OK;
PRBool checked = PR_TRUE;
GetCurrentCheckState(&checked); // Get check state from the content model
if (!checked)
return NS_OK;
return aLists.Content()->AppendNewToTop(new (aBuilder)
nsDisplayGeneric(this, PaintCheckedRadioButton, "CheckedRadioButton"));
nsDisplayRadioButtonFromStyle(this));
}
//--------------------------------------------------------------
NS_IMETHODIMP
nsGfxRadioControlFrame::OnChecked(nsPresContext* aPresContext,
PRBool aChecked)
@ -129,3 +217,4 @@ nsGfxRadioControlFrame::OnChecked(nsPresContext* aPresContext,
InvalidateOverflowRect();
return NS_OK;
}

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

@ -47,24 +47,45 @@ class nsIAccessible;
// 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 nsFormControlFrame,
public nsIRadioControlFrame
{
private:
public:
nsGfxRadioControlFrame(nsStyleContext* aContext);
~nsGfxRadioControlFrame();
NS_DECL_QUERYFRAME
//nsIRadioControlFrame methods
NS_IMETHOD Init(nsIContent* aContent,
nsIFrame* aParent,
nsIFrame* asPrevInFlow);
#ifdef ACCESSIBILITY
NS_IMETHOD GetAccessible(nsIAccessible** aAccessible);
#endif
NS_IMETHOD OnChecked(nsPresContext* aPresContext, PRBool aChecked);
virtual nsStyleContext* GetAdditionalStyleContext(PRInt32 aIndex) const;
virtual void SetAdditionalStyleContext(PRInt32 aIndex,
nsStyleContext* aStyleContext);
NS_IMETHOD BuildDisplayList(nsDisplayListBuilder* aBuilder,
const nsRect& aDirtyRect,
const nsDisplayListSet& aLists);
void PaintRadioButtonFromStyle(nsIRenderingContext& aRenderingContext, nsPoint aPt,
const nsRect& aDirtyRect);
protected:
nsRefPtr<nsStyleContext> mRadioButtonFaceStyle;
};
#endif

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

@ -1,2 +0,0 @@
<!doctype html>
<input type="checkbox">

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

@ -1,2 +0,0 @@
<!doctype html>
<input type="checkbox" checked>

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

@ -1,2 +0,0 @@
<!doctype html>
<input type="checkbox" style="-moz-appearance:none">

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

@ -1,2 +0,0 @@
<!doctype html>
<input type="checkbox" style="-moz-appearance:none" checked>

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

@ -1,2 +0,0 @@
<!doctype html>
<input type="radio">

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

@ -1,2 +0,0 @@
<!doctype html>
<input type="radio" checked>

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

@ -1,2 +0,0 @@
<!doctype html>
<input type="radio" style="-moz-appearance:none">

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

@ -1,2 +0,0 @@
<!doctype html>
<input type="radio" style="-moz-appearance:none" checked>

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

@ -1,4 +1,3 @@
== checkbox-label-dynamic.html checkbox-label-dynamic-ref.html
== checkbox-radio-stretched.html checkbox-radio-stretched-ref.html # bug 464589
== input-file-width-clip-1.html input-file-width-clip-ref.html # bug 409587
@ -11,17 +10,3 @@
!= indeterminate-native-checked.html indeterminate-native-checked-notref.html
!= indeterminate-native-unchecked.html indeterminate-native-unchecked-notref.html
== indeterminate-selector.html indeterminate-selector-ref.html
!= checkbox-checked.html checkbox-checked-notref.html
!= checkbox-checked-native.html checkbox-checked-native-notref.html
!= radio-checked.html radio-checked-notref.html
!= radio-checked-native.html radio-checked-native-notref.html
!= checkbox-checked.html about:blank
!= checkbox-checked-notref.html about:blank
!= radio-checked.html about:blank
!= radio-checked-notref.html about:blank
!= checkbox-checked-native.html about:blank
!= checkbox-checked-native-notref.html about:blank
!= radio-checked-native.html about:blank
!= radio-checked-native-notref.html about:blank

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

@ -408,7 +408,7 @@ input[type="radio"] {
width: 13px;
height: 13px;
margin: 3px 3px 0px 5px;
padding: 2px !important; /* padding controls size of dot in checked state */
padding: 0 !important;
cursor: default;
-moz-binding: none;
@ -466,6 +466,13 @@ input[type="radio"]:hover:active {
border-style: inset !important;
}
*|*::-moz-radio {
width: 4px;
height: 4px;
background-color: -moz-FieldText ! important;
-moz-border-radius: 3px;
}
/* buttons */
/* Note: Values in nsNativeTheme IsWidgetStyled function

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

@ -67,6 +67,8 @@ CSS_ANON_BOX(cellContent, ":-moz-cell-content")
CSS_ANON_BOX(dropDownList, ":-moz-dropdown-list")
CSS_ANON_BOX(fieldsetContent, ":-moz-fieldset-content")
CSS_ANON_BOX(framesetBlank, ":-moz-frameset-blank")
CSS_ANON_BOX(radio, ":-moz-radio")
CSS_ANON_BOX(check, ":-moz-checkbox")
CSS_ANON_BOX(mozDisplayComboboxControlFrame, ":-moz-display-comboboxcontrol-frame")
CSS_ANON_BOX(inlineTable, ":-moz-inline-table")