1
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2
/* ***** BEGIN LICENSE BLOCK *****
3
* Version: NPL 1.1/GPL 2.0/LGPL 2.1
5
* The contents of this file are subject to the Netscape Public License
6
* Version 1.1 (the "License"); you may not use this file except in
7
* compliance with the License. You may obtain a copy of the License at
8
* http://www.mozilla.org/NPL/
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
15
* The Original Code is Mozilla Communicator client code.
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.
24
* Alternatively, the contents of this file may be used under the terms of
25
* either the GNU General Public License Version 2 or later (the "GPL"), or
26
* 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 NPL, 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 NPL, the GPL or the LGPL.
36
* ***** END LICENSE BLOCK ***** */
37
#include "nsButtonFrameRenderer.h"
38
#include "nsIRenderingContext.h"
39
#include "nsCSSRendering.h"
40
#include "nsIPresContext.h"
42
#include "nsIViewManager.h"
43
#include "nsHTMLAtoms.h"
44
#include "nsCSSPseudoElements.h"
45
#include "nsINameSpaceManager.h"
46
#include "nsStyleSet.h"
48
#define ACTIVE "active"
52
MOZ_DECL_CTOR_COUNTER(nsButtonFrameRenderer)
54
nsButtonFrameRenderer::nsButtonFrameRenderer()
56
MOZ_COUNT_CTOR(nsButtonFrameRenderer);
59
nsButtonFrameRenderer::~nsButtonFrameRenderer()
61
MOZ_COUNT_DTOR(nsButtonFrameRenderer);
65
nsButtonFrameRenderer::SetFrame(nsFrame* aFrame, nsIPresContext* aPresContext)
68
ReResolveStyles(aPresContext);
72
nsButtonFrameRenderer::GetFrame()
78
nsButtonFrameRenderer::SetDisabled(PRBool aDisabled, PRBool notify)
81
mFrame->GetContent()->SetAttr(kNameSpaceID_None, nsHTMLAtoms::disabled, nsString(),
84
mFrame->GetContent()->UnsetAttr(kNameSpaceID_None, nsHTMLAtoms::disabled, notify);
88
nsButtonFrameRenderer::isDisabled()
92
if (NS_CONTENT_ATTR_HAS_VALUE ==
93
mFrame->GetContent()->GetAttr(kNameSpaceID_None, nsHTMLAtoms::disabled, value))
100
nsButtonFrameRenderer::PaintButton (nsIPresContext* aPresContext,
101
nsIRenderingContext& aRenderingContext,
102
const nsRect& aDirtyRect,
105
//printf("painted width='%d' height='%d'\n",aRect.width, aRect.height);
107
// draw the border and background inside the focus and outline borders
108
PaintBorderAndBackground(aPresContext, aRenderingContext, aDirtyRect, aRect);
110
// draw the focus and outline borders
111
PaintOutlineAndFocusBorders(aPresContext, aRenderingContext, aDirtyRect, aRect);
115
nsButtonFrameRenderer::PaintOutlineAndFocusBorders(nsIPresContext* aPresContext,
116
nsIRenderingContext& aRenderingContext,
117
const nsRect& aDirtyRect,
120
// once we have all that let draw the focus if we have it. We will need to draw 2 focuses.
121
// the inner and the outer. This is so we can do any kind of look and feel some buttons have
122
// focus on the outside like mac and motif. While others like windows have it inside (dotted line).
123
// Usually only one will be specifed. But I guess you could have both if you wanted to.
127
if (mOuterFocusStyle) {
128
// ---------- paint the outer focus border -------------
130
GetButtonOuterFocusRect(aRect, rect);
132
const nsStyleBorder* border = mOuterFocusStyle->GetStyleBorder();
133
nsCSSRendering::PaintBorder(aPresContext, aRenderingContext, mFrame,
134
aDirtyRect, rect, *border, mOuterFocusStyle, 0);
137
if (mInnerFocusStyle) {
138
// ---------- paint the inner focus border -------------
140
GetButtonInnerFocusRect(aRect, rect);
142
const nsStyleBorder* border = mInnerFocusStyle->GetStyleBorder();
143
nsCSSRendering::PaintBorder(aPresContext, aRenderingContext, mFrame,
144
aDirtyRect, rect, *border, mInnerFocusStyle, 0);
150
nsButtonFrameRenderer::PaintBorderAndBackground(nsIPresContext* aPresContext,
151
nsIRenderingContext& aRenderingContext,
152
const nsRect& aDirtyRect,
156
// get the button rect this is inside the focus and outline rects
158
GetButtonRect(aRect, buttonRect);
160
nsStyleContext* context = mFrame->GetStyleContext();
162
const nsStyleBorder* border = context->GetStyleBorder();
163
const nsStylePadding* padding = context->GetStylePadding();
165
nsCSSRendering::PaintBackground(aPresContext, aRenderingContext, mFrame,
166
aDirtyRect, buttonRect, *border, *padding,
168
nsCSSRendering::PaintBorder(aPresContext, aRenderingContext, mFrame,
169
aDirtyRect, buttonRect, *border, context, 0);
174
nsButtonFrameRenderer::GetButtonOutlineRect(const nsRect& aRect, nsRect& outlineRect)
177
outlineRect.Inflate(GetButtonOutlineBorderAndPadding());
182
nsButtonFrameRenderer::GetButtonOuterFocusRect(const nsRect& aRect, nsRect& focusRect)
188
nsButtonFrameRenderer::GetButtonRect(const nsRect& aRect, nsRect& r)
191
r.Deflate(GetButtonOuterFocusBorderAndPadding());
196
nsButtonFrameRenderer::GetButtonInnerFocusRect(const nsRect& aRect, nsRect& focusRect)
198
GetButtonRect(aRect, focusRect);
199
focusRect.Deflate(GetButtonBorderAndPadding());
200
focusRect.Deflate(GetButtonInnerFocusMargin());
204
nsButtonFrameRenderer::GetButtonContentRect(const nsRect& aRect, nsRect& r)
206
GetButtonInnerFocusRect(aRect, r);
207
r.Deflate(GetButtonInnerFocusBorderAndPadding());
212
nsButtonFrameRenderer::GetButtonOuterFocusBorderAndPadding()
214
nsMargin focusBorderAndPadding(0,0,0,0);
216
if (mOuterFocusStyle) {
217
nsStyleBorderPadding bPad;
218
mOuterFocusStyle->GetBorderPaddingFor(bPad);
219
if (!bPad.GetBorderPadding(focusBorderAndPadding)) {
220
NS_NOTYETIMPLEMENTED("percentage border");
224
return focusBorderAndPadding;
228
nsButtonFrameRenderer::GetButtonBorderAndPadding()
230
nsStyleContext* context = mFrame->GetStyleContext();
232
nsMargin innerFocusBorderAndPadding(0,0,0,0);
233
nsStyleBorderPadding bPad;
234
context->GetBorderPaddingFor(bPad);
235
if (!bPad.GetBorderPadding(innerFocusBorderAndPadding)) {
236
NS_NOTYETIMPLEMENTED("percentage border");
238
return innerFocusBorderAndPadding;
242
* Gets the size of the buttons border this is the union of the normal and disabled borders.
245
nsButtonFrameRenderer::GetButtonInnerFocusMargin()
247
nsMargin innerFocusMargin(0,0,0,0);
249
if (mInnerFocusStyle) {
250
// get the outer focus border and padding
251
const nsStyleMargin* margin = mInnerFocusStyle->GetStyleMargin();
252
margin->GetMargin(innerFocusMargin);
255
return innerFocusMargin;
259
nsButtonFrameRenderer::GetButtonInnerFocusBorderAndPadding()
261
nsMargin innerFocusBorderAndPadding(0,0,0,0);
263
if (mInnerFocusStyle) {
264
// get the outer focus border and padding
265
nsStyleBorderPadding bPad;
266
mInnerFocusStyle->GetBorderPaddingFor(bPad);
267
if (!bPad.GetBorderPadding(innerFocusBorderAndPadding)) {
268
NS_NOTYETIMPLEMENTED("percentage border");
272
return innerFocusBorderAndPadding;
276
nsButtonFrameRenderer::GetButtonOutlineBorderAndPadding()
278
nsMargin borderAndPadding(0,0,0,0);
279
return borderAndPadding;
282
// gets the full size of our border with all the focus borders
284
nsButtonFrameRenderer::GetFullButtonBorderAndPadding()
286
return GetAddedButtonBorderAndPadding() + GetButtonBorderAndPadding();
289
// gets all the focus borders and padding that will be added to the regular border
291
nsButtonFrameRenderer::GetAddedButtonBorderAndPadding()
293
return GetButtonOuterFocusBorderAndPadding() + GetButtonInnerFocusMargin() + GetButtonInnerFocusBorderAndPadding();
297
* Call this when styles change
300
nsButtonFrameRenderer::ReResolveStyles(nsIPresContext* aPresContext)
302
// get all the styles
303
nsStyleContext* context = mFrame->GetStyleContext();
304
nsStyleSet *styleSet = aPresContext->StyleSet();
306
// style for the inner such as a dotted line (Windows)
307
mInnerFocusStyle = styleSet->ProbePseudoStyleFor(mFrame->GetContent(),
308
nsCSSPseudoElements::mozFocusInner,
311
// style for outer focus like a ridged border (MAC).
312
mOuterFocusStyle = styleSet->ProbePseudoStyleFor(mFrame->GetContent(),
313
nsCSSPseudoElements::mozFocusOuter,
318
nsButtonFrameRenderer::GetStyleContext(PRInt32 aIndex) const
321
case NS_BUTTON_RENDERER_FOCUS_INNER_CONTEXT_INDEX:
322
return mInnerFocusStyle;
323
case NS_BUTTON_RENDERER_FOCUS_OUTER_CONTEXT_INDEX:
324
return mOuterFocusStyle;
331
nsButtonFrameRenderer::SetStyleContext(PRInt32 aIndex, nsStyleContext* aStyleContext)
334
case NS_BUTTON_RENDERER_FOCUS_INNER_CONTEXT_INDEX:
335
mInnerFocusStyle = aStyleContext;
337
case NS_BUTTON_RENDERER_FOCUS_OUTER_CONTEXT_INDEX:
338
mOuterFocusStyle = aStyleContext;