author | Wes Kocher <wkocher@mozilla.com> |
Wed, 02 Nov 2016 17:13:21 -0700 | |
changeset 350817 | 7a2381a43ae591c8d0b9138fce0384b66955d5ed |
parent 350816 | 10353378f4fa71d2865344fb35ef5b7513c905b4 |
child 350818 | 0ad230a32984920ee0350ad4fdd00b543f449759 |
push id | unknown |
push user | unknown |
push date | unknown |
reviewers | backout |
bugs | 418833 |
milestone | 52.0a1 |
backs out | 872ebe45f2f6a650a22097348c99c5c268343406 c875e87e5301a75613c22c99172efd12106b8e98 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
layout/forms/nsGfxCheckboxControlFrame.cpp | file | annotate | diff | comparison | revisions | |
layout/forms/nsGfxCheckboxControlFrame.h | file | annotate | diff | comparison | revisions | |
layout/forms/nsGfxRadioControlFrame.cpp | file | annotate | diff | comparison | revisions | |
layout/forms/nsGfxRadioControlFrame.h | file | annotate | diff | comparison | revisions | |
layout/style/jar.mn | file | annotate | diff | comparison | revisions | |
layout/style/res/checkmark.svg | file | annotate | diff | comparison | revisions | |
layout/style/res/forms.css | file | annotate | diff | comparison | revisions | |
layout/style/res/indeterminate-checkmark.svg | file | annotate | diff | comparison | revisions | |
layout/style/res/radio.svg | file | annotate | diff | comparison | revisions |
--- a/layout/forms/nsGfxCheckboxControlFrame.cpp +++ b/layout/forms/nsGfxCheckboxControlFrame.cpp @@ -13,16 +13,72 @@ #include "nsRenderingContext.h" #include "nsIDOMHTMLInputElement.h" #include "nsDisplayList.h" #include <algorithm> using namespace mozilla; using namespace mozilla::gfx; +static void +PaintCheckMark(nsIFrame* aFrame, + DrawTarget* aDrawTarget, + const nsRect& aDirtyRect, + nsPoint aPt) +{ + nsRect rect(aPt, aFrame->GetSize()); + rect.Deflate(aFrame->GetUsedBorderAndPadding()); + + // Points come from the coordinates on a 7X7 unit box centered at 0,0 + const int32_t checkPolygonX[] = { -3, -1, 3, 3, -1, -3 }; + const int32_t checkPolygonY[] = { -1, 1, -3, -1, 3, 1 }; + const int32_t checkNumPoints = sizeof(checkPolygonX) / sizeof(int32_t); + const int32_t checkSize = 9; // 2 units of padding on either side + // of the 7x7 unit checkmark + + // Scale the checkmark based on the smallest dimension + nscoord paintScale = std::min(rect.width, rect.height) / checkSize; + nsPoint paintCenter(rect.x + rect.width / 2, + rect.y + rect.height / 2); + + RefPtr<PathBuilder> builder = aDrawTarget->CreatePathBuilder(); + nsPoint p = paintCenter + nsPoint(checkPolygonX[0] * paintScale, + checkPolygonY[0] * paintScale); + + int32_t appUnitsPerDevPixel = aFrame->PresContext()->AppUnitsPerDevPixel(); + builder->MoveTo(NSPointToPoint(p, appUnitsPerDevPixel)); + for (int32_t polyIndex = 1; polyIndex < checkNumPoints; polyIndex++) { + p = paintCenter + nsPoint(checkPolygonX[polyIndex] * paintScale, + checkPolygonY[polyIndex] * paintScale); + builder->LineTo(NSPointToPoint(p, appUnitsPerDevPixel)); + } + RefPtr<Path> path = builder->Finish(); + aDrawTarget->Fill(path, + ColorPattern(ToDeviceColor(aFrame->StyleColor()->mColor))); +} + +static void +PaintIndeterminateMark(nsIFrame* aFrame, + DrawTarget* aDrawTarget, + const nsRect& aDirtyRect, + nsPoint aPt) +{ + int32_t appUnitsPerDevPixel = aFrame->PresContext()->AppUnitsPerDevPixel(); + + nsRect rect(aPt, aFrame->GetSize()); + rect.Deflate(aFrame->GetUsedBorderAndPadding()); + rect.y += (rect.height - rect.height/4) / 2; + rect.height /= 4; + + Rect devPxRect = NSRectToSnappedRect(rect, appUnitsPerDevPixel, *aDrawTarget); + + aDrawTarget->FillRect( + devPxRect, ColorPattern(ToDeviceColor(aFrame->StyleColor()->mColor))); +} + //------------------------------------------------------------ nsIFrame* NS_NewGfxCheckboxControlFrame(nsIPresShell* aPresShell, nsStyleContext* aContext) { return new (aPresShell) nsGfxCheckboxControlFrame(aContext); } @@ -44,16 +100,39 @@ nsGfxCheckboxControlFrame::~nsGfxCheckbo a11y::AccType nsGfxCheckboxControlFrame::AccessibleType() { return a11y::eHTMLCheckboxType; } #endif //------------------------------------------------------------ +void +nsGfxCheckboxControlFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, + const nsRect& aDirtyRect, + const nsDisplayListSet& aLists) +{ + nsFormControlFrame::BuildDisplayList(aBuilder, aDirtyRect, aLists); + + // Get current checked state through content model. + if ((!IsChecked() && !IsIndeterminate()) || !IsVisibleForPainting(aBuilder)) + return; // we're not checked or not visible, nothing to paint. + + if (IsThemed()) + return; // No need to paint the checkmark. The theme will do it. + + aLists.Content()->AppendNewToTop(new (aBuilder) + nsDisplayGeneric(aBuilder, this, + IsIndeterminate() + ? PaintIndeterminateMark : PaintCheckMark, + "CheckedCheckbox", + nsDisplayItem::TYPE_CHECKED_CHECKBOX)); +} + +//------------------------------------------------------------ bool nsGfxCheckboxControlFrame::IsChecked() { nsCOMPtr<nsIDOMHTMLInputElement> elem(do_QueryInterface(mContent)); bool retval = false; elem->GetChecked(&retval); return retval; }
--- a/layout/forms/nsGfxCheckboxControlFrame.h +++ b/layout/forms/nsGfxCheckboxControlFrame.h @@ -17,16 +17,20 @@ public: virtual ~nsGfxCheckboxControlFrame(); #ifdef DEBUG_FRAME_DUMP virtual nsresult GetFrameName(nsAString& aResult) const override { return MakeFrameName(NS_LITERAL_STRING("CheckboxControl"), aResult); } #endif + virtual void BuildDisplayList(nsDisplayListBuilder* aBuilder, + const nsRect& aDirtyRect, + const nsDisplayListSet& aLists) override; + #ifdef ACCESSIBILITY virtual mozilla::a11y::AccType AccessibleType() override; #endif protected: bool IsChecked(); bool IsIndeterminate();
--- a/layout/forms/nsGfxRadioControlFrame.cpp +++ b/layout/forms/nsGfxRadioControlFrame.cpp @@ -35,8 +35,59 @@ nsGfxRadioControlFrame::~nsGfxRadioContr #ifdef ACCESSIBILITY a11y::AccType nsGfxRadioControlFrame::AccessibleType() { return a11y::eHTMLRadioButtonType; } #endif + +//-------------------------------------------------------------- +// Draw the dot for a non-native radio button in the checked state. +static void +PaintCheckedRadioButton(nsIFrame* aFrame, + DrawTarget* aDrawTarget, + const nsRect& aDirtyRect, + nsPoint aPt) +{ + // The dot is an ellipse 2px on all sides smaller than the content-box, + // drawn in the foreground color. + nsRect rect(aPt, aFrame->GetSize()); + rect.Deflate(aFrame->GetUsedBorderAndPadding()); + rect.Deflate(nsPresContext::CSSPixelsToAppUnits(2), + nsPresContext::CSSPixelsToAppUnits(2)); + + Rect devPxRect = + ToRect(nsLayoutUtils::RectToGfxRect(rect, + aFrame->PresContext()->AppUnitsPerDevPixel())); + + ColorPattern color(ToDeviceColor(aFrame->StyleColor()->mColor)); + + RefPtr<PathBuilder> builder = aDrawTarget->CreatePathBuilder(); + AppendEllipseToPath(builder, devPxRect.Center(), devPxRect.Size()); + RefPtr<Path> ellipse = builder->Finish(); + aDrawTarget->Fill(ellipse, color); +} + +void +nsGfxRadioControlFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, + const nsRect& aDirtyRect, + const nsDisplayListSet& aLists) +{ + nsFormControlFrame::BuildDisplayList(aBuilder, aDirtyRect, aLists); + + if (!IsVisibleForPainting(aBuilder)) + return; + + if (IsThemed()) + return; // The theme will paint the check, if any. + + bool checked = true; + GetCurrentCheckState(&checked); // Get check state from the content model + if (!checked) + return; + + aLists.Content()->AppendNewToTop(new (aBuilder) + nsDisplayGeneric(aBuilder, this, PaintCheckedRadioButton, + "CheckedRadioButton", + nsDisplayItem::TYPE_CHECKED_RADIOBUTTON)); +}
--- a/layout/forms/nsGfxRadioControlFrame.h +++ b/layout/forms/nsGfxRadioControlFrame.h @@ -18,11 +18,15 @@ public: explicit nsGfxRadioControlFrame(nsStyleContext* aContext); ~nsGfxRadioControlFrame(); NS_DECL_FRAMEARENA_HELPERS #ifdef ACCESSIBILITY virtual mozilla::a11y::AccType AccessibleType() override; #endif + + virtual void BuildDisplayList(nsDisplayListBuilder* aBuilder, + const nsRect& aDirtyRect, + const nsDisplayListSet& aLists) override; }; #endif
--- a/layout/style/jar.mn +++ b/layout/style/jar.mn @@ -26,13 +26,10 @@ toolkit.jar: res/accessiblecaret-tilt-left@1x.png (res/accessiblecaret-tilt-left@1x.png) res/accessiblecaret-tilt-left@1.5x.png (res/accessiblecaret-tilt-left@1.5x.png) res/accessiblecaret-tilt-left@2x.png (res/accessiblecaret-tilt-left@2x.png) res/accessiblecaret-tilt-left@2.25x.png (res/accessiblecaret-tilt-left@2.25x.png) res/accessiblecaret-tilt-right@1x.png (res/accessiblecaret-tilt-right@1x.png) res/accessiblecaret-tilt-right@1.5x.png (res/accessiblecaret-tilt-right@1.5x.png) res/accessiblecaret-tilt-right@2x.png (res/accessiblecaret-tilt-right@2x.png) res/accessiblecaret-tilt-right@2.25x.png (res/accessiblecaret-tilt-right@2.25x.png) - res/checkmark.svg (res/checkmark.svg) - res/indeterminate-checkmark.svg (res/indeterminate-checkmark.svg) - res/radio.svg (res/radio.svg) % resource gre-resources %res/
deleted file mode 100644 --- a/layout/style/res/checkmark.svg +++ /dev/null @@ -1,7 +0,0 @@ -<svg xmlns="http://www.w3.org/2000/svg" viewbox="0 0 10 10" width="10" height="10"> - <style type="text/css"> - path { fill: -moz-FieldText; } - #disabled:target { fill: GrayText; } - </style> - <path id="disabled" d="M 2 4 L 4 6 L 8 2 L 8 4 L 4 8 L 2 6 Z"/> -</svg>
--- a/layout/style/res/forms.css +++ b/layout/style/res/forms.css @@ -538,108 +538,80 @@ input[type="file"]:dir(rtl) > xul|label /* radio buttons */ input[type="radio"] { -moz-appearance: radio; margin-block-start: 3px; margin-block-end: 0px; margin-inline-start: 5px; margin-inline-end: 3px; - border-radius: 100%; + border-radius: 100% !important; } /* check boxes */ input[type="checkbox"] { -moz-appearance: checkbox; margin-block-start: 3px; margin-block-end: 3px; margin-inline-start: 4px; margin-inline-end: 3px; - border-radius: 0; + border-radius: 0 !important; } /* common features of radio buttons and check boxes */ /* NOTE: The width, height, border-width, and padding here must all add up the way nsFormControlFrame::GetIntrinsic(Width|Height) expects them to, or they will not come out with total width equal to total height on sites that set their 'width' or 'height' to 'auto'. (Should we maybe set !important on width and height, then?) */ input[type="radio"], input[type="checkbox"] { box-sizing: border-box; inline-size: 13px; block-size: 13px; cursor: default; - padding: 0; + padding: 0 !important; -moz-binding: none; - border: 2px inset ThreeDLightShadow; - background-repeat: no-repeat; - background-position: center; + /* same colors as |input| rule, but |!important| this time. */ + background-color: -moz-Field ! important; + color: -moz-FieldText ! important; + border: 2px inset ThreeDLightShadow ! important; } input[type="radio"]:disabled, input[type="radio"]:disabled:active, input[type="radio"]:disabled:hover, input[type="radio"]:disabled:hover:active, input[type="checkbox"]:disabled, input[type="checkbox"]:disabled:active, input[type="checkbox"]:disabled:hover, input[type="checkbox"]:disabled:hover:active { padding: 1px; - border: 1px inset ThreeDShadow; + border: 1px inset ThreeDShadow ! important; + /* same as above, but !important */ + color: GrayText ! important; + background-color: ThreeDFace ! important; cursor: inherit; } % On Mac, the native theme takes care of this. % See nsNativeThemeCocoa::ThemeDrawsFocusForWidget. %ifndef XP_MACOSX input[type="checkbox"]:-moz-focusring, input[type="radio"]:-moz-focusring { /* Don't specify the outline-color, we should always use initial value. */ outline: 1px dotted; } %endif input[type="checkbox"]:hover:active, input[type="radio"]:hover:active { - background-color: ThreeDFace; - border-style: inset; -} - -input[type="radio"] { - background-size: calc(100% - 4px) calc(100% - 4px); -} - -input[type="radio"]:checked { - background-image: url(radio.svg); -} - -input[type="radio"]:disabled:checked { - background-image: url(radio.svg#disabled); -} - -input[type="checkbox"] { - background-size: 100% 100%; -} - -input[type="checkbox"]:checked { - background-image: url(checkmark.svg); -} - -input[type="checkbox"]:disabled:checked { - background-image: url(checkmark.svg#disabled); -} - -input[type="checkbox"]:indeterminate { - background-image: url(indeterminate-checkmark.svg); -} - -input[type="checkbox"]:indeterminate:disabled { - background-image: url(indeterminate-checkmark.svg#disabled); + background-color: ThreeDFace ! important; + border-style: inset !important; } input[type="search"] { box-sizing: border-box; } /* buttons */
deleted file mode 100644 --- a/layout/style/res/indeterminate-checkmark.svg +++ /dev/null @@ -1,7 +0,0 @@ -<svg xmlns="http://www.w3.org/2000/svg" viewbox="0 0 5 5" width="5" height="5"> - <style type="text/css"> - rect { fill: -moz-FieldText; } - #disabled:target { fill: GrayText; } - </style> - <rect id="disabled" x="0" y="2" width="5" height="1"/> -</svg>
deleted file mode 100644 --- a/layout/style/res/radio.svg +++ /dev/null @@ -1,7 +0,0 @@ -<svg xmlns="http://www.w3.org/2000/svg" viewbox="0 0 20 20" width="20" height="20"> - <style type="text/css"> - circle { fill: -moz-FieldText; } - #disabled:target { fill: GrayText; } - </style> - <circle id="disabled" cx="10" cy="10" r="10"/> -</svg>