2007-03-22 10:30:00 -07:00
|
|
|
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
|
|
/* ***** BEGIN LICENSE BLOCK *****
|
|
|
|
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
|
|
|
*
|
|
|
|
* The contents of this file are subject to the Mozilla Public License Version
|
|
|
|
* 1.1 (the "License"); you may not use this file except in compliance with
|
|
|
|
* the License. You may obtain a copy of the License at
|
|
|
|
* http://www.mozilla.org/MPL/
|
|
|
|
*
|
|
|
|
* Software distributed under the License is distributed on an "AS IS" basis,
|
|
|
|
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
|
|
|
* for the specific language governing rights and limitations under the
|
|
|
|
* License.
|
|
|
|
*
|
|
|
|
* The Original Code is mozilla.org code.
|
|
|
|
*
|
|
|
|
* The Initial Developer of the Original Code is
|
|
|
|
* Mike Pinkerton (pinkerton@netscape.com).
|
|
|
|
* Portions created by the Initial Developer are Copyright (C) 2001
|
|
|
|
* the Initial Developer. All Rights Reserved.
|
|
|
|
*
|
|
|
|
* Contributor(s):
|
|
|
|
* Vladimir Vukicevic <vladimir@pobox.com> (HITheme rewrite)
|
|
|
|
* Josh Aas <josh@mozilla.com>
|
2007-04-10 17:25:11 -07:00
|
|
|
* Colin Barrett <cbarrett@mozilla.com>
|
2007-03-22 10:30:00 -07:00
|
|
|
*
|
|
|
|
* Alternatively, the contents of this file may be used under the terms of
|
|
|
|
* either of the GNU General Public License Version 2 or later (the "GPL"),
|
|
|
|
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
|
|
|
* in which case the provisions of the GPL or the LGPL are applicable instead
|
|
|
|
* of those above. If you wish to allow use of your version of this file only
|
|
|
|
* under the terms of either the GPL or the LGPL, and not to allow others to
|
|
|
|
* use your version of this file under the terms of the MPL, indicate your
|
|
|
|
* decision by deleting the provisions above and replace them with the notice
|
|
|
|
* and other provisions required by the GPL or the LGPL. If you do not delete
|
|
|
|
* the provisions above, a recipient may use your version of this file under
|
|
|
|
* the terms of any one of the MPL, the GPL or the LGPL.
|
|
|
|
*
|
|
|
|
* ***** END LICENSE BLOCK ***** */
|
|
|
|
|
|
|
|
#include "nsNativeThemeCocoa.h"
|
|
|
|
#include "nsIRenderingContext.h"
|
|
|
|
#include "nsRect.h"
|
|
|
|
#include "nsSize.h"
|
|
|
|
#include "nsThemeConstants.h"
|
|
|
|
#include "nsIPresShell.h"
|
|
|
|
#include "nsPresContext.h"
|
|
|
|
#include "nsIContent.h"
|
|
|
|
#include "nsIDocument.h"
|
|
|
|
#include "nsIFrame.h"
|
|
|
|
#include "nsIAtom.h"
|
|
|
|
#include "nsIEventStateManager.h"
|
|
|
|
#include "nsINameSpaceManager.h"
|
|
|
|
#include "nsPresContext.h"
|
|
|
|
#include "nsILookAndFeel.h"
|
|
|
|
#include "nsWidgetAtoms.h"
|
|
|
|
|
|
|
|
#include "gfxContext.h"
|
|
|
|
#include "gfxQuartzSurface.h"
|
|
|
|
|
2007-05-02 16:47:53 -07:00
|
|
|
#import <Cocoa/Cocoa.h>
|
|
|
|
|
2007-03-22 10:30:00 -07:00
|
|
|
#define DRAW_IN_FRAME_DEBUG 0
|
2007-04-10 17:25:11 -07:00
|
|
|
#define SCROLLBARS_VISUAL_DEBUG 0
|
2007-03-22 10:30:00 -07:00
|
|
|
|
2007-08-07 12:36:40 -07:00
|
|
|
// see cairo-quartz-surface.c for the complete list of these
|
|
|
|
enum {
|
|
|
|
kPrivateCGCompositeSourceOver = 2
|
|
|
|
};
|
|
|
|
|
|
|
|
// private Quartz routines needed here
|
2007-03-22 10:30:00 -07:00
|
|
|
extern "C" {
|
|
|
|
CG_EXTERN void CGContextSetCTM(CGContextRef, CGAffineTransform);
|
2007-08-07 12:36:40 -07:00
|
|
|
CG_EXTERN void CGContextSetCompositeOperation (CGContextRef, int);
|
2007-03-22 10:30:00 -07:00
|
|
|
}
|
|
|
|
|
2007-04-10 17:25:11 -07:00
|
|
|
// Copied from nsLookAndFeel.h
|
|
|
|
// Apple hasn't defined a constant for scollbars with two arrows on each end, so we'll use this one.
|
|
|
|
static const int kThemeScrollBarArrowsBoth = 2;
|
|
|
|
|
2007-03-22 10:30:00 -07:00
|
|
|
#define HITHEME_ORIENTATION kHIThemeOrientationNormal
|
|
|
|
|
2007-05-08 05:54:48 -07:00
|
|
|
// Minimum size for buttons that we can create with scaling:
|
|
|
|
#define MIN_SCALED_PUSH_BUTTON_WIDTH 28
|
|
|
|
#define MIN_SCALED_PUSH_BUTTON_HEIGHT 12
|
|
|
|
// We use an offscreen buffer and image scaling to make HITheme draw buttons at any height.
|
|
|
|
// Minimum height that HITheme will draw a normal push button:
|
|
|
|
#define MIN_UNSCALED_PUSH_BUTTON_HEIGHT 22
|
|
|
|
// Difference between the height given to HITheme for a button and the button it actually draws:
|
|
|
|
#define NATIVE_PUSH_BUTTON_HEIGHT_DIFF 2
|
|
|
|
|
|
|
|
|
2007-03-22 10:30:00 -07:00
|
|
|
NS_IMPL_ISUPPORTS1(nsNativeThemeCocoa, nsITheme)
|
|
|
|
|
|
|
|
|
|
|
|
nsNativeThemeCocoa::nsNativeThemeCocoa()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
nsNativeThemeCocoa::~nsNativeThemeCocoa()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
nsNativeThemeCocoa::DrawCheckboxRadio(CGContextRef cgContext, ThemeButtonKind inKind,
|
|
|
|
const HIRect& inBoxRect, PRBool inChecked,
|
2007-08-27 21:05:12 -07:00
|
|
|
PRBool inDisabled, PRInt32 inState)
|
2007-03-22 10:30:00 -07:00
|
|
|
{
|
|
|
|
HIThemeButtonDrawInfo bdi;
|
|
|
|
bdi.version = 0;
|
|
|
|
bdi.kind = inKind;
|
|
|
|
|
|
|
|
if (inDisabled)
|
|
|
|
bdi.state = kThemeStateUnavailable;
|
|
|
|
else if ((inState & NS_EVENT_STATE_ACTIVE) && (inState & NS_EVENT_STATE_HOVER))
|
|
|
|
bdi.state = kThemeStatePressed;
|
|
|
|
else
|
2007-08-27 21:05:12 -07:00
|
|
|
bdi.state = kThemeStateActive;
|
2007-03-22 10:30:00 -07:00
|
|
|
|
|
|
|
bdi.value = inChecked ? kThemeButtonOn : kThemeButtonOff;
|
|
|
|
bdi.adornment = (inState & NS_EVENT_STATE_FOCUS) ? kThemeAdornmentFocus : kThemeAdornmentNone;
|
|
|
|
|
2007-05-17 19:01:02 -07:00
|
|
|
HIRect drawFrame = inBoxRect;
|
|
|
|
if (inKind == kThemeSmallCheckBox)
|
|
|
|
drawFrame.origin.y += 1;
|
|
|
|
|
|
|
|
HIThemeDrawButton(&drawFrame, &bdi, cgContext, HITHEME_ORIENTATION, NULL);
|
|
|
|
|
2007-03-22 10:30:00 -07:00
|
|
|
#if DRAW_IN_FRAME_DEBUG
|
|
|
|
CGContextSetRGBFillColor(cgContext, 0.0, 0.0, 0.5, 0.8);
|
|
|
|
CGContextFillRect(cgContext, inBoxRect);
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2007-04-10 17:25:11 -07:00
|
|
|
|
2007-03-22 10:30:00 -07:00
|
|
|
void
|
|
|
|
nsNativeThemeCocoa::DrawButton(CGContextRef cgContext, ThemeButtonKind inKind,
|
|
|
|
const HIRect& inBoxRect, PRBool inIsDefault, PRBool inDisabled,
|
|
|
|
ThemeButtonValue inValue, ThemeButtonAdornment inAdornment,
|
2007-08-27 21:05:12 -07:00
|
|
|
PRInt32 inState)
|
2007-03-22 10:30:00 -07:00
|
|
|
{
|
2007-05-02 16:47:53 -07:00
|
|
|
HIThemeButtonDrawInfo bdi;
|
2007-03-22 10:30:00 -07:00
|
|
|
bdi.version = 0;
|
|
|
|
bdi.kind = inKind;
|
|
|
|
bdi.value = inValue;
|
|
|
|
bdi.adornment = inAdornment;
|
2007-05-02 16:47:53 -07:00
|
|
|
|
2007-08-27 21:05:12 -07:00
|
|
|
if (inDisabled)
|
2007-03-22 10:30:00 -07:00
|
|
|
bdi.state = kThemeStateUnavailable;
|
2007-08-27 21:05:12 -07:00
|
|
|
else if ((inState & NS_EVENT_STATE_ACTIVE) && (inState & NS_EVENT_STATE_HOVER))
|
2007-03-22 10:30:00 -07:00
|
|
|
bdi.state = kThemeStatePressed;
|
2007-08-27 21:05:12 -07:00
|
|
|
else
|
|
|
|
bdi.state = (inKind == kThemeArrowButton) ? kThemeStateUnavailable : kThemeStateActive;
|
2007-03-22 10:30:00 -07:00
|
|
|
|
|
|
|
if (inState & NS_EVENT_STATE_FOCUS)
|
|
|
|
bdi.adornment |= kThemeAdornmentFocus;
|
|
|
|
|
|
|
|
if (inIsDefault && !inDisabled)
|
|
|
|
bdi.adornment |= kThemeAdornmentDefault;
|
|
|
|
|
2007-05-02 16:47:53 -07:00
|
|
|
// If any of the origin and size offset arithmatic seems strange here, check out the
|
|
|
|
// actual dimensions of an HITheme button compared to the rect you pass to HIThemeDrawButton.
|
2007-05-08 05:54:48 -07:00
|
|
|
if (inKind == kThemePushButton && inBoxRect.size.height < MIN_UNSCALED_PUSH_BUTTON_HEIGHT) {
|
2007-06-17 17:29:34 -07:00
|
|
|
// adjust width up to componsate for the down-scaling we will do later
|
|
|
|
float scaleFactor = inBoxRect.size.height / MIN_UNSCALED_PUSH_BUTTON_HEIGHT;
|
2007-05-02 16:47:53 -07:00
|
|
|
// We'll use these two values to size the button we draw offscreen
|
2007-06-17 17:29:34 -07:00
|
|
|
float offscreenWidth = inBoxRect.size.width / scaleFactor;
|
2007-05-08 05:54:48 -07:00
|
|
|
float offscreenHeight = MIN_UNSCALED_PUSH_BUTTON_HEIGHT;
|
2007-05-02 16:47:53 -07:00
|
|
|
|
|
|
|
// create an offscreen image
|
|
|
|
NSImage* image = [[NSImage alloc] initWithSize:NSMakeSize(offscreenWidth, offscreenHeight)];
|
|
|
|
[image setDataRetained:YES];
|
|
|
|
[image setScalesWhenResized:YES];
|
|
|
|
|
|
|
|
// set up HITheme button to draw
|
|
|
|
HIRect drawFrame;
|
|
|
|
drawFrame.origin.x = 0;
|
2007-05-08 05:54:48 -07:00
|
|
|
drawFrame.origin.y = NATIVE_PUSH_BUTTON_HEIGHT_DIFF;
|
2007-05-02 16:47:53 -07:00
|
|
|
drawFrame.size.width = offscreenWidth;
|
2007-05-08 05:54:48 -07:00
|
|
|
drawFrame.size.height = offscreenHeight - NATIVE_PUSH_BUTTON_HEIGHT_DIFF;
|
2007-05-02 16:47:53 -07:00
|
|
|
|
|
|
|
// draw into offscreen image
|
|
|
|
[image lockFocus];
|
|
|
|
[[NSGraphicsContext currentContext] setImageInterpolation:NSImageInterpolationLow];
|
|
|
|
HIThemeDrawButton(&drawFrame, &bdi, (CGContext*)[[NSGraphicsContext currentContext] graphicsPort], kHIThemeOrientationInverted, NULL);
|
|
|
|
[image unlockFocus];
|
|
|
|
|
|
|
|
// resize vertically
|
2007-06-17 17:29:34 -07:00
|
|
|
[image setSize:NSMakeSize(inBoxRect.size.width, inBoxRect.size.height)];
|
2007-05-02 16:47:53 -07:00
|
|
|
|
|
|
|
// render to the given CGContextRef
|
2007-06-12 14:48:14 -07:00
|
|
|
[NSGraphicsContext saveGraphicsState];
|
|
|
|
[NSGraphicsContext setCurrentContext:[NSGraphicsContext graphicsContextWithGraphicsPort:cgContext flipped:YES]];
|
2007-05-02 16:47:53 -07:00
|
|
|
[image compositeToPoint:NSMakePoint(inBoxRect.origin.x, inBoxRect.origin.y + inBoxRect.size.height)
|
|
|
|
operation:NSCompositeSourceOver];
|
2007-06-12 14:48:14 -07:00
|
|
|
[NSGraphicsContext restoreGraphicsState];
|
2007-05-02 16:47:53 -07:00
|
|
|
[image release];
|
2007-03-22 10:30:00 -07:00
|
|
|
}
|
2007-05-02 16:47:53 -07:00
|
|
|
else {
|
2007-05-17 19:01:02 -07:00
|
|
|
HIRect drawFrame = inBoxRect;
|
2007-09-15 09:39:11 -07:00
|
|
|
if (inKind == kThemePushButton) {
|
2007-05-08 05:54:48 -07:00
|
|
|
drawFrame.size.height -= NATIVE_PUSH_BUTTON_HEIGHT_DIFF;
|
2007-09-15 09:39:11 -07:00
|
|
|
}
|
|
|
|
else if (inKind == kThemePopupButton) {
|
|
|
|
// popup buttons draw outside their frame by 1 pixel on each side and two on the bottom
|
|
|
|
drawFrame.size.width -= 2;
|
|
|
|
drawFrame.origin.x += 1;
|
|
|
|
drawFrame.size.height -= NATIVE_PUSH_BUTTON_HEIGHT_DIFF;
|
|
|
|
}
|
2007-05-02 16:47:53 -07:00
|
|
|
|
|
|
|
HIThemeDrawButton(&drawFrame, &bdi, cgContext, kHIThemeOrientationNormal, NULL);
|
2007-03-22 10:30:00 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
#if DRAW_IN_FRAME_DEBUG
|
|
|
|
CGContextSetRGBFillColor(cgContext, 0.0, 0.0, 0.5, 0.8);
|
|
|
|
CGContextFillRect(cgContext, inBoxRect);
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2007-04-10 17:25:11 -07:00
|
|
|
|
2007-03-22 10:30:00 -07:00
|
|
|
void
|
|
|
|
nsNativeThemeCocoa::DrawSpinButtons(CGContextRef cgContext, ThemeButtonKind inKind,
|
|
|
|
const HIRect& inBoxRect, PRBool inDisabled,
|
2007-08-27 21:05:12 -07:00
|
|
|
ThemeDrawState inDrawState,
|
|
|
|
ThemeButtonAdornment inAdornment,
|
|
|
|
PRInt32 inState)
|
2007-03-22 10:30:00 -07:00
|
|
|
{
|
|
|
|
HIThemeButtonDrawInfo bdi;
|
|
|
|
bdi.version = 0;
|
|
|
|
bdi.kind = inKind;
|
|
|
|
bdi.state = inDrawState;
|
|
|
|
bdi.value = kThemeButtonOff;
|
|
|
|
bdi.adornment = inAdornment;
|
|
|
|
|
|
|
|
if (inDisabled)
|
|
|
|
bdi.state = kThemeStateUnavailable;
|
|
|
|
|
|
|
|
HIThemeDrawButton(&inBoxRect, &bdi, cgContext, HITHEME_ORIENTATION, NULL);
|
|
|
|
}
|
|
|
|
|
2007-04-10 17:25:11 -07:00
|
|
|
|
2007-03-22 10:30:00 -07:00
|
|
|
void
|
|
|
|
nsNativeThemeCocoa::DrawFrame(CGContextRef cgContext, HIThemeFrameKind inKind,
|
2007-08-27 21:05:12 -07:00
|
|
|
const HIRect& inBoxRect, PRBool inIsDisabled, PRInt32 inState)
|
2007-03-22 10:30:00 -07:00
|
|
|
{
|
|
|
|
HIThemeFrameDrawInfo fdi;
|
|
|
|
fdi.version = 0;
|
|
|
|
fdi.kind = inKind;
|
|
|
|
fdi.state = inIsDisabled ? kThemeStateUnavailable : kThemeStateActive;
|
|
|
|
// We do not draw focus rings for frame widgets because their complex layout has nasty
|
|
|
|
// drawing bugs and it looks terrible.
|
|
|
|
// fdi.isFocused = (inState & NS_EVENT_STATE_FOCUS) != 0;
|
|
|
|
fdi.isFocused = 0;
|
|
|
|
|
|
|
|
// HIThemeDrawFrame takes the rect for the content area of the frame, not
|
|
|
|
// the bounding rect for the frame. Here we reduce the size of the rect we
|
|
|
|
// will pass to make it the size of the content.
|
|
|
|
HIRect drawRect = inBoxRect;
|
|
|
|
if (inKind == kHIThemeFrameTextFieldSquare) {
|
|
|
|
SInt32 frameOutset = 0;
|
|
|
|
::GetThemeMetric(kThemeMetricEditTextFrameOutset, &frameOutset);
|
2007-08-28 00:21:04 -07:00
|
|
|
drawRect.origin.x += frameOutset;
|
|
|
|
drawRect.origin.y += frameOutset;
|
|
|
|
drawRect.size.width -= frameOutset * 2;
|
|
|
|
drawRect.size.height -= frameOutset * 2;
|
|
|
|
}
|
|
|
|
else if (inKind == kHIThemeFrameListBox) {
|
|
|
|
SInt32 frameOutset = 0;
|
|
|
|
::GetThemeMetric(kThemeMetricListBoxFrameOutset, &frameOutset);
|
2007-03-22 10:30:00 -07:00
|
|
|
drawRect.origin.x += frameOutset;
|
|
|
|
drawRect.origin.y += frameOutset;
|
|
|
|
drawRect.size.width -= frameOutset * 2;
|
|
|
|
drawRect.size.height -= frameOutset * 2;
|
|
|
|
}
|
|
|
|
|
|
|
|
#if DRAW_IN_FRAME_DEBUG
|
|
|
|
CGContextSetRGBFillColor(cgContext, 0.0, 0.0, 0.5, 0.8);
|
|
|
|
CGContextFillRect(cgContext, inBoxRect);
|
|
|
|
#endif
|
|
|
|
|
|
|
|
HIThemeDrawFrame(&drawRect, &fdi, cgContext, HITHEME_ORIENTATION);
|
|
|
|
}
|
|
|
|
|
2007-04-10 17:25:11 -07:00
|
|
|
|
2007-03-22 10:30:00 -07:00
|
|
|
void
|
2007-08-27 21:05:12 -07:00
|
|
|
nsNativeThemeCocoa::DrawProgress(CGContextRef cgContext,
|
|
|
|
const HIRect& inBoxRect, PRBool inIsIndeterminate,
|
|
|
|
PRBool inIsHorizontal, PRInt32 inValue)
|
2007-03-22 10:30:00 -07:00
|
|
|
{
|
|
|
|
HIThemeTrackDrawInfo tdi;
|
|
|
|
static SInt32 sPhase = 0;
|
|
|
|
|
|
|
|
tdi.version = 0;
|
|
|
|
tdi.kind = inIsIndeterminate ? kThemeMediumIndeterminateBar: kThemeMediumProgressBar;
|
|
|
|
tdi.bounds = inBoxRect;
|
|
|
|
tdi.min = 0;
|
|
|
|
tdi.max = 100;
|
|
|
|
tdi.value = inValue;
|
|
|
|
tdi.attributes = inIsHorizontal ? kThemeTrackHorizontal : 0;
|
2007-08-27 21:05:12 -07:00
|
|
|
tdi.enableState = kThemeTrackActive;
|
2007-03-22 10:30:00 -07:00
|
|
|
tdi.trackInfo.progress.phase = sPhase++; // animate for the next time we're called
|
|
|
|
|
|
|
|
HIThemeDrawTrack(&tdi, NULL, cgContext, HITHEME_ORIENTATION);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void
|
2007-08-27 21:05:12 -07:00
|
|
|
nsNativeThemeCocoa::DrawTabPanel(CGContextRef cgContext, const HIRect& inBoxRect)
|
2007-03-22 10:30:00 -07:00
|
|
|
{
|
|
|
|
HIThemeTabPaneDrawInfo tpdi;
|
|
|
|
|
|
|
|
tpdi.version = 0;
|
2007-08-27 21:05:12 -07:00
|
|
|
tpdi.state = kThemeStateActive;
|
2007-03-22 10:30:00 -07:00
|
|
|
tpdi.direction = kThemeTabNorth;
|
|
|
|
tpdi.size = kHIThemeTabSizeNormal;
|
|
|
|
|
|
|
|
HIThemeDrawTabPane(&inBoxRect, &tpdi, cgContext, HITHEME_ORIENTATION);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
nsNativeThemeCocoa::DrawScale(CGContextRef cgContext, const HIRect& inBoxRect,
|
|
|
|
PRBool inIsDisabled, PRInt32 inState,
|
2007-04-09 15:39:57 -07:00
|
|
|
PRBool inIsVertical, PRBool inIsReverse,
|
2007-08-27 21:05:12 -07:00
|
|
|
PRInt32 inCurrentValue,
|
|
|
|
PRInt32 inMinValue, PRInt32 inMaxValue)
|
2007-03-22 10:30:00 -07:00
|
|
|
{
|
|
|
|
HIThemeTrackDrawInfo tdi;
|
|
|
|
|
|
|
|
tdi.version = 0;
|
|
|
|
tdi.kind = kThemeMediumSlider;
|
|
|
|
tdi.bounds = inBoxRect;
|
|
|
|
tdi.min = inMinValue;
|
|
|
|
tdi.max = inMaxValue;
|
|
|
|
tdi.value = inCurrentValue;
|
|
|
|
tdi.attributes = kThemeTrackShowThumb;
|
|
|
|
if (!inIsVertical)
|
|
|
|
tdi.attributes |= kThemeTrackHorizontal;
|
2007-04-09 15:39:57 -07:00
|
|
|
if (inIsReverse)
|
|
|
|
tdi.attributes |= kThemeTrackRightToLeft;
|
2007-03-22 10:30:00 -07:00
|
|
|
if (inState & NS_EVENT_STATE_FOCUS)
|
|
|
|
tdi.attributes |= kThemeTrackHasFocus;
|
2007-08-27 21:05:12 -07:00
|
|
|
tdi.enableState = inIsDisabled ? kThemeTrackDisabled : kThemeTrackActive;
|
2007-03-22 10:30:00 -07:00
|
|
|
tdi.trackInfo.slider.thumbDir = kThemeThumbPlain;
|
|
|
|
tdi.trackInfo.slider.pressState = 0;
|
|
|
|
|
|
|
|
HIThemeDrawTrack(&tdi, NULL, cgContext, HITHEME_ORIENTATION);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
nsNativeThemeCocoa::DrawTab(CGContextRef cgContext, const HIRect& inBoxRect,
|
|
|
|
PRBool inIsDisabled, PRBool inIsFrontmost,
|
|
|
|
PRBool inIsHorizontal, PRBool inTabBottom,
|
2007-08-27 21:05:12 -07:00
|
|
|
PRInt32 inState)
|
2007-03-22 10:30:00 -07:00
|
|
|
{
|
|
|
|
HIThemeTabDrawInfo tdi;
|
|
|
|
|
|
|
|
tdi.version = 0;
|
|
|
|
|
|
|
|
if (inIsFrontmost) {
|
|
|
|
if (inIsDisabled)
|
|
|
|
tdi.style = kThemeTabFrontUnavailable;
|
|
|
|
else
|
2007-08-27 21:05:12 -07:00
|
|
|
tdi.style = kThemeTabFront;
|
2007-03-22 10:30:00 -07:00
|
|
|
} else {
|
|
|
|
if (inIsDisabled)
|
|
|
|
tdi.style = kThemeTabNonFrontUnavailable;
|
|
|
|
else if ((inState & NS_EVENT_STATE_ACTIVE) && (inState & NS_EVENT_STATE_HOVER))
|
|
|
|
tdi.style = kThemeTabNonFrontPressed;
|
|
|
|
else
|
2007-08-27 21:05:12 -07:00
|
|
|
tdi.style = kThemeTabNonFront;
|
2007-03-22 10:30:00 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
// don't yet support vertical tabs
|
|
|
|
tdi.direction = inTabBottom ? kThemeTabSouth : kThemeTabNorth;
|
|
|
|
tdi.size = kHIThemeTabSizeNormal;
|
|
|
|
tdi.adornment = kThemeAdornmentNone;
|
|
|
|
|
|
|
|
HIThemeDrawTab(&inBoxRect, &tdi, cgContext, HITHEME_ORIENTATION, NULL);
|
|
|
|
}
|
|
|
|
|
2007-04-10 17:25:11 -07:00
|
|
|
|
|
|
|
static UInt8
|
|
|
|
ConvertToPressState(PRInt32 aButtonState, UInt8 aPressState)
|
|
|
|
{
|
|
|
|
// If the button is pressed, return the press state passed in. Otherwise, return 0.
|
|
|
|
return ((aButtonState & NS_EVENT_STATE_ACTIVE) && (aButtonState & NS_EVENT_STATE_HOVER)) ? aPressState : 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
nsNativeThemeCocoa::GetScrollbarPressStates(nsIFrame *aFrame, PRInt32 aButtonStates[])
|
|
|
|
{
|
|
|
|
static nsIContent::AttrValuesArray attributeValues[] = {
|
|
|
|
&nsWidgetAtoms::scrollbarUpTop,
|
|
|
|
&nsWidgetAtoms::scrollbarDownTop,
|
|
|
|
&nsWidgetAtoms::scrollbarUpBottom,
|
|
|
|
&nsWidgetAtoms::scrollbarDownBottom,
|
|
|
|
nsnull
|
|
|
|
};
|
|
|
|
|
|
|
|
// Get the state of any scrollbar buttons in our child frames
|
|
|
|
for (nsIFrame *childFrame = aFrame->GetFirstChild(nsnull);
|
|
|
|
childFrame;
|
|
|
|
childFrame = childFrame->GetNextSibling()) {
|
|
|
|
|
|
|
|
nsIContent *childContent = childFrame->GetContent();
|
|
|
|
if (!childContent) continue;
|
|
|
|
PRInt32 attrIndex = childContent->FindAttrValueIn(kNameSpaceID_None, nsWidgetAtoms::sbattr,
|
|
|
|
attributeValues, eCaseMatters);
|
|
|
|
if (attrIndex < 0) continue;
|
|
|
|
|
|
|
|
PRInt32 currentState = GetContentState(childFrame, NS_THEME_BUTTON);
|
|
|
|
aButtonStates[attrIndex] = currentState;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-07-03 13:05:15 -07:00
|
|
|
// Both of the following sets of numbers were derived by loading the testcase in
|
|
|
|
// bmo bug 380185 in Safari and observing its behavior for various heights of scrollbar.
|
2007-07-03 11:49:44 -07:00
|
|
|
// These magic numbers are the minimum sizes we can draw a scrollbar and still
|
|
|
|
// have room for everything to display, including the thumb
|
|
|
|
#define MIN_SCROLLBAR_SIZE_WITH_THUMB 61
|
|
|
|
#define MIN_SMALL_SCROLLBAR_SIZE_WITH_THUMB 49
|
|
|
|
// And these are the minimum sizes if we don't draw the thumb
|
|
|
|
#define MIN_SCROLLBAR_SIZE 56
|
|
|
|
#define MIN_SMALL_SCROLLBAR_SIZE 46
|
|
|
|
|
2007-04-10 17:25:11 -07:00
|
|
|
void
|
|
|
|
nsNativeThemeCocoa::GetScrollbarDrawInfo(HIThemeTrackDrawInfo& aTdi, nsIFrame *aFrame,
|
|
|
|
const HIRect& aRect, PRBool aShouldGetButtonStates)
|
|
|
|
{
|
|
|
|
PRInt32 curpos = CheckIntAttr(aFrame, nsWidgetAtoms::curpos);
|
|
|
|
PRInt32 minpos = CheckIntAttr(aFrame, nsWidgetAtoms::minpos);
|
|
|
|
PRInt32 maxpos = CheckIntAttr(aFrame, nsWidgetAtoms::maxpos);
|
|
|
|
|
|
|
|
PRBool isHorizontal = aFrame->GetContent()->AttrValueIs(kNameSpaceID_None, nsWidgetAtoms::orient,
|
|
|
|
nsWidgetAtoms::horizontal, eCaseMatters);
|
|
|
|
PRBool isSmall = aFrame->GetStyleDisplay()->mAppearance == NS_THEME_SCROLLBAR_SMALL;
|
|
|
|
|
|
|
|
aTdi.version = 0;
|
|
|
|
aTdi.kind = isSmall ? kThemeSmallScrollBar : kThemeMediumScrollBar;
|
|
|
|
aTdi.bounds = aRect;
|
|
|
|
aTdi.min = minpos;
|
|
|
|
aTdi.max = maxpos;
|
|
|
|
aTdi.value = curpos;
|
2007-07-03 11:49:44 -07:00
|
|
|
aTdi.attributes = 0;
|
2007-04-10 17:25:11 -07:00
|
|
|
if (isHorizontal)
|
|
|
|
aTdi.attributes |= kThemeTrackHorizontal;
|
|
|
|
|
2007-07-03 13:05:15 -07:00
|
|
|
PRInt32 longSideLength = (PRInt32)(isHorizontal ? (aRect.size.width) : (aRect.size.height));
|
|
|
|
aTdi.trackInfo.scrollbar.viewsize = (SInt32)longSideLength;
|
2007-04-10 17:25:11 -07:00
|
|
|
|
2007-07-03 11:49:44 -07:00
|
|
|
// Only display the thumb if we have room for it to display. Note that this doesn't
|
|
|
|
// affect the actual tracking rects Gecko maintains -- this is a purely cosmetic
|
|
|
|
// change. See bmo bug 380185 for more info.
|
2007-07-03 13:05:15 -07:00
|
|
|
if (longSideLength >= (isSmall ? MIN_SMALL_SCROLLBAR_SIZE_WITH_THUMB : MIN_SCROLLBAR_SIZE_WITH_THUMB)) {
|
2007-07-03 11:49:44 -07:00
|
|
|
aTdi.attributes |= kThemeTrackShowThumb;
|
|
|
|
}
|
|
|
|
// If we don't have enough room to display *any* features, we're done creating
|
|
|
|
// this tdi, so return early. Again, this doesn't affect the tracking rects Gecko
|
|
|
|
// maintains. See bmo bug 380185 for more info.
|
2007-07-03 13:05:15 -07:00
|
|
|
else if (longSideLength < (isSmall ? MIN_SMALL_SCROLLBAR_SIZE : MIN_SCROLLBAR_SIZE)) {
|
2007-07-03 11:49:44 -07:00
|
|
|
aTdi.enableState = kThemeTrackNothingToScroll;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2007-04-10 17:25:11 -07:00
|
|
|
// Only go get these scrollbar button states if we need it. For example, there's no reaon to look up scrollbar button
|
|
|
|
// states when we're only creating a TrackDrawInfo to determine the size of the thumb.
|
|
|
|
if (aShouldGetButtonStates) {
|
|
|
|
PRInt32 buttonStates[] = {0, 0, 0, 0};
|
|
|
|
GetScrollbarPressStates(aFrame, buttonStates);
|
|
|
|
ThemeScrollBarArrowStyle arrowStyle;
|
|
|
|
::GetThemeScrollBarArrowStyle(&arrowStyle);
|
|
|
|
// If all four buttons are visible
|
|
|
|
if (arrowStyle == kThemeScrollBarArrowsBoth) {
|
|
|
|
aTdi.trackInfo.scrollbar.pressState = ConvertToPressState(buttonStates[0], kThemeTopOutsideArrowPressed) |
|
|
|
|
ConvertToPressState(buttonStates[1], kThemeTopInsideArrowPressed) |
|
|
|
|
ConvertToPressState(buttonStates[2], kThemeBottomInsideArrowPressed) |
|
|
|
|
ConvertToPressState(buttonStates[3], kThemeBottomOutsideArrowPressed);
|
|
|
|
} else {
|
|
|
|
// It seems that unless all four buttons are showing, kThemeTopOutsideArrowPressed is the correct constant for
|
|
|
|
// the up scrollbar button.
|
|
|
|
aTdi.trackInfo.scrollbar.pressState = ConvertToPressState(buttonStates[0], kThemeTopOutsideArrowPressed) |
|
|
|
|
ConvertToPressState(buttonStates[2], kThemeTopOutsideArrowPressed) |
|
|
|
|
ConvertToPressState(buttonStates[3], kThemeBottomOutsideArrowPressed);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
nsNativeThemeCocoa::DrawScrollbar(CGContextRef aCGContext, const HIRect& aBoxRect, nsIFrame *aFrame)
|
|
|
|
{
|
|
|
|
HIThemeTrackDrawInfo tdi;
|
|
|
|
GetScrollbarDrawInfo(tdi, aFrame, aBoxRect, PR_TRUE); //True means we want the press states
|
|
|
|
::HIThemeDrawTrack(&tdi, NULL, aCGContext, HITHEME_ORIENTATION);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
nsIFrame*
|
|
|
|
nsNativeThemeCocoa::GetParentScrollbarFrame(nsIFrame *aFrame)
|
|
|
|
{
|
|
|
|
// Walk our parents to find a scrollbar frame
|
|
|
|
nsIFrame *scrollbarFrame = aFrame;
|
|
|
|
do {
|
|
|
|
if (scrollbarFrame->GetType() == nsWidgetAtoms::scrollbarFrame) break;
|
|
|
|
} while ((scrollbarFrame = scrollbarFrame->GetParent()));
|
|
|
|
|
|
|
|
// We return null if we can't find a parent scrollbar frame
|
|
|
|
return scrollbarFrame;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-03-22 10:30:00 -07:00
|
|
|
NS_IMETHODIMP
|
|
|
|
nsNativeThemeCocoa::DrawWidgetBackground(nsIRenderingContext* aContext, nsIFrame* aFrame,
|
|
|
|
PRUint8 aWidgetType, const nsRect& aRect,
|
|
|
|
const nsRect& aClipRect)
|
|
|
|
{
|
|
|
|
// setup to draw into the correct port
|
|
|
|
nsCOMPtr<nsIDeviceContext> dctx;
|
|
|
|
aContext->GetDeviceContext(*getter_AddRefs(dctx));
|
|
|
|
PRInt32 p2a = dctx->AppUnitsPerDevPixel();
|
|
|
|
|
|
|
|
nsRefPtr<gfxContext> thebesCtx = (gfxContext*)
|
|
|
|
aContext->GetNativeGraphicData(nsIRenderingContext::NATIVE_THEBES_CONTEXT);
|
|
|
|
if (!thebesCtx)
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
|
|
|
|
thebesCtx->UpdateSurfaceClip();
|
|
|
|
|
|
|
|
double offsetX = 0.0, offsetY = 0.0;
|
|
|
|
nsRefPtr<gfxASurface> thebesSurface = thebesCtx->CurrentSurface(&offsetX, &offsetY);
|
2007-07-18 07:40:19 -07:00
|
|
|
if (thebesSurface->CairoStatus() != 0) {
|
|
|
|
NS_WARNING("Got Cairo surface with nonzero error status");
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
}
|
|
|
|
|
2007-04-03 18:09:15 -07:00
|
|
|
if (thebesSurface->GetType() != gfxASurface::SurfaceTypeQuartz) {
|
2007-07-18 07:40:19 -07:00
|
|
|
NS_WARNING("Expected surface of type Quartz, got somthing else");
|
2007-03-22 10:30:00 -07:00
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
}
|
|
|
|
|
|
|
|
gfxMatrix mat = thebesCtx->CurrentMatrix();
|
|
|
|
gfxQuartzSurface* quartzSurf = (gfxQuartzSurface*) (thebesSurface.get());
|
|
|
|
CGContextRef cgContext = quartzSurf->GetCGContext();
|
|
|
|
|
|
|
|
//fprintf (stderr, "surface: %p cgContext: %p\n", quartzSurf, cgContext);
|
|
|
|
|
2007-07-18 07:40:19 -07:00
|
|
|
if (cgContext == nsnull) {
|
|
|
|
NS_WARNING("Invalid CGContext!");
|
|
|
|
return NS_ERROR_FAILURE;
|
2007-03-22 10:30:00 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
// Eventually we can just do a GetCTM and restore it with SetCTM,
|
|
|
|
// but for now do a full save/restore
|
|
|
|
CGAffineTransform mm0 = CGContextGetCTM(cgContext);
|
|
|
|
|
|
|
|
CGContextSaveGState(cgContext);
|
|
|
|
//CGContextSetCTM(cgContext, CGAffineTransformIdentity);
|
|
|
|
|
|
|
|
// I -think- that this context will always have an identity
|
|
|
|
// transform (since we don't maintain a transform on it in
|
|
|
|
// cairo-land, and instead push/pop as needed)
|
|
|
|
if (mat.HasNonTranslationOrFlip()) {
|
|
|
|
// If we have a scale, I think we've already lost; so don't round
|
|
|
|
// anything here
|
|
|
|
CGContextConcatCTM(cgContext,
|
|
|
|
CGAffineTransformMake(mat.xx, mat.xy,
|
|
|
|
mat.yx, mat.yy,
|
|
|
|
mat.x0, mat.y0));
|
|
|
|
} else {
|
|
|
|
// Otherwise, we round the x0/y0, because otherwise things get rendered badly
|
|
|
|
// XXX how should we be rounding the x0/y0?
|
|
|
|
CGContextConcatCTM(cgContext,
|
|
|
|
CGAffineTransformMake(mat.xx, mat.xy,
|
|
|
|
mat.yx, mat.yy,
|
|
|
|
floor(mat.x0 + 0.5),
|
|
|
|
floor(mat.y0 + 0.5)));
|
|
|
|
}
|
|
|
|
|
|
|
|
#if 0
|
|
|
|
if (1 /*aWidgetType == NS_THEME_TEXTFIELD*/) {
|
|
|
|
fprintf(stderr, "Native theme drawing widget %d [%p] dis:%d in rect [%d %d %d %d]\n",
|
|
|
|
aWidgetType, aFrame, IsDisabled(aFrame), aRect.x, aRect.y, aRect.width, aRect.height);
|
|
|
|
fprintf(stderr, "Native theme xform[0]: [%f %f %f %f %f %f]\n",
|
|
|
|
mm0.a, mm0.b, mm0.c, mm0.d, mm0.tx, mm0.ty);
|
|
|
|
CGAffineTransform mm = CGContextGetCTM(cgContext);
|
|
|
|
fprintf(stderr, "Native theme xform[1]: [%f %f %f %f %f %f]\n",
|
|
|
|
mm.a, mm.b, mm.c, mm.d, mm.tx, mm.ty);
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
CGRect macRect = CGRectMake(NSAppUnitsToIntPixels(aRect.x, p2a),
|
|
|
|
NSAppUnitsToIntPixels(aRect.y, p2a),
|
|
|
|
NSAppUnitsToIntPixels(aRect.width, p2a),
|
|
|
|
NSAppUnitsToIntPixels(aRect.height, p2a));
|
2007-08-07 12:36:40 -07:00
|
|
|
macRect.origin.x += offsetX;
|
|
|
|
macRect.origin.y += offsetY;
|
|
|
|
|
|
|
|
// 382049 - need to explicitly set the composite operation to sourceOver
|
|
|
|
CGContextSetCompositeOperation(cgContext, kPrivateCGCompositeSourceOver);
|
2007-03-22 10:30:00 -07:00
|
|
|
|
|
|
|
#if 0
|
|
|
|
fprintf(stderr, " --> macRect %f %f %f %f\n",
|
|
|
|
macRect.origin.x, macRect.origin.y, macRect.size.width, macRect.size.height);
|
|
|
|
CGRect bounds = CGContextGetClipBoundingBox(cgContext);
|
|
|
|
fprintf(stderr, " --> clip bounds: %f %f %f %f\n",
|
|
|
|
bounds.origin.x, bounds.origin.y, bounds.size.width, bounds.size.height);
|
|
|
|
|
|
|
|
//CGContextSetRGBFillColor(cgContext, 0.0, 0.0, 1.0, 0.1);
|
|
|
|
//CGContextFillRect(cgContext, bounds);
|
|
|
|
#endif
|
|
|
|
|
|
|
|
PRInt32 eventState = GetContentState(aFrame, aWidgetType);
|
|
|
|
|
|
|
|
switch (aWidgetType) {
|
|
|
|
case NS_THEME_DIALOG: {
|
|
|
|
// XXXvlad -- I don't think we can just pass macRect here,
|
|
|
|
// due to pattern phase, but it seems like it works correctly
|
|
|
|
HIThemeBackgroundDrawInfo bdi = {
|
|
|
|
version: 0,
|
|
|
|
state: kThemeStateActive,
|
|
|
|
kind: kThemeBackgroundPlacard
|
|
|
|
};
|
|
|
|
|
|
|
|
HIThemeApplyBackground(&macRect, &bdi, cgContext, HITHEME_ORIENTATION);
|
|
|
|
CGContextFillRect(cgContext, macRect);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case NS_THEME_MENUPOPUP: {
|
|
|
|
HIThemeMenuDrawInfo mdi = {
|
|
|
|
version: 0,
|
|
|
|
menuType: IsDisabled(aFrame) ? kThemeMenuTypeInactive : kThemeMenuTypePopUp
|
|
|
|
};
|
|
|
|
|
|
|
|
HIThemeDrawMenuBackground(&macRect, &mdi, cgContext, HITHEME_ORIENTATION);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case NS_THEME_MENUITEM: {
|
|
|
|
// maybe use kThemeMenuItemHierBackground or PopUpBackground instead of just Plain?
|
|
|
|
HIThemeMenuItemDrawInfo drawInfo = {
|
|
|
|
version: 0,
|
|
|
|
itemType: kThemeMenuItemPlain,
|
|
|
|
state: (IsDisabled(aFrame) ? kThemeMenuDisabled :
|
|
|
|
CheckBooleanAttr(aFrame, nsWidgetAtoms::mozmenuactive) ? kThemeMenuSelected :
|
|
|
|
kThemeMenuActive)
|
|
|
|
};
|
|
|
|
|
|
|
|
// XXX pass in the menu rect instead of always using the item rect
|
|
|
|
HIRect ignored;
|
|
|
|
HIThemeDrawMenuItem(&macRect, &macRect, &drawInfo, cgContext, HITHEME_ORIENTATION, &ignored);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case NS_THEME_TOOLTIP:
|
|
|
|
CGContextSetRGBFillColor(cgContext, 1.0, 1.0, 0.78, 1.0);
|
|
|
|
CGContextFillRect(cgContext, macRect);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case NS_THEME_CHECKBOX:
|
2007-08-27 21:05:12 -07:00
|
|
|
DrawCheckboxRadio(cgContext, kThemeCheckBox, macRect, IsChecked(aFrame), IsDisabled(aFrame), eventState);
|
2007-03-22 10:30:00 -07:00
|
|
|
break;
|
|
|
|
|
|
|
|
case NS_THEME_CHECKBOX_SMALL:
|
2007-08-27 21:05:12 -07:00
|
|
|
DrawCheckboxRadio(cgContext, kThemeSmallCheckBox, macRect, IsChecked(aFrame), IsDisabled(aFrame), eventState);
|
2007-03-22 10:30:00 -07:00
|
|
|
break;
|
|
|
|
|
|
|
|
case NS_THEME_RADIO:
|
2007-08-27 21:05:12 -07:00
|
|
|
DrawCheckboxRadio(cgContext, kThemeRadioButton, macRect, IsSelected(aFrame), IsDisabled(aFrame), eventState);
|
2007-03-22 10:30:00 -07:00
|
|
|
break;
|
|
|
|
|
|
|
|
case NS_THEME_RADIO_SMALL:
|
|
|
|
DrawCheckboxRadio(cgContext, kThemeSmallRadioButton, macRect,
|
2007-08-27 21:05:12 -07:00
|
|
|
IsSelected(aFrame), IsDisabled(aFrame), eventState);
|
2007-03-22 10:30:00 -07:00
|
|
|
break;
|
|
|
|
|
|
|
|
case NS_THEME_BUTTON:
|
2007-05-02 16:47:53 -07:00
|
|
|
DrawButton(cgContext, kThemePushButton, macRect,
|
2007-03-22 10:30:00 -07:00
|
|
|
IsDefaultButton(aFrame), IsDisabled(aFrame),
|
2007-08-27 21:05:12 -07:00
|
|
|
kThemeButtonOn, kThemeAdornmentNone, eventState);
|
2007-03-22 10:30:00 -07:00
|
|
|
break;
|
|
|
|
|
|
|
|
case NS_THEME_BUTTON_BEVEL:
|
|
|
|
DrawButton(cgContext, kThemeMediumBevelButton, macRect,
|
|
|
|
IsDefaultButton(aFrame), IsDisabled(aFrame),
|
2007-08-27 21:05:12 -07:00
|
|
|
kThemeButtonOff, kThemeAdornmentNone, eventState);
|
2007-03-22 10:30:00 -07:00
|
|
|
break;
|
|
|
|
|
|
|
|
case NS_THEME_SPINNER: {
|
|
|
|
ThemeDrawState state = kThemeStateActive;
|
|
|
|
nsIContent* content = aFrame->GetContent();
|
|
|
|
if (content->AttrValueIs(kNameSpaceID_None, nsWidgetAtoms::state,
|
|
|
|
NS_LITERAL_STRING("up"), eCaseMatters)) {
|
|
|
|
state = kThemeStatePressedUp;
|
|
|
|
}
|
|
|
|
else if (content->AttrValueIs(kNameSpaceID_None, nsWidgetAtoms::state,
|
|
|
|
NS_LITERAL_STRING("down"), eCaseMatters)) {
|
|
|
|
state = kThemeStatePressedDown;
|
|
|
|
}
|
|
|
|
|
|
|
|
DrawSpinButtons(cgContext, kThemeIncDecButton, macRect, IsDisabled(aFrame),
|
2007-08-27 21:05:12 -07:00
|
|
|
state, kThemeAdornmentNone, eventState);
|
2007-03-22 10:30:00 -07:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case NS_THEME_TOOLBAR_BUTTON:
|
|
|
|
DrawButton(cgContext, kThemePushButton, macRect,
|
|
|
|
IsDefaultButton(aFrame), IsDisabled(aFrame),
|
2007-08-27 21:05:12 -07:00
|
|
|
kThemeButtonOn, kThemeAdornmentNone, eventState);
|
2007-03-22 10:30:00 -07:00
|
|
|
break;
|
|
|
|
|
|
|
|
case NS_THEME_TOOLBAR_SEPARATOR: {
|
|
|
|
HIThemeSeparatorDrawInfo sdi = { 0, kThemeStateActive };
|
|
|
|
HIThemeDrawSeparator(&macRect, &sdi, cgContext, HITHEME_ORIENTATION);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case NS_THEME_TOOLBAR:
|
|
|
|
case NS_THEME_TOOLBOX:
|
|
|
|
case NS_THEME_STATUSBAR: {
|
|
|
|
HIThemeHeaderDrawInfo hdi = { 0, kThemeStateActive, kHIThemeHeaderKindWindow };
|
|
|
|
HIThemeDrawHeader(&macRect, &hdi, cgContext, HITHEME_ORIENTATION);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case NS_THEME_DROPDOWN:
|
|
|
|
DrawButton(cgContext, kThemePopupButton, macRect,
|
|
|
|
IsDefaultButton(aFrame), IsDisabled(aFrame),
|
2007-08-27 21:05:12 -07:00
|
|
|
kThemeButtonOn, kThemeAdornmentNone, eventState);
|
2007-03-22 10:30:00 -07:00
|
|
|
break;
|
|
|
|
|
|
|
|
case NS_THEME_DROPDOWN_BUTTON:
|
2007-08-27 21:05:12 -07:00
|
|
|
DrawButton (cgContext, kThemeArrowButton, macRect, PR_FALSE,
|
|
|
|
IsDisabled(aFrame), kThemeButtonOn,
|
|
|
|
kThemeAdornmentArrowDownArrow, eventState);
|
2007-03-22 10:30:00 -07:00
|
|
|
break;
|
|
|
|
|
|
|
|
case NS_THEME_TEXTFIELD:
|
|
|
|
// HIThemeSetFill is not available on 10.3
|
|
|
|
CGContextSetRGBFillColor(cgContext, 1.0, 1.0, 1.0, 1.0);
|
|
|
|
CGContextFillRect(cgContext, macRect);
|
|
|
|
DrawFrame(cgContext, kHIThemeFrameTextFieldSquare,
|
|
|
|
macRect, (IsDisabled(aFrame) || IsReadOnly(aFrame)), eventState);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case NS_THEME_PROGRESSBAR:
|
|
|
|
DrawProgress(cgContext, macRect, IsIndeterminateProgress(aFrame),
|
2007-08-27 21:05:12 -07:00
|
|
|
PR_TRUE, GetProgressValue(aFrame));
|
2007-03-22 10:30:00 -07:00
|
|
|
break;
|
|
|
|
|
|
|
|
case NS_THEME_PROGRESSBAR_VERTICAL:
|
|
|
|
DrawProgress(cgContext, macRect, IsIndeterminateProgress(aFrame),
|
2007-08-27 21:05:12 -07:00
|
|
|
PR_FALSE, GetProgressValue(aFrame));
|
2007-03-22 10:30:00 -07:00
|
|
|
break;
|
|
|
|
|
|
|
|
case NS_THEME_PROGRESSBAR_CHUNK:
|
|
|
|
case NS_THEME_PROGRESSBAR_CHUNK_VERTICAL:
|
|
|
|
// do nothing, covered by the progress bar cases above
|
|
|
|
break;
|
|
|
|
|
|
|
|
case NS_THEME_TREEVIEW_TWISTY:
|
|
|
|
DrawButton(cgContext, kThemeDisclosureButton, macRect, PR_FALSE, IsDisabled(aFrame),
|
2007-08-27 21:05:12 -07:00
|
|
|
kThemeDisclosureRight, kThemeAdornmentNone, eventState);
|
2007-03-22 10:30:00 -07:00
|
|
|
break;
|
|
|
|
|
|
|
|
case NS_THEME_TREEVIEW_TWISTY_OPEN:
|
|
|
|
DrawButton(cgContext, kThemeDisclosureButton, macRect, PR_FALSE, IsDisabled(aFrame),
|
2007-08-27 21:05:12 -07:00
|
|
|
kThemeDisclosureDown, kThemeAdornmentNone, eventState);
|
2007-03-22 10:30:00 -07:00
|
|
|
break;
|
|
|
|
|
|
|
|
case NS_THEME_TREEVIEW_HEADER_CELL: {
|
|
|
|
TreeSortDirection sortDirection = GetTreeSortDirection(aFrame);
|
|
|
|
DrawButton(cgContext, kThemeListHeaderButton, macRect, PR_FALSE, IsDisabled(aFrame),
|
|
|
|
sortDirection == eTreeSortDirection_Natural ? kThemeButtonOff : kThemeButtonOn,
|
|
|
|
sortDirection == eTreeSortDirection_Descending ?
|
2007-08-27 21:05:12 -07:00
|
|
|
kThemeAdornmentHeaderButtonSortUp : kThemeAdornmentNone, eventState);
|
2007-03-22 10:30:00 -07:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case NS_THEME_TREEVIEW_TREEITEM:
|
|
|
|
case NS_THEME_TREEVIEW:
|
|
|
|
// HIThemeSetFill is not available on 10.3
|
|
|
|
// HIThemeSetFill(kThemeBrushWhite, NULL, cgContext, HITHEME_ORIENTATION);
|
|
|
|
CGContextSetRGBFillColor(cgContext, 1.0, 1.0, 1.0, 1.0);
|
|
|
|
CGContextFillRect(cgContext, macRect);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case NS_THEME_TREEVIEW_HEADER:
|
|
|
|
// do nothing, taken care of by individual header cells
|
|
|
|
case NS_THEME_TREEVIEW_HEADER_SORTARROW:
|
|
|
|
// do nothing, taken care of by treeview header
|
|
|
|
case NS_THEME_TREEVIEW_LINE:
|
|
|
|
// do nothing, these lines don't exist on macos
|
|
|
|
break;
|
|
|
|
|
|
|
|
case NS_THEME_SCALE_HORIZONTAL:
|
|
|
|
case NS_THEME_SCALE_VERTICAL: {
|
|
|
|
PRInt32 curpos = CheckIntAttr(aFrame, nsWidgetAtoms::curpos);
|
|
|
|
PRInt32 minpos = CheckIntAttr(aFrame, nsWidgetAtoms::minpos);
|
|
|
|
PRInt32 maxpos = CheckIntAttr(aFrame, nsWidgetAtoms::maxpos);
|
|
|
|
if (!maxpos)
|
|
|
|
maxpos = 100;
|
|
|
|
|
2007-04-09 15:39:57 -07:00
|
|
|
PRBool reverse = aFrame->GetContent()->
|
|
|
|
AttrValueIs(kNameSpaceID_None, nsWidgetAtoms::dir,
|
|
|
|
NS_LITERAL_STRING("reverse"), eCaseMatters);
|
2007-03-22 10:30:00 -07:00
|
|
|
DrawScale(cgContext, macRect, IsDisabled(aFrame), eventState,
|
2007-04-09 15:39:57 -07:00
|
|
|
(aWidgetType == NS_THEME_SCALE_VERTICAL), reverse,
|
2007-08-27 21:05:12 -07:00
|
|
|
curpos, minpos, maxpos);
|
2007-03-22 10:30:00 -07:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case NS_THEME_SCALE_THUMB_HORIZONTAL:
|
|
|
|
case NS_THEME_SCALE_THUMB_VERTICAL:
|
|
|
|
// do nothing, drawn by scale
|
|
|
|
break;
|
|
|
|
|
2007-04-10 17:25:11 -07:00
|
|
|
case NS_THEME_SCROLLBAR_SMALL:
|
|
|
|
case NS_THEME_SCROLLBAR: {
|
|
|
|
DrawScrollbar(cgContext, macRect, aFrame);
|
|
|
|
}
|
|
|
|
break;
|
2007-03-22 10:30:00 -07:00
|
|
|
case NS_THEME_SCROLLBAR_THUMB_VERTICAL:
|
|
|
|
case NS_THEME_SCROLLBAR_THUMB_HORIZONTAL:
|
2007-04-10 17:25:11 -07:00
|
|
|
#if SCROLLBARS_VISUAL_DEBUG
|
|
|
|
CGContextSetRGBFillColor(cgContext, 1.0, 1.0, 0, 0.6);
|
|
|
|
CGContextFillRect(cgContext, macRect);
|
|
|
|
break;
|
|
|
|
#endif
|
2007-03-22 10:30:00 -07:00
|
|
|
case NS_THEME_SCROLLBAR_BUTTON_UP:
|
2007-04-10 17:25:11 -07:00
|
|
|
case NS_THEME_SCROLLBAR_BUTTON_LEFT:
|
|
|
|
#if SCROLLBARS_VISUAL_DEBUG
|
|
|
|
CGContextSetRGBFillColor(cgContext, 1.0, 0, 0, 0.6);
|
|
|
|
CGContextFillRect(cgContext, macRect);
|
|
|
|
break;
|
|
|
|
#endif
|
2007-03-22 10:30:00 -07:00
|
|
|
case NS_THEME_SCROLLBAR_BUTTON_DOWN:
|
2007-04-10 17:25:11 -07:00
|
|
|
case NS_THEME_SCROLLBAR_BUTTON_RIGHT:
|
|
|
|
#if SCROLLBARS_VISUAL_DEBUG
|
|
|
|
CGContextSetRGBFillColor(cgContext, 0, 1.0, 0, 0.6);
|
|
|
|
CGContextFillRect(cgContext, macRect);
|
|
|
|
break;
|
|
|
|
#endif
|
2007-03-22 10:30:00 -07:00
|
|
|
case NS_THEME_SCROLLBAR_TRACK_HORIZONTAL:
|
|
|
|
case NS_THEME_SCROLLBAR_TRACK_VERTICAL:
|
2007-04-10 17:25:11 -07:00
|
|
|
// do nothing, drawn by scrollbar
|
2007-03-22 10:30:00 -07:00
|
|
|
break;
|
2007-05-06 19:06:58 -07:00
|
|
|
|
|
|
|
case NS_THEME_TEXTFIELD_MULTILINE: {
|
|
|
|
// we have to draw this by hand because there is no HITheme value for it
|
|
|
|
CGContextSetRGBFillColor(cgContext, 1.0, 1.0, 1.0, 1.0);
|
|
|
|
|
|
|
|
CGContextFillRect(cgContext, macRect);
|
|
|
|
|
|
|
|
CGContextSetLineWidth(cgContext, 1.0);
|
|
|
|
CGContextSetShouldAntialias(cgContext, false);
|
|
|
|
|
|
|
|
// stroke everything but the top line of the text area
|
|
|
|
CGContextSetRGBStrokeColor(cgContext, 0.6, 0.6, 0.6, 1.0);
|
|
|
|
CGContextBeginPath(cgContext);
|
|
|
|
CGContextMoveToPoint(cgContext, macRect.origin.x, macRect.origin.y + 1);
|
|
|
|
CGContextAddLineToPoint(cgContext, macRect.origin.x, macRect.origin.y + macRect.size.height);
|
|
|
|
CGContextAddLineToPoint(cgContext, macRect.origin.x + macRect.size.width - 1, macRect.origin.y + macRect.size.height);
|
|
|
|
CGContextAddLineToPoint(cgContext, macRect.origin.x + macRect.size.width - 1, macRect.origin.y + 1);
|
|
|
|
CGContextStrokePath(cgContext);
|
|
|
|
|
|
|
|
// stroke the line across the top of the text area
|
|
|
|
CGContextSetRGBStrokeColor(cgContext, 0.4510, 0.4510, 0.4510, 1.0);
|
|
|
|
CGContextBeginPath(cgContext);
|
|
|
|
CGContextMoveToPoint(cgContext, macRect.origin.x, macRect.origin.y + 1);
|
|
|
|
CGContextAddLineToPoint(cgContext, macRect.origin.x + macRect.size.width - 1, macRect.origin.y + 1);
|
|
|
|
CGContextStrokePath(cgContext);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
2007-03-22 10:30:00 -07:00
|
|
|
case NS_THEME_LISTBOX:
|
|
|
|
// HIThemeSetFill is not available on 10.3
|
|
|
|
CGContextSetRGBFillColor(cgContext, 1.0, 1.0, 1.0, 1.0);
|
|
|
|
CGContextFillRect(cgContext, macRect);
|
2007-08-27 21:05:12 -07:00
|
|
|
DrawFrame(cgContext, kHIThemeFrameListBox,
|
|
|
|
macRect, (IsDisabled(aFrame) || IsReadOnly(aFrame)), eventState);
|
2007-03-22 10:30:00 -07:00
|
|
|
break;
|
|
|
|
|
|
|
|
case NS_THEME_TAB: {
|
|
|
|
DrawTab(cgContext, macRect,
|
|
|
|
IsDisabled(aFrame), IsSelectedTab(aFrame),
|
|
|
|
PR_TRUE, IsBottomTab(aFrame),
|
2007-08-27 21:05:12 -07:00
|
|
|
eventState);
|
2007-03-22 10:30:00 -07:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case NS_THEME_TAB_PANELS:
|
2007-08-27 21:05:12 -07:00
|
|
|
DrawTabPanel(cgContext, macRect);
|
2007-03-22 10:30:00 -07:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
CGContextRestoreGState(cgContext);
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2007-05-28 22:31:04 -07:00
|
|
|
|
2007-05-22 12:35:18 -07:00
|
|
|
static const int kAquaDropdownLeftBorder = 5;
|
2007-05-28 22:31:04 -07:00
|
|
|
static const int kAquaDropdownRightBorder = 22;
|
2007-03-22 10:30:00 -07:00
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
nsNativeThemeCocoa::GetWidgetBorder(nsIDeviceContext* aContext,
|
|
|
|
nsIFrame* aFrame,
|
|
|
|
PRUint8 aWidgetType,
|
|
|
|
nsMargin* aResult)
|
|
|
|
{
|
|
|
|
aResult->SizeTo(0, 0, 0, 0);
|
|
|
|
|
|
|
|
switch (aWidgetType) {
|
|
|
|
case NS_THEME_BUTTON:
|
|
|
|
// Top has a single pixel line, bottom has a single pixel line plus a single
|
2007-06-17 17:29:34 -07:00
|
|
|
// pixel shadow. We say 2 for the sides so that text doesn't hit the border.
|
|
|
|
aResult->SizeTo(2, 1, 2, 3);
|
2007-03-22 10:30:00 -07:00
|
|
|
break;
|
|
|
|
|
|
|
|
case NS_THEME_DROPDOWN:
|
|
|
|
case NS_THEME_DROPDOWN_BUTTON:
|
2007-09-15 09:39:11 -07:00
|
|
|
aResult->SizeTo(kAquaDropdownLeftBorder, 2, kAquaDropdownRightBorder, 2);
|
2007-03-22 10:30:00 -07:00
|
|
|
break;
|
2007-09-03 08:25:15 -07:00
|
|
|
|
|
|
|
case NS_THEME_TEXTFIELD:
|
|
|
|
{
|
2007-03-22 10:30:00 -07:00
|
|
|
SInt32 frameOutset = 0;
|
|
|
|
::GetThemeMetric(kThemeMetricEditTextFrameOutset, &frameOutset);
|
2007-09-03 08:25:15 -07:00
|
|
|
|
|
|
|
SInt32 textPadding = 0;
|
|
|
|
::GetThemeMetric(kThemeMetricEditTextWhitespace, &textPadding);
|
|
|
|
|
|
|
|
frameOutset += textPadding;
|
|
|
|
|
2007-03-22 10:30:00 -07:00
|
|
|
aResult->SizeTo(frameOutset, frameOutset, frameOutset, frameOutset);
|
|
|
|
break;
|
2007-09-03 08:25:15 -07:00
|
|
|
}
|
2007-03-22 10:30:00 -07:00
|
|
|
|
2007-05-06 19:06:58 -07:00
|
|
|
case NS_THEME_TEXTFIELD_MULTILINE:
|
|
|
|
aResult->SizeTo(1, 1, 1, 1);
|
|
|
|
break;
|
2007-09-03 08:25:15 -07:00
|
|
|
|
|
|
|
case NS_THEME_LISTBOX:
|
|
|
|
{
|
2007-03-22 10:30:00 -07:00
|
|
|
SInt32 frameOutset = 0;
|
|
|
|
::GetThemeMetric(kThemeMetricListBoxFrameOutset, &frameOutset);
|
|
|
|
aResult->SizeTo(frameOutset, frameOutset, frameOutset, frameOutset);
|
|
|
|
break;
|
2007-09-03 08:25:15 -07:00
|
|
|
}
|
2007-05-06 19:06:58 -07:00
|
|
|
|
2007-04-10 17:25:11 -07:00
|
|
|
case NS_THEME_SCROLLBAR_TRACK_HORIZONTAL:
|
|
|
|
case NS_THEME_SCROLLBAR_TRACK_VERTICAL:
|
|
|
|
{
|
|
|
|
// There's only an endcap to worry about when both arrows are on the bottom
|
|
|
|
ThemeScrollBarArrowStyle arrowStyle;
|
|
|
|
::GetThemeScrollBarArrowStyle(&arrowStyle);
|
|
|
|
if (arrowStyle == kThemeScrollBarArrowsLowerRight) {
|
|
|
|
PRBool isHorizontal = (aWidgetType == NS_THEME_SCROLLBAR_TRACK_HORIZONTAL);
|
|
|
|
|
|
|
|
nsIFrame *scrollbarFrame = GetParentScrollbarFrame(aFrame);
|
|
|
|
if (!scrollbarFrame) return NS_ERROR_FAILURE;
|
|
|
|
PRBool isSmall = (scrollbarFrame->GetStyleDisplay()->mAppearance == NS_THEME_SCROLLBAR_SMALL);
|
|
|
|
|
|
|
|
// There isn't a metric for this, so just hardcode a best guess at the value.
|
|
|
|
// This value is even less exact due to the fact that the endcap is partially concave.
|
|
|
|
PRInt32 endcapSize = isSmall ? 5 : 6;
|
|
|
|
|
|
|
|
if (isHorizontal)
|
|
|
|
aResult->SizeTo(endcapSize, 0, 0, 0);
|
|
|
|
else
|
|
|
|
aResult->SizeTo(0, endcapSize, 0, 0);
|
|
|
|
}
|
|
|
|
break;
|
2007-09-03 08:25:15 -07:00
|
|
|
}
|
2007-03-22 10:30:00 -07:00
|
|
|
}
|
2007-09-03 08:25:15 -07:00
|
|
|
|
2007-03-22 10:30:00 -07:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2007-04-10 17:25:11 -07:00
|
|
|
|
2007-09-03 08:25:15 -07:00
|
|
|
// Return PR_FALSE here to indicate that CSS padding values should be used. There is
|
|
|
|
// no reason to make a distinction between padding and border values, just specify
|
|
|
|
// whatever values you want in GetWidgetBorder and only use this to return PR_TRUE
|
|
|
|
// if you want to override CSS padding values.
|
2007-03-22 10:30:00 -07:00
|
|
|
PRBool
|
|
|
|
nsNativeThemeCocoa::GetWidgetPadding(nsIDeviceContext* aContext,
|
|
|
|
nsIFrame* aFrame,
|
|
|
|
PRUint8 aWidgetType,
|
|
|
|
nsMargin* aResult)
|
|
|
|
{
|
|
|
|
return PR_FALSE;
|
|
|
|
}
|
|
|
|
|
2007-04-10 17:25:11 -07:00
|
|
|
|
2007-03-22 10:30:00 -07:00
|
|
|
PRBool
|
|
|
|
nsNativeThemeCocoa::GetWidgetOverflow(nsIDeviceContext* aContext, nsIFrame* aFrame,
|
|
|
|
PRUint8 aWidgetType, nsRect* aResult)
|
|
|
|
{
|
|
|
|
switch (aWidgetType) {
|
|
|
|
case NS_THEME_BUTTON:
|
|
|
|
case NS_THEME_TEXTFIELD:
|
2007-05-06 19:06:58 -07:00
|
|
|
case NS_THEME_TEXTFIELD_MULTILINE:
|
2007-03-22 10:30:00 -07:00
|
|
|
case NS_THEME_LISTBOX:
|
|
|
|
case NS_THEME_DROPDOWN:
|
|
|
|
case NS_THEME_DROPDOWN_BUTTON:
|
|
|
|
case NS_THEME_CHECKBOX:
|
|
|
|
case NS_THEME_CHECKBOX_SMALL:
|
|
|
|
case NS_THEME_RADIO:
|
|
|
|
case NS_THEME_RADIO_SMALL:
|
|
|
|
{
|
|
|
|
// We assume that the above widgets can draw a focus ring that will be less than
|
|
|
|
// or equal to 4 pixels thick.
|
|
|
|
nsIntMargin extraSize = nsIntMargin(4, 4, 4, 4);
|
|
|
|
PRInt32 p2a = aContext->AppUnitsPerDevPixel();
|
|
|
|
nsMargin m(NSIntPixelsToAppUnits(extraSize.left, p2a),
|
|
|
|
NSIntPixelsToAppUnits(extraSize.top, p2a),
|
|
|
|
NSIntPixelsToAppUnits(extraSize.right, p2a),
|
|
|
|
NSIntPixelsToAppUnits(extraSize.bottom, p2a));
|
|
|
|
nsRect r(nsPoint(0, 0), aFrame->GetSize());
|
|
|
|
r.Inflate(m);
|
|
|
|
*aResult = r;
|
|
|
|
return PR_TRUE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return PR_FALSE;
|
|
|
|
}
|
|
|
|
|
2007-04-10 17:25:11 -07:00
|
|
|
|
2007-03-22 10:30:00 -07:00
|
|
|
NS_IMETHODIMP
|
|
|
|
nsNativeThemeCocoa::GetMinimumWidgetSize(nsIRenderingContext* aContext,
|
|
|
|
nsIFrame* aFrame,
|
|
|
|
PRUint8 aWidgetType,
|
|
|
|
nsSize* aResult,
|
|
|
|
PRBool* aIsOverridable)
|
|
|
|
{
|
|
|
|
aResult->SizeTo(0,0);
|
|
|
|
*aIsOverridable = PR_TRUE;
|
|
|
|
|
|
|
|
switch (aWidgetType) {
|
|
|
|
case NS_THEME_BUTTON:
|
|
|
|
{
|
2007-05-08 05:54:48 -07:00
|
|
|
aResult->SizeTo(MIN_SCALED_PUSH_BUTTON_WIDTH, MIN_SCALED_PUSH_BUTTON_HEIGHT);
|
2007-03-22 10:30:00 -07:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
case NS_THEME_SPINNER:
|
|
|
|
{
|
2007-09-18 02:17:51 -07:00
|
|
|
SInt32 buttonHeight = 0, buttonWidth = 0;
|
|
|
|
::GetThemeMetric(kThemeMetricLittleArrowsWidth, &buttonWidth);
|
|
|
|
::GetThemeMetric(kThemeMetricLittleArrowsHeight, &buttonHeight);
|
|
|
|
aResult->SizeTo(buttonWidth, buttonHeight);
|
|
|
|
*aIsOverridable = PR_FALSE;
|
2007-03-22 10:30:00 -07:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
case NS_THEME_CHECKBOX:
|
|
|
|
{
|
|
|
|
SInt32 boxHeight = 0, boxWidth = 0;
|
|
|
|
::GetThemeMetric(kThemeMetricCheckBoxWidth, &boxWidth);
|
|
|
|
::GetThemeMetric(kThemeMetricCheckBoxHeight, &boxHeight);
|
|
|
|
aResult->SizeTo(boxWidth, boxHeight);
|
|
|
|
*aIsOverridable = PR_FALSE;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
case NS_THEME_CHECKBOX_SMALL:
|
|
|
|
{
|
2007-05-17 19:01:02 -07:00
|
|
|
SInt32 boxHeight = 0, boxWidth = 0;
|
|
|
|
::GetThemeMetric(kThemeMetricSmallCheckBoxWidth, &boxWidth);
|
|
|
|
::GetThemeMetric(kThemeMetricSmallCheckBoxHeight, &boxHeight);
|
|
|
|
aResult->SizeTo(boxWidth, boxHeight - 1);
|
2007-03-22 10:30:00 -07:00
|
|
|
*aIsOverridable = PR_FALSE;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
case NS_THEME_RADIO:
|
|
|
|
{
|
|
|
|
SInt32 radioHeight = 0, radioWidth = 0;
|
|
|
|
::GetThemeMetric(kThemeMetricRadioButtonWidth, &radioWidth);
|
|
|
|
::GetThemeMetric(kThemeMetricRadioButtonHeight, &radioHeight);
|
|
|
|
aResult->SizeTo(radioWidth, radioHeight);
|
|
|
|
*aIsOverridable = PR_FALSE;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
case NS_THEME_RADIO_SMALL:
|
|
|
|
{
|
2007-05-17 19:01:02 -07:00
|
|
|
SInt32 radioHeight = 0, radioWidth = 0;
|
|
|
|
::GetThemeMetric(kThemeMetricSmallRadioButtonWidth, &radioWidth);
|
|
|
|
::GetThemeMetric(kThemeMetricSmallRadioButtonHeight, &radioHeight);
|
|
|
|
// small radio buttons have an extra row on top and bottom, cut that off
|
|
|
|
aResult->SizeTo(radioWidth, radioHeight - 2);
|
2007-03-22 10:30:00 -07:00
|
|
|
*aIsOverridable = PR_FALSE;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
case NS_THEME_DROPDOWN:
|
|
|
|
case NS_THEME_DROPDOWN_BUTTON:
|
|
|
|
{
|
|
|
|
SInt32 popupHeight = 0;
|
|
|
|
::GetThemeMetric(kThemeMetricPopupButtonHeight, &popupHeight);
|
|
|
|
aResult->SizeTo(0, popupHeight);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
case NS_THEME_TEXTFIELD:
|
2007-05-06 19:06:58 -07:00
|
|
|
case NS_THEME_TEXTFIELD_MULTILINE:
|
2007-03-22 10:30:00 -07:00
|
|
|
{
|
|
|
|
// at minimum, we should be tall enough for 9pt text.
|
|
|
|
// I'm using hardcoded values here because the appearance manager
|
|
|
|
// values for the frame size are incorrect.
|
|
|
|
aResult->SizeTo(0, (2 + 2) /* top */ + 9 + (1 + 1) /* bottom */);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
case NS_THEME_PROGRESSBAR:
|
|
|
|
{
|
|
|
|
SInt32 barHeight = 0;
|
|
|
|
::GetThemeMetric(kThemeMetricNormalProgressBarThickness, &barHeight);
|
|
|
|
aResult->SizeTo(0, barHeight);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
case NS_THEME_TREEVIEW_TWISTY:
|
|
|
|
case NS_THEME_TREEVIEW_TWISTY_OPEN:
|
|
|
|
{
|
|
|
|
SInt32 twistyHeight = 0, twistyWidth = 0;
|
|
|
|
::GetThemeMetric(kThemeMetricDisclosureButtonWidth, &twistyWidth);
|
|
|
|
::GetThemeMetric(kThemeMetricDisclosureButtonHeight, &twistyHeight);
|
|
|
|
aResult->SizeTo(twistyWidth, twistyHeight);
|
|
|
|
*aIsOverridable = PR_FALSE;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
case NS_THEME_TREEVIEW_HEADER:
|
|
|
|
case NS_THEME_TREEVIEW_HEADER_CELL:
|
|
|
|
{
|
|
|
|
SInt32 headerHeight = 0;
|
|
|
|
::GetThemeMetric(kThemeMetricListHeaderHeight, &headerHeight);
|
|
|
|
aResult->SizeTo(0, headerHeight);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
case NS_THEME_SCALE_HORIZONTAL:
|
|
|
|
{
|
|
|
|
SInt32 scaleHeight = 0;
|
|
|
|
::GetThemeMetric(kThemeMetricHSliderHeight, &scaleHeight);
|
|
|
|
aResult->SizeTo(scaleHeight, scaleHeight);
|
|
|
|
*aIsOverridable = PR_FALSE;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
case NS_THEME_SCALE_VERTICAL:
|
|
|
|
{
|
|
|
|
SInt32 scaleWidth = 0;
|
|
|
|
::GetThemeMetric(kThemeMetricVSliderWidth, &scaleWidth);
|
|
|
|
aResult->SizeTo(scaleWidth, scaleWidth);
|
|
|
|
*aIsOverridable = PR_FALSE;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
case NS_THEME_SCROLLBAR_SMALL:
|
|
|
|
{
|
|
|
|
SInt32 scrollbarWidth = 0;
|
|
|
|
::GetThemeMetric(kThemeMetricSmallScrollBarWidth, &scrollbarWidth);
|
|
|
|
aResult->SizeTo(scrollbarWidth, scrollbarWidth);
|
|
|
|
*aIsOverridable = PR_FALSE;
|
|
|
|
break;
|
|
|
|
}
|
2007-04-10 17:25:11 -07:00
|
|
|
|
|
|
|
// Get the rect of the thumb from HITheme, so we can return it to Gecko, which has different ideas about
|
|
|
|
// how big the thumb should be. This is kind of a hack.
|
2007-03-22 10:30:00 -07:00
|
|
|
case NS_THEME_SCROLLBAR_THUMB_HORIZONTAL:
|
|
|
|
case NS_THEME_SCROLLBAR_THUMB_VERTICAL:
|
2007-04-10 17:25:11 -07:00
|
|
|
{
|
|
|
|
// Find our parent scrollbar frame. If we can't, abort.
|
|
|
|
nsIFrame *scrollbarFrame = GetParentScrollbarFrame(aFrame);
|
|
|
|
if (!scrollbarFrame) return NS_ERROR_FAILURE;
|
|
|
|
|
2007-05-15 15:19:54 -07:00
|
|
|
nsRect scrollbarRect = scrollbarFrame->GetRect();
|
|
|
|
*aIsOverridable = PR_FALSE;
|
|
|
|
|
|
|
|
if (scrollbarRect.IsEmpty()) {
|
|
|
|
// just return (0,0)
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2007-04-10 17:25:11 -07:00
|
|
|
// We need to get the device context to convert from app units :(
|
|
|
|
nsCOMPtr<nsIDeviceContext> dctx;
|
|
|
|
aContext->GetDeviceContext(*getter_AddRefs(dctx));
|
|
|
|
PRInt32 p2a = dctx->AppUnitsPerDevPixel();
|
|
|
|
CGRect macRect = CGRectMake(NSAppUnitsToIntPixels(scrollbarRect.x, p2a),
|
|
|
|
NSAppUnitsToIntPixels(scrollbarRect.y, p2a),
|
|
|
|
NSAppUnitsToIntPixels(scrollbarRect.width, p2a),
|
|
|
|
NSAppUnitsToIntPixels(scrollbarRect.height, p2a));
|
|
|
|
|
|
|
|
// False here means not to get scrollbar button state information.
|
|
|
|
HIThemeTrackDrawInfo tdi;
|
|
|
|
GetScrollbarDrawInfo(tdi, scrollbarFrame, macRect, PR_FALSE);
|
|
|
|
|
|
|
|
HIRect thumbRect;
|
|
|
|
::HIThemeGetTrackPartBounds(&tdi, kControlIndicatorPart, &thumbRect);
|
|
|
|
|
|
|
|
// HITheme is just lying to us, I guess...
|
|
|
|
PRInt32 thumbAdjust = ((scrollbarFrame->GetStyleDisplay()->mAppearance == NS_THEME_SCROLLBAR_SMALL) ?
|
|
|
|
2 : 4);
|
|
|
|
|
|
|
|
if (aWidgetType == NS_THEME_SCROLLBAR_THUMB_VERTICAL)
|
|
|
|
aResult->SizeTo(nscoord(thumbRect.size.width), nscoord(thumbRect.size.height - thumbAdjust));
|
|
|
|
else
|
|
|
|
aResult->SizeTo(nscoord(thumbRect.size.width - thumbAdjust), nscoord(thumbRect.size.height));
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
case NS_THEME_SCROLLBAR:
|
2007-03-22 10:30:00 -07:00
|
|
|
case NS_THEME_SCROLLBAR_TRACK_VERTICAL:
|
|
|
|
case NS_THEME_SCROLLBAR_TRACK_HORIZONTAL:
|
|
|
|
{
|
|
|
|
// yeah, i know i'm cheating a little here, but i figure that it
|
|
|
|
// really doesn't matter if the scrollbar is vertical or horizontal
|
|
|
|
// and the width metric is a really good metric for every piece
|
|
|
|
// of the scrollbar.
|
2007-04-10 17:25:11 -07:00
|
|
|
|
|
|
|
nsIFrame *scrollbarFrame = GetParentScrollbarFrame(aFrame);
|
|
|
|
if (!scrollbarFrame) return NS_ERROR_FAILURE;
|
|
|
|
|
|
|
|
PRInt32 themeMetric = (scrollbarFrame->GetStyleDisplay()->mAppearance == NS_THEME_SCROLLBAR_SMALL) ?
|
|
|
|
kThemeMetricSmallScrollBarWidth :
|
|
|
|
kThemeMetricScrollBarWidth;
|
2007-03-22 10:30:00 -07:00
|
|
|
SInt32 scrollbarWidth = 0;
|
2007-04-10 17:25:11 -07:00
|
|
|
::GetThemeMetric(themeMetric, &scrollbarWidth);
|
2007-03-22 10:30:00 -07:00
|
|
|
aResult->SizeTo(scrollbarWidth, scrollbarWidth);
|
|
|
|
*aIsOverridable = PR_FALSE;
|
|
|
|
break;
|
|
|
|
}
|
2007-04-10 17:25:11 -07:00
|
|
|
|
|
|
|
case NS_THEME_SCROLLBAR_BUTTON_UP:
|
|
|
|
case NS_THEME_SCROLLBAR_BUTTON_DOWN:
|
|
|
|
case NS_THEME_SCROLLBAR_BUTTON_LEFT:
|
|
|
|
case NS_THEME_SCROLLBAR_BUTTON_RIGHT:
|
|
|
|
{
|
|
|
|
nsIFrame *scrollbarFrame = GetParentScrollbarFrame(aFrame);
|
|
|
|
if (!scrollbarFrame) return NS_ERROR_FAILURE;
|
|
|
|
|
|
|
|
// Since there is no NS_THEME_SCROLLBAR_BUTTON_UP_SMALL we need to ask the parent what appearance style it has.
|
|
|
|
PRInt32 themeMetric = (scrollbarFrame->GetStyleDisplay()->mAppearance == NS_THEME_SCROLLBAR_SMALL) ?
|
|
|
|
kThemeMetricSmallScrollBarWidth :
|
|
|
|
kThemeMetricScrollBarWidth;
|
|
|
|
SInt32 scrollbarWidth = 0;
|
|
|
|
::GetThemeMetric(themeMetric, &scrollbarWidth);
|
|
|
|
|
|
|
|
// It seems that for both sizes of scrollbar, the buttons are one pixel "longer".
|
|
|
|
if (aWidgetType == NS_THEME_SCROLLBAR_BUTTON_LEFT || aWidgetType == NS_THEME_SCROLLBAR_BUTTON_RIGHT)
|
|
|
|
aResult->SizeTo(scrollbarWidth+1, scrollbarWidth);
|
|
|
|
else
|
|
|
|
aResult->SizeTo(scrollbarWidth, scrollbarWidth+1);
|
|
|
|
|
|
|
|
*aIsOverridable = PR_FALSE;
|
|
|
|
break;
|
|
|
|
}
|
2007-03-22 10:30:00 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
nsNativeThemeCocoa::WidgetStateChanged(nsIFrame* aFrame, PRUint8 aWidgetType,
|
|
|
|
nsIAtom* aAttribute, PRBool* aShouldRepaint)
|
|
|
|
{
|
|
|
|
// Some widget types just never change state.
|
|
|
|
switch (aWidgetType) {
|
|
|
|
case NS_THEME_TOOLBOX:
|
|
|
|
case NS_THEME_TOOLBAR:
|
|
|
|
case NS_THEME_TOOLBAR_BUTTON:
|
|
|
|
case NS_THEME_SCROLLBAR_TRACK_VERTICAL:
|
|
|
|
case NS_THEME_SCROLLBAR_TRACK_HORIZONTAL:
|
|
|
|
case NS_THEME_STATUSBAR:
|
|
|
|
case NS_THEME_STATUSBAR_PANEL:
|
|
|
|
case NS_THEME_STATUSBAR_RESIZER_PANEL:
|
|
|
|
case NS_THEME_PROGRESSBAR_CHUNK:
|
|
|
|
case NS_THEME_PROGRESSBAR_CHUNK_VERTICAL:
|
|
|
|
case NS_THEME_PROGRESSBAR:
|
|
|
|
case NS_THEME_PROGRESSBAR_VERTICAL:
|
|
|
|
case NS_THEME_TOOLTIP:
|
|
|
|
case NS_THEME_TAB_PANELS:
|
|
|
|
case NS_THEME_TAB_PANEL:
|
|
|
|
case NS_THEME_TEXTFIELD:
|
2007-05-06 19:06:58 -07:00
|
|
|
case NS_THEME_TEXTFIELD_MULTILINE:
|
2007-03-22 10:30:00 -07:00
|
|
|
case NS_THEME_DIALOG:
|
|
|
|
case NS_THEME_MENUPOPUP:
|
|
|
|
*aShouldRepaint = PR_FALSE;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
// XXXdwh Not sure what can really be done here. Can at least guess for
|
|
|
|
// specific widgets that they're highly unlikely to have certain states.
|
|
|
|
// For example, a toolbar doesn't care about any states.
|
|
|
|
if (!aAttribute) {
|
|
|
|
// Hover/focus/active changed. Always repaint.
|
|
|
|
*aShouldRepaint = PR_TRUE;
|
|
|
|
} else {
|
|
|
|
// Check the attribute to see if it's relevant.
|
|
|
|
// disabled, checked, dlgtype, default, etc.
|
|
|
|
*aShouldRepaint = PR_FALSE;
|
|
|
|
if (aAttribute == nsWidgetAtoms::disabled ||
|
|
|
|
aAttribute == nsWidgetAtoms::checked ||
|
|
|
|
aAttribute == nsWidgetAtoms::selected ||
|
|
|
|
aAttribute == nsWidgetAtoms::mozmenuactive ||
|
2007-05-22 17:10:02 -07:00
|
|
|
aAttribute == nsWidgetAtoms::sortdirection ||
|
|
|
|
aAttribute == nsWidgetAtoms::_default)
|
2007-03-22 10:30:00 -07:00
|
|
|
*aShouldRepaint = PR_TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
nsNativeThemeCocoa::ThemeChanged()
|
|
|
|
{
|
|
|
|
// This is unimplemented because we don't care if gecko changes its theme
|
|
|
|
// and Mac OS X doesn't have themes.
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
PRBool
|
|
|
|
nsNativeThemeCocoa::ThemeSupportsWidget(nsPresContext* aPresContext, nsIFrame* aFrame,
|
|
|
|
PRUint8 aWidgetType)
|
|
|
|
{
|
|
|
|
if (aPresContext && !aPresContext->PresShell()->IsThemeSupportEnabled())
|
|
|
|
return PR_FALSE;
|
|
|
|
|
2007-08-27 20:39:19 -07:00
|
|
|
// if this is a dropdown button in a combobox the answer is always no
|
|
|
|
if (aWidgetType == NS_THEME_DROPDOWN_BUTTON) {
|
|
|
|
nsIFrame* parentFrame = aFrame->GetParent();
|
|
|
|
if (parentFrame && (parentFrame->GetType() == nsWidgetAtoms::comboboxControlFrame))
|
|
|
|
return PR_FALSE;
|
|
|
|
}
|
2007-03-22 10:30:00 -07:00
|
|
|
|
|
|
|
switch (aWidgetType) {
|
2007-08-27 20:39:19 -07:00
|
|
|
case NS_THEME_LISTBOX:
|
|
|
|
|
2007-03-22 10:30:00 -07:00
|
|
|
case NS_THEME_DIALOG:
|
|
|
|
case NS_THEME_WINDOW:
|
|
|
|
case NS_THEME_MENUPOPUP:
|
|
|
|
case NS_THEME_MENUITEM:
|
|
|
|
case NS_THEME_TOOLTIP:
|
|
|
|
|
|
|
|
case NS_THEME_CHECKBOX:
|
|
|
|
case NS_THEME_CHECKBOX_SMALL:
|
|
|
|
case NS_THEME_CHECKBOX_CONTAINER:
|
|
|
|
case NS_THEME_RADIO:
|
|
|
|
case NS_THEME_RADIO_SMALL:
|
|
|
|
case NS_THEME_RADIO_CONTAINER:
|
|
|
|
case NS_THEME_BUTTON:
|
|
|
|
case NS_THEME_BUTTON_BEVEL:
|
|
|
|
case NS_THEME_SPINNER:
|
|
|
|
case NS_THEME_TOOLBAR:
|
|
|
|
case NS_THEME_STATUSBAR:
|
|
|
|
case NS_THEME_TEXTFIELD:
|
2007-05-06 19:06:58 -07:00
|
|
|
case NS_THEME_TEXTFIELD_MULTILINE:
|
2007-03-22 10:30:00 -07:00
|
|
|
//case NS_THEME_TOOLBOX:
|
|
|
|
//case NS_THEME_TOOLBAR_BUTTON:
|
|
|
|
case NS_THEME_PROGRESSBAR:
|
|
|
|
case NS_THEME_PROGRESSBAR_VERTICAL:
|
|
|
|
case NS_THEME_PROGRESSBAR_CHUNK:
|
|
|
|
case NS_THEME_PROGRESSBAR_CHUNK_VERTICAL:
|
|
|
|
case NS_THEME_TOOLBAR_SEPARATOR:
|
|
|
|
|
|
|
|
case NS_THEME_TAB_PANELS:
|
|
|
|
case NS_THEME_TAB:
|
|
|
|
case NS_THEME_TAB_LEFT_EDGE:
|
|
|
|
case NS_THEME_TAB_RIGHT_EDGE:
|
|
|
|
|
|
|
|
case NS_THEME_TREEVIEW_TWISTY:
|
|
|
|
case NS_THEME_TREEVIEW_TWISTY_OPEN:
|
|
|
|
case NS_THEME_TREEVIEW:
|
|
|
|
case NS_THEME_TREEVIEW_HEADER:
|
|
|
|
case NS_THEME_TREEVIEW_HEADER_CELL:
|
|
|
|
case NS_THEME_TREEVIEW_HEADER_SORTARROW:
|
|
|
|
case NS_THEME_TREEVIEW_TREEITEM:
|
|
|
|
case NS_THEME_TREEVIEW_LINE:
|
|
|
|
|
|
|
|
case NS_THEME_SCALE_HORIZONTAL:
|
|
|
|
case NS_THEME_SCALE_THUMB_HORIZONTAL:
|
|
|
|
case NS_THEME_SCALE_VERTICAL:
|
|
|
|
case NS_THEME_SCALE_THUMB_VERTICAL:
|
|
|
|
|
|
|
|
case NS_THEME_SCROLLBAR:
|
|
|
|
case NS_THEME_SCROLLBAR_SMALL:
|
|
|
|
case NS_THEME_SCROLLBAR_BUTTON_UP:
|
|
|
|
case NS_THEME_SCROLLBAR_BUTTON_DOWN:
|
|
|
|
case NS_THEME_SCROLLBAR_BUTTON_LEFT:
|
|
|
|
case NS_THEME_SCROLLBAR_BUTTON_RIGHT:
|
|
|
|
case NS_THEME_SCROLLBAR_THUMB_HORIZONTAL:
|
|
|
|
case NS_THEME_SCROLLBAR_THUMB_VERTICAL:
|
|
|
|
case NS_THEME_SCROLLBAR_TRACK_VERTICAL:
|
|
|
|
case NS_THEME_SCROLLBAR_TRACK_HORIZONTAL:
|
|
|
|
|
|
|
|
case NS_THEME_DROPDOWN:
|
|
|
|
case NS_THEME_DROPDOWN_BUTTON:
|
|
|
|
case NS_THEME_DROPDOWN_TEXT:
|
2007-08-27 20:39:19 -07:00
|
|
|
return !IsWidgetStyled(aPresContext, aFrame, aWidgetType);
|
|
|
|
break;
|
2007-03-22 10:30:00 -07:00
|
|
|
}
|
|
|
|
|
2007-08-27 20:39:19 -07:00
|
|
|
return PR_FALSE;
|
2007-03-22 10:30:00 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
PRBool
|
|
|
|
nsNativeThemeCocoa::WidgetIsContainer(PRUint8 aWidgetType)
|
|
|
|
{
|
|
|
|
// flesh this out at some point
|
|
|
|
switch (aWidgetType) {
|
|
|
|
case NS_THEME_DROPDOWN_BUTTON:
|
|
|
|
case NS_THEME_RADIO:
|
2007-05-17 19:01:02 -07:00
|
|
|
case NS_THEME_RADIO_SMALL:
|
2007-03-22 10:30:00 -07:00
|
|
|
case NS_THEME_CHECKBOX:
|
2007-05-17 19:01:02 -07:00
|
|
|
case NS_THEME_CHECKBOX_SMALL:
|
2007-03-22 10:30:00 -07:00
|
|
|
case NS_THEME_PROGRESSBAR:
|
|
|
|
return PR_FALSE;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
return PR_TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
PRBool
|
|
|
|
nsNativeThemeCocoa::ThemeDrawsFocusForWidget(nsPresContext* aPresContext, nsIFrame* aFrame, PRUint8 aWidgetType)
|
|
|
|
{
|
|
|
|
if (aWidgetType == NS_THEME_DROPDOWN ||
|
2007-05-07 18:20:11 -07:00
|
|
|
aWidgetType == NS_THEME_BUTTON)
|
2007-03-22 10:30:00 -07:00
|
|
|
return PR_TRUE;
|
|
|
|
|
|
|
|
return PR_FALSE;
|
|
|
|
}
|
2007-05-17 20:04:04 -07:00
|
|
|
|
|
|
|
PRBool
|
|
|
|
nsNativeThemeCocoa::ThemeNeedsComboboxDropmarker()
|
|
|
|
{
|
|
|
|
return PR_FALSE;
|
|
|
|
}
|