This commit is contained in:
pinkerton%netscape.com 1999-04-15 19:43:35 +00:00
Родитель 23f81e9c7c
Коммит 581acc5c8a
2 изменённых файлов: 399 добавлений и 0 удалений

Просмотреть файл

@ -0,0 +1,289 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#include "nsTriStateCheckboxFrame.h"
#include "nsFormControlHelper.h"
#include "nsIContent.h"
#include "prtypes.h"
#include "nsIFrame.h"
#include "nsIAtom.h"
#include "nsIPresContext.h"
#include "nsHTMLAtoms.h"
#include "nsIStyleContext.h"
#include "nsStyleUtil.h"
#include "nsIFormControl.h"
#include "nsCSSRendering.h"
#include "nsINameSpaceManager.h"
//
// NS_NewTriStateCheckboxFrame
//
// Wrapper for creating a new tristate checkbox
//
nsresult
NS_NewTriStateCheckboxFrame(nsIFrame*& aResult)
{
aResult = new nsTriStateCheckboxFrame;
if ( !aResult )
return NS_ERROR_OUT_OF_MEMORY;
return NS_OK;
}
//
// nsTriStateCheckboxFrame cntr
//
nsTriStateCheckboxFrame::nsTriStateCheckboxFrame()
: mMouseDownOnCheckbox(PR_FALSE)
{
}
//
// GetCurrentCheckState
//
// Looks in the DOM to find out what the value is. 0 is off, 1 is on, 2 is mixed.
// This will default to "off" if no value is set in the DOM.
//
nsresult
nsTriStateCheckboxFrame::GetCurrentCheckState(CheckState *outState)
{
nsString value;
nsresult res = mContent->GetAttribute ( kNameSpaceID_None, nsHTMLAtoms::value, value );
if ( res == NS_CONTENT_ATTR_HAS_VALUE )
*outState = StringToCheckState(value);
else
*outState = eOff;
printf("getting value, it is %s\n", value.ToNewCString());
return NS_OK;
}
//
// SetCurrentCheckState
//
// Sets the value in the DOM. 0 is off, 1 is on, 2 is mixed.
//
nsresult
nsTriStateCheckboxFrame::SetCurrentCheckState(CheckState aState)
{
nsString valueAsString;
CheckStateToString ( aState, valueAsString );
printf("setting value, it is %s\n", valueAsString.ToNewCString());
return mContent->SetAttribute ( kNameSpaceID_None, nsHTMLAtoms::value, valueAsString, PR_TRUE );
} // SetCurrentCheckState
//
// MouseClicked
//
// handle when the mouse is clicked in the box. If the check is on or off, toggle it.
// If the state is mixed, then set it to off. You can't ever get back to mixed.
//
void
nsTriStateCheckboxFrame::MouseClicked(nsIPresContext* aPresContext)
{
mMouseDownOnCheckbox = PR_FALSE;
CheckState oldState;
GetCurrentCheckState(&oldState);
CheckState newState = eOn;
switch ( oldState ) {
case eOn:
case eMixed:
newState = eOff;
break;
}
SetCurrentCheckState(newState);
}
//
// GetMaxNumValues
//
// Because we have a mixed state, we go up to two.
//
PRInt32
nsTriStateCheckboxFrame::GetMaxNumValues()
{
return 2;
}
//
// PaintCheckBox
//
// Paint the checkbox depending on the mode
//
void
nsTriStateCheckboxFrame::PaintCheckBox(nsIPresContext& aPresContext,
nsIRenderingContext& aRenderingContext,
const nsRect& aDirtyRect,
nsFramePaintLayer aWhichLayer)
{
aRenderingContext.PushState();
float p2t;
aPresContext.GetScaledPixelsToTwips(&p2t);
CheckState checked = eOff;
// Get current checked state through content model.
// XXX: This is very inefficient, but it is necessary in the case of printing.
// During printing the Paint is called but the actual state of the checkbox
// is in a frame in presentation shell 0.
/*XXXnsresult result = */GetCurrentCheckState(&checked);
if ( checked == eOn ) {
// Draw check mark
const nsStyleColor* color = (const nsStyleColor*)
mStyleContext->GetStyleData(eStyleStruct_Color);
aRenderingContext.SetColor(color->mColor);
printf("painting checkbox\n");
nsFormControlHelper::PaintCheckMark(aRenderingContext,
p2t, mRect.width, mRect.height);
}
PRBool clip;
aRenderingContext.PopState(clip);
}
//
// Paint
//
// Overidden to handle drawing the checkmark in addition to everything else
//
NS_METHOD
nsTriStateCheckboxFrame::Paint(nsIPresContext& aPresContext,
nsIRenderingContext& aRenderingContext,
const nsRect& aDirtyRect,
nsFramePaintLayer aWhichLayer)
{
printf("painting checkbox\n");
// Paint the background
nsFormControlFrame::Paint(aPresContext, aRenderingContext, aDirtyRect, aWhichLayer);
if (NS_FRAME_PAINT_LAYER_FOREGROUND == aWhichLayer) {
// Paint the checkmark
PaintCheckBox(aPresContext, aRenderingContext, aDirtyRect, aWhichLayer);
}
return NS_OK;
}
//
// HandleEvent
//
// Track the mouse and handle clicks
//
NS_METHOD
nsTriStateCheckboxFrame::HandleEvent(nsIPresContext& aPresContext,
nsGUIEvent* aEvent,
nsEventStatus& aEventStatus)
{
if (nsEventStatus_eConsumeNoDefault == aEventStatus) {
return NS_OK;
}
switch(aEvent->message) {
case NS_KEY_PRESS:
if (NS_KEY_EVENT == aEvent->eventStructType) {
nsKeyEvent* keyEvent = (nsKeyEvent*)aEvent;
if (NS_VK_SPACE == keyEvent->keyCode || NS_VK_RETURN == keyEvent->keyCode) {
MouseClicked(&aPresContext);
}
}
break;
default:
break;
}
// Handle GFX rendered widget Mouse Down event
switch (aEvent->message) {
case NS_MOUSE_LEFT_BUTTON_DOWN:
mMouseDownOnCheckbox = PR_TRUE;
//XXX: TODO render gray rectangle on mouse down
break;
case NS_MOUSE_EXIT:
mMouseDownOnCheckbox = PR_FALSE;
//XXX: TO DO clear gray rectangle on mouse up
break;
}
return(nsFormControlFrame::HandleEvent(aPresContext, aEvent, aEventStatus));
}
//
// RequiresWidget
//
// Tell callers that we are GFX rendered through and through
//
nsresult
nsTriStateCheckboxFrame::RequiresWidget(PRBool& aRequiresWidget)
{
aRequiresWidget = PR_FALSE;
return NS_OK;
}
//
// StringToCheckState
//
// Converts from a string to a CheckState enum
//
nsTriStateCheckboxFrame::CheckState
nsTriStateCheckboxFrame :: StringToCheckState ( const nsString & aStateAsString )
{
if ( aStateAsString == NS_STRING_TRUE )
return eOn;
else if ( aStateAsString == NS_STRING_FALSE )
return eOff;
// not true and not false means mixed
return eMixed;
} // StringToCheckState
//
// CheckStateToString
//
// Converts from a CheckState to a string
//
void
nsTriStateCheckboxFrame :: CheckStateToString ( CheckState inState, nsString& outStateAsString )
{
switch ( inState ) {
case eOn:
outStateAsString = NS_STRING_TRUE;
break;
case eOff:
outStateAsString = NS_STRING_FALSE;
break;
case eMixed:
outStateAsString = "2";
break;
}
} // CheckStateToString

