1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/layout/forms/nsGfxCheckboxControlFrame.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,135 @@ 1.4 +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 1.5 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.7 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.8 + 1.9 +#include "nsGfxCheckboxControlFrame.h" 1.10 +#include "nsIContent.h" 1.11 +#include "nsCOMPtr.h" 1.12 +#include "nsRenderingContext.h" 1.13 +#include "nsIDOMHTMLInputElement.h" 1.14 +#include "nsDisplayList.h" 1.15 +#include <algorithm> 1.16 + 1.17 +using namespace mozilla; 1.18 + 1.19 +static void 1.20 +PaintCheckMark(nsIFrame* aFrame, 1.21 + nsRenderingContext* aCtx, 1.22 + const nsRect& aDirtyRect, 1.23 + nsPoint aPt) 1.24 +{ 1.25 + nsRect rect(aPt, aFrame->GetSize()); 1.26 + rect.Deflate(aFrame->GetUsedBorderAndPadding()); 1.27 + 1.28 + // Points come from the coordinates on a 7X7 unit box centered at 0,0 1.29 + const int32_t checkPolygonX[] = { -3, -1, 3, 3, -1, -3 }; 1.30 + const int32_t checkPolygonY[] = { -1, 1, -3, -1, 3, 1 }; 1.31 + const int32_t checkNumPoints = sizeof(checkPolygonX) / sizeof(int32_t); 1.32 + const int32_t checkSize = 9; // 2 units of padding on either side 1.33 + // of the 7x7 unit checkmark 1.34 + 1.35 + // Scale the checkmark based on the smallest dimension 1.36 + nscoord paintScale = std::min(rect.width, rect.height) / checkSize; 1.37 + nsPoint paintCenter(rect.x + rect.width / 2, 1.38 + rect.y + rect.height / 2); 1.39 + 1.40 + nsPoint paintPolygon[checkNumPoints]; 1.41 + // Convert checkmark for screen rendering 1.42 + for (int32_t polyIndex = 0; polyIndex < checkNumPoints; polyIndex++) { 1.43 + paintPolygon[polyIndex] = paintCenter + 1.44 + nsPoint(checkPolygonX[polyIndex] * paintScale, 1.45 + checkPolygonY[polyIndex] * paintScale); 1.46 + } 1.47 + 1.48 + aCtx->SetColor(aFrame->StyleColor()->mColor); 1.49 + aCtx->FillPolygon(paintPolygon, checkNumPoints); 1.50 +} 1.51 + 1.52 +static void 1.53 +PaintIndeterminateMark(nsIFrame* aFrame, 1.54 + nsRenderingContext* aCtx, 1.55 + const nsRect& aDirtyRect, 1.56 + nsPoint aPt) 1.57 +{ 1.58 + nsRect rect(aPt, aFrame->GetSize()); 1.59 + rect.Deflate(aFrame->GetUsedBorderAndPadding()); 1.60 + 1.61 + rect.y += (rect.height - rect.height/4) / 2; 1.62 + rect.height /= 4; 1.63 + 1.64 + aCtx->SetColor(aFrame->StyleColor()->mColor); 1.65 + aCtx->FillRect(rect); 1.66 +} 1.67 + 1.68 +//------------------------------------------------------------ 1.69 +nsIFrame* 1.70 +NS_NewGfxCheckboxControlFrame(nsIPresShell* aPresShell, 1.71 + nsStyleContext* aContext) 1.72 +{ 1.73 + return new (aPresShell) nsGfxCheckboxControlFrame(aContext); 1.74 +} 1.75 + 1.76 +NS_IMPL_FRAMEARENA_HELPERS(nsGfxCheckboxControlFrame) 1.77 + 1.78 + 1.79 +//------------------------------------------------------------ 1.80 +// Initialize GFX-rendered state 1.81 +nsGfxCheckboxControlFrame::nsGfxCheckboxControlFrame(nsStyleContext* aContext) 1.82 +: nsFormControlFrame(aContext) 1.83 +{ 1.84 +} 1.85 + 1.86 +nsGfxCheckboxControlFrame::~nsGfxCheckboxControlFrame() 1.87 +{ 1.88 +} 1.89 + 1.90 +#ifdef ACCESSIBILITY 1.91 +a11y::AccType 1.92 +nsGfxCheckboxControlFrame::AccessibleType() 1.93 +{ 1.94 + return a11y::eHTMLCheckboxType; 1.95 +} 1.96 +#endif 1.97 + 1.98 +//------------------------------------------------------------ 1.99 +void 1.100 +nsGfxCheckboxControlFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, 1.101 + const nsRect& aDirtyRect, 1.102 + const nsDisplayListSet& aLists) 1.103 +{ 1.104 + nsFormControlFrame::BuildDisplayList(aBuilder, aDirtyRect, aLists); 1.105 + 1.106 + // Get current checked state through content model. 1.107 + if ((!IsChecked() && !IsIndeterminate()) || !IsVisibleForPainting(aBuilder)) 1.108 + return; // we're not checked or not visible, nothing to paint. 1.109 + 1.110 + if (IsThemed()) 1.111 + return; // No need to paint the checkmark. The theme will do it. 1.112 + 1.113 + aLists.Content()->AppendNewToTop(new (aBuilder) 1.114 + nsDisplayGeneric(aBuilder, this, 1.115 + IsIndeterminate() 1.116 + ? PaintIndeterminateMark : PaintCheckMark, 1.117 + "CheckedCheckbox", 1.118 + nsDisplayItem::TYPE_CHECKED_CHECKBOX)); 1.119 +} 1.120 + 1.121 +//------------------------------------------------------------ 1.122 +bool 1.123 +nsGfxCheckboxControlFrame::IsChecked() 1.124 +{ 1.125 + nsCOMPtr<nsIDOMHTMLInputElement> elem(do_QueryInterface(mContent)); 1.126 + bool retval = false; 1.127 + elem->GetChecked(&retval); 1.128 + return retval; 1.129 +} 1.130 + 1.131 +bool 1.132 +nsGfxCheckboxControlFrame::IsIndeterminate() 1.133 +{ 1.134 + nsCOMPtr<nsIDOMHTMLInputElement> elem(do_QueryInterface(mContent)); 1.135 + bool retval = false; 1.136 + elem->GetIndeterminate(&retval); 1.137 + return retval; 1.138 +}