forked from mirrors/gecko-dev
		
	
		
			
				
	
	
		
			139 lines
		
	
	
	
		
			4.5 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			139 lines
		
	
	
	
		
			4.5 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 | |
| /* This Source Code Form is subject to the terms of the Mozilla Public
 | |
|  * License, v. 2.0. If a copy of the MPL was not distributed with this
 | |
|  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 | |
| 
 | |
| #include "nsGfxCheckboxControlFrame.h"
 | |
| #include "nsIContent.h"
 | |
| #include "nsCOMPtr.h"
 | |
| #include "nsCSSRendering.h"
 | |
| #include "nsRenderingContext.h"
 | |
| #include "nsIServiceManager.h"
 | |
| #include "nsIDOMHTMLInputElement.h"
 | |
| #include "nsDisplayList.h"
 | |
| #include "nsCSSAnonBoxes.h"
 | |
| 
 | |
| using namespace mozilla;
 | |
| 
 | |
| static void
 | |
| PaintCheckMark(nsIFrame* aFrame,
 | |
|                nsRenderingContext* aCtx,
 | |
|                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 = NS_MIN(rect.width, rect.height) / checkSize;
 | |
|   nsPoint paintCenter(rect.x + rect.width  / 2,
 | |
|                       rect.y + rect.height / 2);
 | |
| 
 | |
|   nsPoint paintPolygon[checkNumPoints];
 | |
|   // Convert checkmark for screen rendering
 | |
|   for (int32_t polyIndex = 0; polyIndex < checkNumPoints; polyIndex++) {
 | |
|     paintPolygon[polyIndex] = paintCenter +
 | |
|                               nsPoint(checkPolygonX[polyIndex] * paintScale,
 | |
|                                       checkPolygonY[polyIndex] * paintScale);
 | |
|   }
 | |
| 
 | |
|   aCtx->SetColor(aFrame->GetStyleColor()->mColor);
 | |
|   aCtx->FillPolygon(paintPolygon, checkNumPoints);
 | |
| }
 | |
| 
 | |
| static void
 | |
| PaintIndeterminateMark(nsIFrame* aFrame,
 | |
|                        nsRenderingContext* aCtx,
 | |
|                        const nsRect& aDirtyRect,
 | |
|                        nsPoint aPt)
 | |
| {
 | |
|   nsRect rect(aPt, aFrame->GetSize());
 | |
|   rect.Deflate(aFrame->GetUsedBorderAndPadding());
 | |
| 
 | |
|   rect.y += (rect.height - rect.height/4) / 2;
 | |
|   rect.height /= 4;
 | |
| 
 | |
|   aCtx->SetColor(aFrame->GetStyleColor()->mColor);
 | |
|   aCtx->FillRect(rect);
 | |
| }
 | |
| 
 | |
| //------------------------------------------------------------
 | |
| nsIFrame*
 | |
| NS_NewGfxCheckboxControlFrame(nsIPresShell* aPresShell,
 | |
|                               nsStyleContext* aContext)
 | |
| {
 | |
|   return new (aPresShell) nsGfxCheckboxControlFrame(aContext);
 | |
| }
 | |
| 
 | |
| NS_IMPL_FRAMEARENA_HELPERS(nsGfxCheckboxControlFrame)
 | |
| 
 | |
| 
 | |
| //------------------------------------------------------------
 | |
| // Initialize GFX-rendered state
 | |
| nsGfxCheckboxControlFrame::nsGfxCheckboxControlFrame(nsStyleContext* aContext)
 | |
| : nsFormControlFrame(aContext)
 | |
| {
 | |
| }
 | |
| 
 | |
| nsGfxCheckboxControlFrame::~nsGfxCheckboxControlFrame()
 | |
| {
 | |
| }
 | |
| 
 | |
| #ifdef ACCESSIBILITY
 | |
| a11y::AccType
 | |
| nsGfxCheckboxControlFrame::AccessibleType()
 | |
| {
 | |
|   return a11y::eHTMLCheckbox;
 | |
| }
 | |
| #endif
 | |
| 
 | |
| //------------------------------------------------------------
 | |
| NS_IMETHODIMP
 | |
| nsGfxCheckboxControlFrame::BuildDisplayList(nsDisplayListBuilder*   aBuilder,
 | |
|                                             const nsRect&           aDirtyRect,
 | |
|                                             const nsDisplayListSet& aLists)
 | |
| {
 | |
|   nsresult rv = nsFormControlFrame::BuildDisplayList(aBuilder, aDirtyRect,
 | |
|                                                      aLists);
 | |
|   NS_ENSURE_SUCCESS(rv, rv);
 | |
|   
 | |
|   // Get current checked state through content model.
 | |
|   if ((!IsChecked() && !IsIndeterminate()) || !IsVisibleForPainting(aBuilder))
 | |
|     return NS_OK;   // we're not checked or not visible, nothing to paint.
 | |
|     
 | |
|   if (IsThemed())
 | |
|     return NS_OK; // No need to paint the checkmark. The theme will do it.
 | |
| 
 | |
|   return 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;
 | |
| }
 | |
| 
 | |
| bool
 | |
| nsGfxCheckboxControlFrame::IsIndeterminate()
 | |
| {
 | |
|   nsCOMPtr<nsIDOMHTMLInputElement> elem(do_QueryInterface(mContent));
 | |
|   bool retval = false;
 | |
|   elem->GetIndeterminate(&retval);
 | |
|   return retval;
 | |
| }
 | 
