~ubuntu-branches/ubuntu/precise/kompozer/precise

« back to all changes in this revision

Viewing changes to mozilla/layout/html/forms/src/nsButtonFrameRenderer.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Anthony Yarusso
  • Date: 2007-08-27 01:11:03 UTC
  • Revision ID: james.westby@ubuntu.com-20070827011103-2jgf4s6532gqu2ka
Tags: upstream-0.7.10
ImportĀ upstreamĀ versionĀ 0.7.10

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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
 
4
 *
 
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/
 
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 Communicator client 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 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.
 
35
 *
 
36
 * ***** END LICENSE BLOCK ***** */
 
37
#include "nsButtonFrameRenderer.h"
 
38
#include "nsIRenderingContext.h"
 
39
#include "nsCSSRendering.h"
 
40
#include "nsIPresContext.h"
 
41
#include "nsIView.h"
 
42
#include "nsIViewManager.h"
 
43
#include "nsHTMLAtoms.h"
 
44
#include "nsCSSPseudoElements.h"
 
45
#include "nsINameSpaceManager.h"
 
46
#include "nsStyleSet.h"
 
47
 
 
48
#define ACTIVE   "active"
 
49
#define HOVER    "hover"
 
50
#define FOCUS    "focus"
 
51
 
 
52
MOZ_DECL_CTOR_COUNTER(nsButtonFrameRenderer)
 
53
 
 
54
nsButtonFrameRenderer::nsButtonFrameRenderer()
 
55
{
 
56
  MOZ_COUNT_CTOR(nsButtonFrameRenderer);
 
57
}
 
58
 
 
59
nsButtonFrameRenderer::~nsButtonFrameRenderer()
 
60
{
 
61
  MOZ_COUNT_DTOR(nsButtonFrameRenderer);
 
62
}
 
63
 
 
64
void
 
65
nsButtonFrameRenderer::SetFrame(nsFrame* aFrame, nsIPresContext* aPresContext)
 
66
{
 
67
  mFrame = aFrame;
 
68
  ReResolveStyles(aPresContext);
 
69
}
 
70
 
 
71
nsIFrame*
 
72
nsButtonFrameRenderer::GetFrame()
 
73
{
 
74
  return mFrame;
 
75
}
 
76
 
 
77
void
 
78
nsButtonFrameRenderer::SetDisabled(PRBool aDisabled, PRBool notify)
 
79
{
 
80
  if (aDisabled)
 
81
    mFrame->GetContent()->SetAttr(kNameSpaceID_None, nsHTMLAtoms::disabled, nsString(),
 
82
                                  notify);
 
83
  else
 
84
    mFrame->GetContent()->UnsetAttr(kNameSpaceID_None, nsHTMLAtoms::disabled, notify);
 
85
}
 
86
 
 
87
PRBool
 
88
nsButtonFrameRenderer::isDisabled() 
 
89
{
 
90
  // get the content
 
91
  nsAutoString value;
 
92
  if (NS_CONTENT_ATTR_HAS_VALUE ==
 
93
      mFrame->GetContent()->GetAttr(kNameSpaceID_None, nsHTMLAtoms::disabled, value))
 
94
    return PR_TRUE;
 
95
 
 
96
  return PR_FALSE;
 
97
}
 
98
 
 
99
void 
 
100
nsButtonFrameRenderer::PaintButton     (nsIPresContext* aPresContext,
 
101
          nsIRenderingContext& aRenderingContext,
 
102
          const nsRect& aDirtyRect,
 
103
          const nsRect& aRect)
 
104
{
 
105
  //printf("painted width='%d' height='%d'\n",aRect.width, aRect.height);
 
106
 
 
107
  // draw the border and background inside the focus and outline borders
 
108
  PaintBorderAndBackground(aPresContext, aRenderingContext, aDirtyRect, aRect);
 
109
 
 
110
  // draw the focus and outline borders
 
111
  PaintOutlineAndFocusBorders(aPresContext, aRenderingContext, aDirtyRect, aRect);
 
112
}
 
113
 
 
114
void
 
115
nsButtonFrameRenderer::PaintOutlineAndFocusBorders(nsIPresContext* aPresContext,
 
116
          nsIRenderingContext& aRenderingContext,
 
117
          const nsRect& aDirtyRect,
 
118
          const nsRect& aRect)
 
