1 : /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 : /* ***** BEGIN LICENSE BLOCK *****
3 : * Version: MPL 1.1/GPL 2.0/LGPL 2.1
4 : *
5 : * The contents of this file are subject to the Mozilla Public License Version
6 : * 1.1 (the "License"); you may not use this file except in compliance with
7 : * the License. You may obtain a copy of the License at
8 : * http://www.mozilla.org/MPL/
9 : *
10 : * Software distributed under the License is distributed on an "AS IS" basis,
11 : * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12 : * for the specific language governing rights and limitations under the
13 : * License.
14 : *
15 : * The Original Code is mozilla.org code.
16 : *
17 : * The Initial Developer of the Original Code is
18 : * Netscape Communications Corporation.
19 : * Portions created by the Initial Developer are Copyright (C) 1998
20 : * the Initial Developer. All Rights Reserved.
21 : *
22 : * Contributor(s):
23 : *
24 : * Alternatively, the contents of this file may be used under the terms of
25 : * either of the GNU General Public License Version 2 or later (the "GPL"),
26 : * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
27 : * in which case the provisions of the GPL or the LGPL are applicable instead
28 : * of those above. If you wish to allow use of your version of this file only
29 : * under the terms of either the GPL or the LGPL, and not to allow others to
30 : * use your version of this file under the terms of the MPL, indicate your
31 : * decision by deleting the provisions above and replace them with the notice
32 : * and other provisions required by the GPL or the LGPL. If you do not delete
33 : * the provisions above, a recipient may use your version of this file under
34 : * the terms of any one of the MPL, the GPL or the LGPL.
35 : *
36 : * ***** END LICENSE BLOCK ***** */
37 :
38 : #include "nsGfxCheckboxControlFrame.h"
39 : #include "nsIContent.h"
40 : #include "nsCOMPtr.h"
41 : #include "nsCSSRendering.h"
42 : #include "nsRenderingContext.h"
43 : #ifdef ACCESSIBILITY
44 : #include "nsAccessibilityService.h"
45 : #endif
46 : #include "nsIServiceManager.h"
47 : #include "nsIDOMHTMLInputElement.h"
48 : #include "nsDisplayList.h"
49 : #include "nsCSSAnonBoxes.h"
50 :
51 : static void
52 0 : PaintCheckMark(nsIFrame* aFrame,
53 : nsRenderingContext* aCtx,
54 : const nsRect& aDirtyRect,
55 : nsPoint aPt)
56 : {
57 0 : nsRect rect(aPt, aFrame->GetSize());
58 0 : rect.Deflate(aFrame->GetUsedBorderAndPadding());
59 :
60 : // Points come from the coordinates on a 7X7 unit box centered at 0,0
61 0 : const PRInt32 checkPolygonX[] = { -3, -1, 3, 3, -1, -3 };
62 0 : const PRInt32 checkPolygonY[] = { -1, 1, -3, -1, 3, 1 };
63 0 : const PRInt32 checkNumPoints = sizeof(checkPolygonX) / sizeof(PRInt32);
64 0 : const PRInt32 checkSize = 9; // 2 units of padding on either side
65 : // of the 7x7 unit checkmark
66 :
67 : // Scale the checkmark based on the smallest dimension
68 0 : nscoord paintScale = NS_MIN(rect.width, rect.height) / checkSize;
69 : nsPoint paintCenter(rect.x + rect.width / 2,
70 0 : rect.y + rect.height / 2);
71 :
72 0 : nsPoint paintPolygon[checkNumPoints];
73 : // Convert checkmark for screen rendering
74 0 : for (PRInt32 polyIndex = 0; polyIndex < checkNumPoints; polyIndex++) {
75 : paintPolygon[polyIndex] = paintCenter +
76 0 : nsPoint(checkPolygonX[polyIndex] * paintScale,
77 0 : checkPolygonY[polyIndex] * paintScale);
78 : }
79 :
80 0 : aCtx->SetColor(aFrame->GetStyleColor()->mColor);
81 0 : aCtx->FillPolygon(paintPolygon, checkNumPoints);
82 0 : }
83 :
84 : static void
85 0 : PaintIndeterminateMark(nsIFrame* aFrame,
86 : nsRenderingContext* aCtx,
87 : const nsRect& aDirtyRect,
88 : nsPoint aPt)
89 : {
90 0 : nsRect rect(aPt, aFrame->GetSize());
91 0 : rect.Deflate(aFrame->GetUsedBorderAndPadding());
92 :
93 0 : rect.y += (rect.height - rect.height/4) / 2;
94 0 : rect.height /= 4;
95 :
96 0 : aCtx->SetColor(aFrame->GetStyleColor()->mColor);
97 0 : aCtx->FillRect(rect);
98 0 : }
99 :
100 : //------------------------------------------------------------
101 : nsIFrame*
102 0 : NS_NewGfxCheckboxControlFrame(nsIPresShell* aPresShell,
103 : nsStyleContext* aContext)
104 : {
105 0 : return new (aPresShell) nsGfxCheckboxControlFrame(aContext);
106 : }
107 :
108 0 : NS_IMPL_FRAMEARENA_HELPERS(nsGfxCheckboxControlFrame)
109 :
110 :
111 : //------------------------------------------------------------
112 : // Initialize GFX-rendered state
113 0 : nsGfxCheckboxControlFrame::nsGfxCheckboxControlFrame(nsStyleContext* aContext)
114 0 : : nsFormControlFrame(aContext)
115 : {
116 0 : }
117 :
118 0 : nsGfxCheckboxControlFrame::~nsGfxCheckboxControlFrame()
119 : {
120 0 : }
121 :
122 : #ifdef ACCESSIBILITY
123 : already_AddRefed<nsAccessible>
124 0 : nsGfxCheckboxControlFrame::CreateAccessible()
125 : {
126 0 : nsAccessibilityService* accService = nsIPresShell::AccService();
127 0 : if (accService) {
128 : return accService->CreateHTMLCheckboxAccessible(mContent,
129 0 : PresContext()->PresShell());
130 : }
131 :
132 0 : return nsnull;
133 : }
134 : #endif
135 :
136 : //------------------------------------------------------------
137 : NS_IMETHODIMP
138 0 : nsGfxCheckboxControlFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
139 : const nsRect& aDirtyRect,
140 : const nsDisplayListSet& aLists)
141 : {
142 : nsresult rv = nsFormControlFrame::BuildDisplayList(aBuilder, aDirtyRect,
143 0 : aLists);
144 0 : NS_ENSURE_SUCCESS(rv, rv);
145 :
146 : // Get current checked state through content model.
147 0 : if ((!IsChecked() && !IsIndeterminate()) || !IsVisibleForPainting(aBuilder))
148 0 : return NS_OK; // we're not checked or not visible, nothing to paint.
149 :
150 0 : if (IsThemed())
151 0 : return NS_OK; // No need to paint the checkmark. The theme will do it.
152 :
153 : return aLists.Content()->AppendNewToTop(new (aBuilder)
154 : nsDisplayGeneric(aBuilder, this,
155 0 : IsIndeterminate()
156 : ? PaintIndeterminateMark : PaintCheckMark,
157 : "CheckedCheckbox",
158 0 : nsDisplayItem::TYPE_CHECKED_CHECKBOX));
159 : }
160 :
161 : //------------------------------------------------------------
162 : bool
163 0 : nsGfxCheckboxControlFrame::IsChecked()
164 : {
165 0 : nsCOMPtr<nsIDOMHTMLInputElement> elem(do_QueryInterface(mContent));
166 0 : bool retval = false;
167 0 : elem->GetChecked(&retval);
168 0 : return retval;
169 : }
170 :
171 : bool
172 0 : nsGfxCheckboxControlFrame::IsIndeterminate()
173 : {
174 0 : nsCOMPtr<nsIDOMHTMLInputElement> elem(do_QueryInterface(mContent));
175 0 : bool retval = false;
176 0 : elem->GetIndeterminate(&retval);
177 0 : return retval;
178 : }
|