|
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/. */ |
|
5 |
|
6 #include "nsGfxCheckboxControlFrame.h" |
|
7 #include "nsIContent.h" |
|
8 #include "nsCOMPtr.h" |
|
9 #include "nsRenderingContext.h" |
|
10 #include "nsIDOMHTMLInputElement.h" |
|
11 #include "nsDisplayList.h" |
|
12 #include <algorithm> |
|
13 |
|
14 using namespace mozilla; |
|
15 |
|
16 static void |
|
17 PaintCheckMark(nsIFrame* aFrame, |
|
18 nsRenderingContext* aCtx, |
|
19 const nsRect& aDirtyRect, |
|
20 nsPoint aPt) |
|
21 { |
|
22 nsRect rect(aPt, aFrame->GetSize()); |
|
23 rect.Deflate(aFrame->GetUsedBorderAndPadding()); |
|
24 |
|
25 // Points come from the coordinates on a 7X7 unit box centered at 0,0 |
|
26 const int32_t checkPolygonX[] = { -3, -1, 3, 3, -1, -3 }; |
|
27 const int32_t checkPolygonY[] = { -1, 1, -3, -1, 3, 1 }; |
|
28 const int32_t checkNumPoints = sizeof(checkPolygonX) / sizeof(int32_t); |
|
29 const int32_t checkSize = 9; // 2 units of padding on either side |
|
30 // of the 7x7 unit checkmark |
|
31 |
|
32 // Scale the checkmark based on the smallest dimension |
|
33 nscoord paintScale = std::min(rect.width, rect.height) / checkSize; |
|
34 nsPoint paintCenter(rect.x + rect.width / 2, |
|
35 rect.y + rect.height / 2); |
|
36 |
|
37 nsPoint paintPolygon[checkNumPoints]; |
|
38 // Convert checkmark for screen rendering |
|
39 for (int32_t polyIndex = 0; polyIndex < checkNumPoints; polyIndex++) { |
|
40 paintPolygon[polyIndex] = paintCenter + |
|
41 nsPoint(checkPolygonX[polyIndex] * paintScale, |
|
42 checkPolygonY[polyIndex] * paintScale); |
|
43 } |
|
44 |
|
45 aCtx->SetColor(aFrame->StyleColor()->mColor); |
|
46 aCtx->FillPolygon(paintPolygon, checkNumPoints); |
|
47 } |
|
48 |
|
49 static void |
|
50 PaintIndeterminateMark(nsIFrame* aFrame, |
|
51 nsRenderingContext* aCtx, |
|
52 const nsRect& aDirtyRect, |
|
53 nsPoint aPt) |
|
54 { |
|
55 nsRect rect(aPt, aFrame->GetSize()); |
|
56 rect.Deflate(aFrame->GetUsedBorderAndPadding()); |
|
57 |
|
58 rect.y += (rect.height - rect.height/4) / 2; |
|
59 rect.height /= 4; |
|
60 |
|
61 aCtx->SetColor(aFrame->StyleColor()->mColor); |
|
62 aCtx->FillRect(rect); |
|
63 } |
|
64 |
|
65 //------------------------------------------------------------ |
|
66 nsIFrame* |
|
67 NS_NewGfxCheckboxControlFrame(nsIPresShell* aPresShell, |
|
68 nsStyleContext* aContext) |
|
69 { |
|
70 return new (aPresShell) nsGfxCheckboxControlFrame(aContext); |
|
71 } |
|
72 |
|
73 NS_IMPL_FRAMEARENA_HELPERS(nsGfxCheckboxControlFrame) |
|
74 |
|
75 |
|
76 //------------------------------------------------------------ |
|
77 // Initialize GFX-rendered state |
|
78 nsGfxCheckboxControlFrame::nsGfxCheckboxControlFrame(nsStyleContext* aContext) |
|
79 : nsFormControlFrame(aContext) |
|
80 { |
|
81 } |
|
82 |
|
83 nsGfxCheckboxControlFrame::~nsGfxCheckboxControlFrame() |
|
84 { |
|
85 } |
|
86 |
|
87 #ifdef ACCESSIBILITY |
|
88 a11y::AccType |
|
89 nsGfxCheckboxControlFrame::AccessibleType() |
|
90 { |
|
91 return a11y::eHTMLCheckboxType; |
|
92 } |
|
93 #endif |
|
94 |
|
95 //------------------------------------------------------------ |
|
96 void |
|
97 nsGfxCheckboxControlFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, |
|
98 const nsRect& aDirtyRect, |
|
99 const nsDisplayListSet& aLists) |
|
100 { |
|
101 nsFormControlFrame::BuildDisplayList(aBuilder, aDirtyRect, aLists); |
|
102 |
|
103 // Get current checked state through content model. |
|
104 if ((!IsChecked() && !IsIndeterminate()) || !IsVisibleForPainting(aBuilder)) |
|
105 return; // we're not checked or not visible, nothing to paint. |
|
106 |
|
107 if (IsThemed()) |
|
108 return; // No need to paint the checkmark. The theme will do it. |
|
109 |
|
110 aLists.Content()->AppendNewToTop(new (aBuilder) |
|
111 nsDisplayGeneric(aBuilder, this, |
|
112 IsIndeterminate() |
|
113 ? PaintIndeterminateMark : PaintCheckMark, |
|
114 "CheckedCheckbox", |
|
115 nsDisplayItem::TYPE_CHECKED_CHECKBOX)); |
|
116 } |
|
117 |
|
118 //------------------------------------------------------------ |
|
119 bool |
|
120 nsGfxCheckboxControlFrame::IsChecked() |
|
121 { |
|
122 nsCOMPtr<nsIDOMHTMLInputElement> elem(do_QueryInterface(mContent)); |
|
123 bool retval = false; |
|
124 elem->GetChecked(&retval); |
|
125 return retval; |
|
126 } |
|
127 |
|
128 bool |
|
129 nsGfxCheckboxControlFrame::IsIndeterminate() |
|
130 { |
|
131 nsCOMPtr<nsIDOMHTMLInputElement> elem(do_QueryInterface(mContent)); |
|
132 bool retval = false; |
|
133 elem->GetIndeterminate(&retval); |
|
134 return retval; |
|
135 } |