119
{
 
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.
 
124
 
 
125
  nsRect rect;
 
126
 
 
127
  if (mOuterFocusStyle) {
 
128
    // ---------- paint the outer focus border -------------
 
129
 
 
130
    GetButtonOuterFocusRect(aRect, rect);
 
131
 
 
132
    const nsStyleBorder* border = mOuterFocusStyle->GetStyleBorder();
 
133
    nsCSSRendering::PaintBorder(aPresContext, aRenderingContext, mFrame,
 
134
                                aDirtyRect, rect, *border, mOuterFocusStyle, 0);
 
135
  }
 
136
 
 
137
  if (mInnerFocusStyle) { 
 
138
    // ---------- paint the inner focus border -------------
 
139
 
 
140
    GetButtonInnerFocusRect(aRect, rect);
 
141
 
 
142
    const nsStyleBorder* border = mInnerFocusStyle->GetStyleBorder();
 
143
    nsCSSRendering::PaintBorder(aPresContext, aRenderingContext, mFrame,
 
144
                                aDirtyRect, rect, *border, mInnerFocusStyle, 0);
 
145
  }
 
146
}
 
147
 
 
148
 
 
149
void
 
150
nsButtonFrameRenderer::PaintBorderAndBackground(nsIPresContext* aPresContext,
 
151
          nsIRenderingContext& aRenderingContext,
 
152
          const nsRect& aDirtyRect,
 
153
          const nsRect& aRect)
 
154
 
 
155
{
 
156
  // get the button rect this is inside the focus and outline rects
 
157
  nsRect buttonRect;
 
158
  GetButtonRect(aRect, buttonRect);
 
159
 
 
160
  nsStyleContext* context = mFrame->GetStyleContext();
 
161
 
 
162
  const nsStyleBorder* border = context->GetStyleBorder();
 
163
  const nsStylePadding* padding = context->GetStylePadding();
 
164
 
 
165
  nsCSSRendering::PaintBackground(aPresContext, aRenderingContext, mFrame,
 
166
                                  aDirtyRect, buttonRect, *border, *padding,
 
167
                                  PR_FALSE);
 
168
  nsCSSRendering::PaintBorder(aPresContext, aRenderingContext, mFrame,
 
169
                              aDirtyRect, buttonRect, *border, context, 0);
 
170
}
 
171
 
 
172
 
 
173
void
 
174
nsButtonFrameRenderer::GetButtonOutlineRect(const nsRect& aRect, nsRect& outlineRect)
 
175
{
 
176
  outlineRect = aRect;
 
177
  outlineRect.Inflate(GetButtonOutlineBorderAndPadding());
 
178
}
 
179
 
 
180
 
 
181
void
 
182
nsButtonFrameRenderer::GetButtonOuterFocusRect(const nsRect& aRect, nsRect& focusRect)
 
183
{
 
184
  focusRect = aRect;
 
185
}
 
186
 
 
187
void
 
188
nsButtonFrameRenderer::GetButtonRect(const nsRect& aRect, nsRect& r)
 
189
{
 
190
  r = aRect;
 
191
  r.Deflate(GetButtonOuterFocusBorderAndPadding());
 
192
}
 
193
 
 
194
 
 
195
void
 
196
nsButtonFrameRenderer::GetButtonInnerFocusRect(const nsRect& aRect, nsRect& focusRect)
 
197
{
 
198
  GetButtonRect(aRect, focusRect);
 
199
  focusRect.Deflate(GetButtonBorderAndPadding());
 
200
  focusRect.Deflate(GetButtonInnerFocusMargin());
 
201
}
 
202
 
 
203
void
 
204
nsButtonFrameRenderer::GetButtonContentRect(const nsRect& aRect, nsRect& r)
 
205
{
 
206
  GetButtonInnerFocusRect(aRect, r);
 
207
  r.Deflate(GetButtonInnerFocusBorderAndPadding());
 
208
}
 
209
 
 
210
 
 
211
nsMargin
 
212
nsButtonFrameRenderer::GetButtonOuterFocusBorderAndPadding()
 
213
{
 
214
  nsMargin focusBorderAndPadding(0,0,0,0);
 
215
 
 
216
  if (mOuterFocusStyle) {
 
217
    nsStyleBorderPadding  bPad;
 
218
    mOuterFocusStyle->GetBorderPaddingFor(bPad);
 
219
    if (!bPad.GetBorderPadding(focusBorderAndPadding)) {
 
220
      NS_NOTYETIMPLEMENTED("percentage border");
 
221
    }
 
222
  }
 
223
 
 
224
  return focusBorderAndPadding;
 
225
}
 
226
 
 
227
nsMargin
 
228
nsButtonFrameRenderer::GetButtonBorderAndPadding()
 