Просмотреть файл

@ -0,0 +1,110 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
//
// nsTriStateCheckboxFrame
//
// A sibling of a checkbox, but with an extra state, mixed, that represents
// something in between on and off.
//
// An example will explain it best. Say you
// select some text, part of which is bold, and go to a dialog that lets you
// customize the styles of that text. The checkboxes for each style should
// represent the current state of the text, but what value should the "Bold"
// checkbox have? All the text isn't bold, so it shouldn't be on, but some
// if it is, so you want to indicate that to the user. Hence, a 3rd state.
//
// Clicking the control when it is mixed would uncheck the control, as if
// it is totally off. In the above example, the entire selection would be
// unbolded. Clicking it again would check the control and bold the entire
// selection. Note that there is no way to get back to the mixed state. This
// is by design. It just doesn't make any sense. What that action really means
// would be satisfied by "Cancel" or "Undo" which is beyond the scope of
// the control.
//
#ifndef nsTriStateCheckboxFrame_h__
#define nsTriStateCheckboxFrame_h__
#include "nsFormControlFrame.h"
#include "prtypes.h"
class nsIPresContext;
class nsString;
class nsIContent;
class nsIAtom;
nsresult NS_NewTriStateCheckboxFrame(nsIFrame*& aResult) ;
class nsTriStateCheckboxFrame : public nsFormControlFrame
{
public:
nsTriStateCheckboxFrame();
NS_IMETHOD GetFrameName(nsString& aResult) const {
return MakeFrameName("TriStateCheckboxFrame", aResult);
}
virtual PRInt32 GetMaxNumValues();
// nsFormControlFrame overrides
nsresult RequiresWidget(PRBool &aHasWidget);
//
// Methods used to GFX-render the checkbox
//
NS_IMETHOD Paint(nsIPresContext& aPresContext,
nsIRenderingContext& aRenderingContext,
const nsRect& aDirtyRect,
nsFramePaintLayer aWhichLayer);
NS_IMETHOD HandleEvent(nsIPresContext& aPresContext,
nsGUIEvent* aEvent,
nsEventStatus& aEventStatus);
//End of GFX-rendering methods
protected:
enum CheckState { eOff, eOn, eMixed } ;
nsresult GetCurrentCheckState(CheckState *outState) ;
nsresult SetCurrentCheckState(CheckState aState) ;
virtual void MouseClicked(nsIPresContext* aPresContext);
virtual void PaintCheckBox(nsIPresContext& aPresContext,
nsIRenderingContext& aRenderingContext,
const nsRect& aDirtyRect,
nsFramePaintLayer aWhichLayer);
// utility routine for converting from DOM values to internal enum
void CheckStateToString ( CheckState inState, nsString& outStateAsString ) ;
CheckState StringToCheckState ( const nsString & aStateAsString ) ;
//GFX-rendered state variables
PRBool mMouseDownOnCheckbox;
}; // class nsTriStateCheckboxFrame
#endif