1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 #include "nsGfxCheckboxControlFrame.h"
9 #include "mozilla/gfx/2D.h"
10 #include "nsIContent.h"
12 #include "nsLayoutUtils.h"
13 #include "nsRenderingContext.h"
14 #include "nsIDOMHTMLInputElement.h"
15 #include "nsDisplayList.h"
18 using namespace mozilla
;
19 using namespace mozilla::gfx
;
22 PaintCheckMark(nsIFrame
* aFrame
,
23 nsRenderingContext
* aCtx
,
24 const nsRect
& aDirtyRect
,
27 nsRect
rect(aPt
, aFrame
->GetSize());
28 rect
.Deflate(aFrame
->GetUsedBorderAndPadding());
30 // Points come from the coordinates on a 7X7 unit box centered at 0,0
31 const int32_t checkPolygonX
[] = { -3, -1, 3, 3, -1, -3 };
32 const int32_t checkPolygonY
[] = { -1, 1, -3, -1, 3, 1 };
33 const int32_t checkNumPoints
= sizeof(checkPolygonX
) / sizeof(int32_t);
34 const int32_t checkSize
= 9; // 2 units of padding on either side
35 // of the 7x7 unit checkmark
37 // Scale the checkmark based on the smallest dimension
38 nscoord paintScale
= std::min(rect
.width
, rect
.height
) / checkSize
;
39 nsPoint
paintCenter(rect
.x
+ rect
.width
/ 2,
40 rect
.y
+ rect
.height
/ 2);
42 DrawTarget
* drawTarget
= aCtx
->GetDrawTarget();
43 RefPtr
<PathBuilder
> builder
= drawTarget
->CreatePathBuilder();
44 nsPoint p
= paintCenter
+ nsPoint(checkPolygonX
[0] * paintScale
,
45 checkPolygonY
[0] * paintScale
);
47 int32_t appUnitsPerDevPixel
= aFrame
->PresContext()->AppUnitsPerDevPixel();
48 builder
->MoveTo(NSPointToPoint(p
, appUnitsPerDevPixel
));
49 for (int32_t polyIndex
= 1; polyIndex
< checkNumPoints
; polyIndex
++) {
50 p
= paintCenter
+ nsPoint(checkPolygonX
[polyIndex
] * paintScale
,
51 checkPolygonY
[polyIndex
] * paintScale
);
52 builder
->LineTo(NSPointToPoint(p
, appUnitsPerDevPixel
));
54 RefPtr
<Path
> path
= builder
->Finish();
55 drawTarget
->Fill(path
,
56 ColorPattern(ToDeviceColor(aFrame
->StyleColor()->mColor
)));
60 PaintIndeterminateMark(nsIFrame
* aFrame
,
61 nsRenderingContext
* aCtx
,
62 const nsRect
& aDirtyRect
,
65 DrawTarget
* drawTarget
= aCtx
->GetDrawTarget();
66 int32_t appUnitsPerDevPixel
= aFrame
->PresContext()->AppUnitsPerDevPixel();
68 nsRect
rect(aPt
, aFrame
->GetSize());
69 rect
.Deflate(aFrame
->GetUsedBorderAndPadding());
70 rect
.y
+= (rect
.height
- rect
.height
/4) / 2;
73 Rect devPxRect
= NSRectToSnappedRect(rect
, appUnitsPerDevPixel
, *drawTarget
);
75 drawTarget
->FillRect(devPxRect
,
76 ColorPattern(ToDeviceColor(aFrame
->StyleColor()->mColor
)));
79 //------------------------------------------------------------
81 NS_NewGfxCheckboxControlFrame(nsIPresShell
* aPresShell
,
82 nsStyleContext
* aContext
)
84 return new (aPresShell
) nsGfxCheckboxControlFrame(aContext
);
87 NS_IMPL_FRAMEARENA_HELPERS(nsGfxCheckboxControlFrame
)
90 //------------------------------------------------------------
91 // Initialize GFX-rendered state
92 nsGfxCheckboxControlFrame::nsGfxCheckboxControlFrame(nsStyleContext
* aContext
)
93 : nsFormControlFrame(aContext
)
97 nsGfxCheckboxControlFrame::~nsGfxCheckboxControlFrame()
103 nsGfxCheckboxControlFrame::AccessibleType()
105 return a11y::eHTMLCheckboxType
;
109 //------------------------------------------------------------
111 nsGfxCheckboxControlFrame::BuildDisplayList(nsDisplayListBuilder
* aBuilder
,
112 const nsRect
& aDirtyRect
,
113 const nsDisplayListSet
& aLists
)
115 nsFormControlFrame::BuildDisplayList(aBuilder
, aDirtyRect
, aLists
);
117 // Get current checked state through content model.
118 if ((!IsChecked() && !IsIndeterminate()) || !IsVisibleForPainting(aBuilder
))
119 return; // we're not checked or not visible, nothing to paint.
122 return; // No need to paint the checkmark. The theme will do it.
124 aLists
.Content()->AppendNewToTop(new (aBuilder
)
125 nsDisplayGeneric(aBuilder
, this,
127 ? PaintIndeterminateMark
: PaintCheckMark
,
129 nsDisplayItem::TYPE_CHECKED_CHECKBOX
));
132 //------------------------------------------------------------
134 nsGfxCheckboxControlFrame::IsChecked()
136 nsCOMPtr
<nsIDOMHTMLInputElement
> elem(do_QueryInterface(mContent
));
138 elem
->GetChecked(&retval
);
143 nsGfxCheckboxControlFrame::IsIndeterminate()
145 nsCOMPtr
<nsIDOMHTMLInputElement
> elem(do_QueryInterface(mContent
));
147 elem
->GetIndeterminate(&retval
);