229
{
 
230
  nsStyleContext* context = mFrame->GetStyleContext();
 
231
 
 
232
  nsMargin innerFocusBorderAndPadding(0,0,0,0);
 
233
  nsStyleBorderPadding  bPad;
 
234
  context->GetBorderPaddingFor(bPad);
 
235
  if (!bPad.GetBorderPadding(innerFocusBorderAndPadding)) {
 
236
    NS_NOTYETIMPLEMENTED("percentage border");
 
237
  }
 
238
  return innerFocusBorderAndPadding;
 
239
}
 
240
 
 
241
/**
 
242
 * Gets the size of the buttons border this is the union of the normal and disabled borders.
 
243
 */
 
244
nsMargin
 
245
nsButtonFrameRenderer::GetButtonInnerFocusMargin()
 
246
{
 
247
  nsMargin innerFocusMargin(0,0,0,0);
 
248
 
 
249
  if (mInnerFocusStyle) {
 
250
    // get the outer focus border and padding
 
251
    const nsStyleMargin* margin = mInnerFocusStyle->GetStyleMargin();
 
252
    margin->GetMargin(innerFocusMargin);
 
253
  }
 
254
 
 
255
  return innerFocusMargin;
 
256
}
 
257
 
 
258
nsMargin
 
259
nsButtonFrameRenderer::GetButtonInnerFocusBorderAndPadding()
 
260
{
 
261
  nsMargin innerFocusBorderAndPadding(0,0,0,0);
 
262
 
 
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");
 
269
    }
 
270
  }
 
271
 
 
272
  return innerFocusBorderAndPadding;
 
273
}
 
274
 
 
275
nsMargin
 
276
nsButtonFrameRenderer::GetButtonOutlineBorderAndPadding()
 
277
{
 
278
  nsMargin borderAndPadding(0,0,0,0);
 
279
  return borderAndPadding;
 
280
}
 
281
 
 
282
// gets the full size of our border with all the focus borders
 
283
nsMargin
 
284
nsButtonFrameRenderer::GetFullButtonBorderAndPadding()
 
285
{
 
286
  return GetAddedButtonBorderAndPadding() + GetButtonBorderAndPadding();
 
287
}
 
288
 
 
289
// gets all the focus borders and padding that will be added to the regular border
 
290
nsMargin
 
291
nsButtonFrameRenderer::GetAddedButtonBorderAndPadding()
 
292
{
 
293
  return GetButtonOuterFocusBorderAndPadding() + GetButtonInnerFocusMargin() + GetButtonInnerFocusBorderAndPadding();
 
294
}
 
295
 
 
296
/**
 
297
 * Call this when styles change
 
298
 */
 
299
void 
 
300
nsButtonFrameRenderer::ReResolveStyles(nsIPresContext* aPresContext)
 
301
{
 
302
  // get all the styles
 
303
  nsStyleContext* context = mFrame->GetStyleContext();
 
304
  nsStyleSet *styleSet = aPresContext->StyleSet();
 
305
 
 
306
  // style for the inner such as a dotted line (Windows)
 
307
  mInnerFocusStyle = styleSet->ProbePseudoStyleFor(mFrame->GetContent(),
 
308
                                                   nsCSSPseudoElements::mozFocusInner,
 
309
                                                   context);
 
310
 
 
311
  // style for outer focus like a ridged border (MAC).
 
312
  mOuterFocusStyle = styleSet->ProbePseudoStyleFor(mFrame->GetContent(),
 
313
                                                   nsCSSPseudoElements::mozFocusOuter,
 
314
                                                   context);
 
315
}
 
316
 
 
317
nsStyleContext*
 
318
nsButtonFrameRenderer::GetStyleContext(PRInt32 aIndex) const
 
319
{
 
320
  switch (aIndex) {
 
321
  case NS_BUTTON_RENDERER_FOCUS_INNER_CONTEXT_INDEX:
 
322
    return mInnerFocusStyle;
 
323
  case NS_BUTTON_RENDERER_FOCUS_OUTER_CONTEXT_INDEX:
 
324
    return mOuterFocusStyle;
 
325
  default:
 
326
    return nsnull;
 
327
  }
 
328
}
 
329
 
 
330
void 
 
331
nsButtonFrameRenderer::SetStyleContext(PRInt32 aIndex, nsStyleContext* aStyleContext)
 
332
{
 
333
  switch (aIndex) {
 
334
  case NS_BUTTON_RENDERER_FOCUS_INNER_CONTEXT_INDEX:
 
335
    mInnerFocusStyle = aStyleContext;
 
336
    break;
 
337
  case NS_BUTTON_RENDERER_FOCUS_OUTER_CONTEXT_INDEX:
 
338
    mOuterFocusStyle = aStyleContext;
 
339
    break;
 
340
  }
 
341
}